JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
value.hpp
Go to the documentation of this file.
1/// \file jsonv/value.hpp
2///
3/// Copyright (c) 2012-2020 by Travis Gockel. All rights reserved.
4///
5/// This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
6/// as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
7/// version.
8///
9/// \author Travis Gockel (travis@gockelhut.com)
10#pragma once
11
12#include <jsonv/config.hpp>
13#include <jsonv/kind.hpp>
14#include <string_view>
16
17#include <cstddef>
18#include <cstdint>
19#include <initializer_list>
20#include <iosfwd>
21#include <iterator>
22#include <functional>
23#include <map>
24#include <stdexcept>
25#include <string>
26#include <type_traits>
27#include <utility>
28
29namespace jsonv
30{
31
32class path;
33class value;
34class object_node_handle;
35
36namespace detail
37{
38
39class object_impl;
40class array_impl;
41class string_impl;
42
43union value_storage
44{
45 object_impl* object;
46 array_impl* array;
47 string_impl* string;
48 int64_t integer;
49 double decimal;
50 bool boolean;
51
52 constexpr value_storage() :
53 object(nullptr)
54 { }
55};
56
57}
58
59/// \defgroup Value
60/// JSON \ref value instances.
61///
62/// The side-effect-free parts of this API -- the predicates, the accessors, the constant lookups and everything which
63/// returns a freshly built \ref value -- are \c JSONV_NODISCARD. Calling one and dropping the result does nothing at
64/// all, so the compiler says so. The accessors which create on demand (non-`const` \ref value::path and
65/// \ref value::operator[] for an object key) and the mutators are deliberately left alone, since discarding those is
66/// how they are normally used.
67/// \{
68
69/// Get a string representation of the given \c value.
71
72/// Thrown from various \c value methods when attempting to perform an operation which is not valid for the \c kind of
73/// value.
75 public std::logic_error
76{
77public:
78 explicit kind_error(const std::string& description);
79
80 virtual ~kind_error() noexcept;
81};
82
83/// Represents a single JSON value, which can be any one of a potential \c kind, each behaving slightly differently.
84/// Instances will vary their behavior based on their kind -- functions will throw a \c kind_error if the operation does
85/// not apply to the value's kind. For example, it does not make sense to call \c find on an \c integer.
86///
87/// - \c kind::null
88/// You cannot do anything with this...it is just null.
89/// - \c kind::boolean
90/// These values can be \c true or \c false.
91/// - \c kind::integer
92/// A numeric value which can be added, subtracted and all the other things you would expect.
93/// - \c kind::decimal
94/// Floating-point values should be considered "more general" than integers -- you may request an integer value as a
95/// decimal, but you cannot request a decimal as an integer, even when doing so would not require rounding. The
96/// literal \c 20.0 will always have \c kind::decimal.
97/// - \c kind::string
98/// A UTF-8 encoded string which is mostly accessed through the \c std::string class. Some random functions work in
99/// the cases where it makes sense (for example: \c empty and \c size), but in general, string manipulation should be
100/// done after calling \c as_string.
101/// - \c kind::array
102/// An array behaves like a \c std::vector because it is ultimately backed by one. If you feel the documentation is
103/// lacking, read this: http://en.cppreference.com/w/cpp/container/vector.
104/// - \c kind::object
105/// An object behaves lake a \c std::map because it is ultimately backed by one. If you feel the documentation is
106/// lacking, read this: http://en.cppreference.com/w/cpp/container/map. This library follows the recommendation in
107/// RFC 7159 to not allow for duplicate keys because most other libraries can not deal with it. It would also make
108/// the AST significantly more painful.
109///
110/// \see http://json.org/
111/// \see http://tools.ietf.org/html/rfc7159
113{
114public:
115 typedef std::size_t size_type;
116 typedef std::ptrdiff_t difference_type;
117
118 /** The base type for iterating over array values. **/
119 template <typename T, typename TArrayView>
121 {
122 public:
123 using iterator_category = std::random_access_iterator_tag;
124 using value_type = T;
125 using difference_type = std::ptrdiff_t;
126 using pointer = T*;
127 using reference = T&;
129 _owner(0),
130 _index(0)
131 { }
132
133 basic_array_iterator(TArrayView* owner, size_type index) :
134 _owner(owner),
135 _index(index)
136 { }
137
138 template <typename U, typename UArrayView>
140 typename std::enable_if<std::is_convertible<U*, T*>::value>::type* = 0
141 ) :
142 _owner(source._owner),
143 _index(source._index)
144 { }
145
146 basic_array_iterator& operator++()
147 {
148 ++_index;
149 return *this;
150 }
151
152 basic_array_iterator operator++(int)
153 {
154 basic_array_iterator clone = *this;
155 ++*this;
156 return clone;
157 }
158
159 basic_array_iterator& operator--()
160 {
161 --_index;
162 return *this;
163 }
164
165 basic_array_iterator operator--(int)
166 {
167 basic_array_iterator clone = *this;
168 --*this;
169 return clone;
170 }
171
172 template <typename U, typename UArrayView>
174 bool operator==(const basic_array_iterator<U, UArrayView>& other) const
175 {
176 return _owner == other._owner && _index == other._index;
177 }
178
179 template <typename U, typename UArrayView>
181 bool operator!=(const basic_array_iterator<U, UArrayView>& other) const
182 {
183 return !operator==(other);
184 }
185
187 T& operator*() const
188 {
189 return _owner->operator[](_index);
190 }
191
193 T* operator->() const
194 {
195 return &_owner->operator[](_index);
196 }
197
198 basic_array_iterator& operator+=(size_type n)
199 {
200 _index += n;
201 return *this;
202 }
203
205 basic_array_iterator operator+(size_type n) const
206 {
207 basic_array_iterator clone = *this;
208 clone += n;
209 return clone;
210 }
211
212 basic_array_iterator& operator-=(size_type n)
213 {
214 _index -= n;
215 return *this;
216 }
217
219 basic_array_iterator operator-(size_type n) const
220 {
221 basic_array_iterator clone = *this;
222 clone -= n;
223 return clone;
224 }
225
227 difference_type operator-(const basic_array_iterator& other) const
228 {
229 return difference_type(_index) - difference_type(other._index);
230 }
231
233 bool operator<(const basic_array_iterator& rhs) const
234 {
235 return _index < rhs._index;
236 }
237
239 bool operator<=(const basic_array_iterator& rhs) const
240 {
241 return _index <= rhs._index;
242 }
243
245 bool operator>(const basic_array_iterator& rhs) const
246 {
247 return _index > rhs._index;
248 }
249
251 bool operator>=(const basic_array_iterator& rhs) const
252 {
253 return _index >= rhs._index;
254 }
255
257 T& operator[](size_type n) const
258 {
259 return _owner->operator[](_index + n);
260 }
261 private:
262 template <typename U, typename UArrayView>
263 friend struct basic_array_iterator;
264
265 friend class value;
266
267 private:
268 TArrayView* _owner;
269 size_type _index;
270 };
271
272 /** The \c array_iterator is applicable when \c kind is \c kind::array. It allows you to use algorithms as if
273 * a \c value was a normal sequence container.
274 **/
277
278 /** If \c kind is \c kind::array, an \c array_view allows you to access a value as a sequence container. This is
279 * most useful for range-based for loops.
280 **/
281 typedef detail::basic_view<array_iterator, const_array_iterator> array_view;
282 typedef detail::basic_view<const_array_iterator> const_array_view;
283 typedef detail::basic_owning_view<value, array_iterator, const_array_iterator> owning_array_view;
284
285 /** The base iterator type for iterating over object types. It is a bidirectional iterator similar to a
286 * \c std::map<std::string, jsonv::value>.
287 **/
288 template <typename T, typename TIterator>
290 {
291 public:
292 using iterator_category = std::bidirectional_iterator_tag;
293 using value_type = T;
294 using difference_type = std::ptrdiff_t;
295 using pointer = T*;
296 using reference = T&;
297
299 _impl()
300 { }
301
303 _impl(source._impl)
304 { }
305
306 /** This allows assignment from an \c object_iterator to a \c const_object_iterator. **/
307 template <typename U, typename UIterator>
309 typename std::enable_if<std::is_convertible<U*, T*>::value>::type* = 0
310 ) :
311 _impl(source._impl)
312 { }
313
314 basic_object_iterator& operator=(const basic_object_iterator& source)
315 {
316 _impl = source._impl;
317 return *this;
318 }
319
320 template <typename U, typename UIterator>
321 typename std::enable_if<std::is_convertible<U*, T*>::value, basic_object_iterator&>::type
322 operator=(const basic_object_iterator<U, UIterator>& source)
323 {
324 return operator=(basic_object_iterator(source));
325 }
326
327 basic_object_iterator& operator++()
328 {
329 increment();
330 return *this;
331 }
332
333 basic_object_iterator operator++(int)
334 {
335 basic_object_iterator clone(*this);
336 increment();
337 return clone;
338 }
339
340 basic_object_iterator& operator--()
341 {
342 decrement();
343 return *this;
344 }
345
346 basic_object_iterator operator--(int)
347 {
348 basic_object_iterator clone(*this);
349 decrement();
350 return clone;
351 }
352
353 template <typename U, typename UIterator>
355 bool operator ==(const basic_object_iterator<U, UIterator>& other) const
356 {
357 return _impl == other._impl;
358 }
359
360 template <typename U, typename UIterator>
362 bool operator !=(const basic_object_iterator<U, UIterator>& other) const
363 {
364 return _impl != other._impl;
365 }
366
368 T& operator *() const
369 {
370 return current();
371 }
372
374 T* operator ->() const
375 {
376 return &current();
377 }
378
379 private:
380 friend class value;
381
382 template <typename UIterator>
383 explicit basic_object_iterator(const UIterator& iter) :
384 _impl(iter)
385 { }
386
387 void increment()
388 {
389 ++_impl;
390 }
391
392 void decrement()
393 {
394 --_impl;
395 }
396
397 T& current() const
398 {
399 return *_impl;
400 }
401
402 private:
403 TIterator _impl;
404 };
405
406 /** The type of value stored when \c kind is \c kind::object. **/
407 typedef std::pair<const std::string, value> object_value_type;
408
409 /** The \c object_iterator is applicable when \c kind is \c kind::object. It allows you to use algorithms as if
410 * a \c value was a normal associative container.
411 **/
414
415 /** If \c kind is \c kind::object, an \c object_view allows you to access a value as an associative container.
416 * This is most useful for range-based for loops.
417 **/
418 typedef detail::basic_view<object_iterator, const_object_iterator> object_view;
419 typedef detail::basic_view<const_object_iterator> const_object_view;
420 typedef detail::basic_owning_view<value, object_iterator, const_object_iterator> owning_object_view;
421
422 /// Type returned from \c insert operations when this has \ref kind::object. It is generally compatible with the
423 /// \c insert_return_type of \c std::map, with the notable lack of \c node.
424 ///
425 /// \see insert
427 {
428 /// The position of the inserted node or node with the duplicate key.
430
431 /// Did the insert operation perform an insert? A value of \c false indicates there was a key already present
432 /// with the same name.
434 };
435
436public:
437 /** Default-construct this to null. **/
438 constexpr value() :
439 _kind(jsonv::kind::null)
440 { }
441
442 /// The nullptr overload will fail to compile -- use \c jsonv::null if you want a \c kind::null.
443 value(std::nullptr_t) = delete;
444
445 /** Copy the contents of \a source into a new instance. **/
446 value(const value& source);
447
448 /** Create a \c kind::string with the given \a value. **/
449 value(const std::string& value);
450
451 /** Create a \c kind::string with the given \a value. **/
452 value(const std::string_view& value);
453
454 /// Create a \c kind::string with the given \a value.
455 ///
456 /// \param value The value to create with. This must be null-terminated.
457 value(const char* value);
458
459 /// Create a \c kind::string with the given \a value. Keep in mind that it will be converted to and stored as a
460 /// UTF-8 encoded string.
461 ///
462 /// \throws std::range_error if \a value is not valid UTF-16, such as when it holds an unpaired surrogate or, where
463 /// \c wchar_t is 32 bits, a code unit above 0xFFFF.
464 value(const std::wstring& value);
465
466 /** Create a \c kind::string with the given \a value. Keep in mind that it will be converted to and stored as a
467 * UTF-8 encoded string.
468 *
469 * \param value The value to create with. This must be null-terminated.
470 * \throws std::range_error if \a value is not valid UTF-16, such as when it holds an unpaired surrogate or, where
471 * \c wchar_t is 32 bits, a code unit above 0xFFFF.
472 **/
473 value(const wchar_t* value);
474
475 /** Create a \c kind::integer with the given \a value. **/
476 value(int64_t value);
477
478 /** Create a \c kind::decimal with the given \a value. **/
479 value(double value);
480
481 /** Create a \c kind::decimal with the given \a value. **/
482 value(float value);
483
484 /** Create a \c kind::boolean with the given \a value. **/
486
487 #define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR(type_) \
488 value(type_ val);
489 JSONV_INTEGER_ALTERNATES_LIST(JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR)
490 #undef JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR
491
492 /** Destruction will never throw. **/
493 ~value() noexcept;
494
495 /** Copy-assigns \c source to this.
496 *
497 * If an exception is thrown during the copy, it is propagated out. This instance will remain unchanged.
498 **/
499 value& operator=(const value& source);
500
501 /** Move-construct this instance, leaving \a source as a null value. **/
502 value(value&& source) noexcept;
503
504 /** Move-assigns \c source to this, leaving \a source as a null value.
505 *
506 * Unlike a copy, this will never throw.
507 **/
508 value& operator=(value&& source) noexcept;
509
510 /** Get this value as a string.
511 *
512 * \throws kind_error if this value does not represent a string.
513 **/
515 const std::string& as_string() const;
516
517 /** Tests if this \c kind is \c kind::string. **/
519 bool is_string() const;
520
521 /** Get this value as a \c std::string_view. It is your responsibility to ensure the \c value instance remains valid.
522 *
523 * \throws kind_error if this value does not represent a string.
524 **/
526 std::string_view as_string_view() const &;
527
528 /** Get this value as a wide string. Keep in mind that this is slower than \c as_string, as the internal storage is
529 * the \c char base \c std::string. The result is UTF-16 even where \c wchar_t is 32 bits, so a code point outside
530 * the BMP takes a surrogate pair there too.
531 *
532 * \throws kind_error if this value does not represent a string.
533 * \throws std::range_error if the stored string is not valid UTF-8.
534 **/
536 std::wstring as_wstring() const;
537
538 /** Get this value as an integer.
539 *
540 * \throws kind_error if this value does not represent an integer.
541 **/
543 int64_t as_integer() const;
544
545 /** Tests if this \c kind is \c kind::integer. **/
547 bool is_integer() const;
548
549 /** Get this value as a decimal. If the value's underlying kind is actually an integer type, cast the integer to a
550 * double before returning. This ignores the potential loss of precision.
551 *
552 * \throws kind_error if this value does not represent a decimal or integer.
553 **/
555 double as_decimal() const;
556
557 /** Tests if this \c kind is \c kind::integer or \c kind::decimal. **/
559 bool is_decimal() const;
560
561 /** Get this value as a boolean.
562 *
563 * \throws kind_error if this value does not represent a boolean.
564 **/
566 bool as_boolean() const;
567
568 /** Tests if this \c kind is \c kind::boolean. **/
570 bool is_boolean() const;
571
572 /** Tests if this \c kind is \c kind::array. **/
574 bool is_array() const;
575
576 /** Tests if this \c kind is \c kind::object. **/
578 bool is_object() const;
579
580 /** Tests if this \c kind is \c kind::null. **/
582 bool is_null() const;
583
584 /** Resets this value to null. **/
585 void clear();
586
587 /** Get this value's kind. **/
589 inline jsonv::kind kind() const
590 {
591 return _kind;
592 }
593
594 /// \{
595
596 /** Get the value specified by the path \a p.
597 *
598 * \throws std::out_of_range if any path along the chain did not exist.
599 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
600 * index when the value is a string).
601 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
602 * (see \c path::create).
603 **/
604 value& at_path(const path& p);
605 value& at_path(std::string_view p);
606 value& at_path(size_type p);
608 const value& at_path(const path& p) const;
610 const value& at_path(std::string_view p) const;
612 const value& at_path(size_type p) const;
613 /// \}
614
615 /// \{
616
617 /** Similar to \c count, but walks the given path \a p to determine its presence.
618 *
619 * \returns \c 1 if the path finds an element; \c 0 if there is no such path in the tree.
620 *
621 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
622 * (see \c path::create).
623 **/
625 size_type count_path(const path& p) const;
627 size_type count_path(std::string_view p) const;
629 size_type count_path(size_type p) const;
630 /// \}
631
632 /// \{
633
634 /** Get or create the value specified by the path \a p. This is the moral equivalent to \c operator[] for paths. If
635 * no value exists at the path, a new one is created as the default (\c null) value. If any path along the way
636 * either does not exist or is \c null, it is created for you, based on the \e implications of the specification
637 * \a p. Unlike \c at_path, which will throw if accessing a non-existent key of an \c object or going past the end
638 * of an \c array, this will simply create that path and fill in the blanks with \c null values.
639 *
640 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
641 * index when the value is a string).
642 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
643 * (see \c path::create).
644 * \throws std::length_error if the path has an array index which no array can hold, such as the largest
645 * \c std::size_t.
646 * \throws std::bad_alloc if there is not enough memory to create what the path needs.
647 *
648 * If this throws, for any reason, \c *this is left as it was. What the path needs is built apart from the tree and
649 * added to it in a single step at the end, so there is no partial result: a \c null does not become \c [] and a
650 * key on the way to the failing index is not created. A path which already exists is only followed, with nothing
651 * allocated.
652 *
653 * \see at_path
654 **/
655 value& path(const path& p);
656 value& path(std::string_view p);
657 value& path(size_type p);
658 /// \}
659
660 /** Swap the value this instance represents with \a other. **/
661 void swap(value& other) noexcept;
662
663 /** Compares two JSON values for equality. Two JSON values are equal if and only if all of the following conditions
664 * apply:
665 *
666 * 1. They have the same valid value for \c kind, where \c kind::integer and \c kind::decimal count as the same.
667 * - If \c kind is invalid (memory corruption), then two JSON values are \e not equal, even if they have been
668 * corrupted in the same way and even if they share \c this (a corrupt object is not equal to itself).
669 * 2. The kind comparison is also equal:
670 * - Two null values are always equivalent.
671 * - string, integer and boolean follow the classic rules for their type.
672 * - decimals compare exactly, with signed zeros equal and all NaNs equal (see \c compare).
673 * - an integer and a decimal are equal only when the decimal holds exactly that integer (see \c compare).
674 * - objects are equal if they have the same keys and values corresponding with the same key are also equal.
675 * - arrays are equal if they have the same length and the values at each index are also equal.
676 *
677 * \note
678 * The rules for equality are based on Python \c dict and \c list.
679 **/
681 bool operator==(const value& other) const;
682
683 /** Compares two JSON values for inequality. The rules for inequality are the exact opposite of equality.
684 **/
686 bool operator!=(const value& other) const;
687
688 /** Used to build a strict-ordering of JSON values. When comparing values of the same kind, the ordering should
689 * align with your intuition. When comparing values of different kinds, some arbitrary rules were created based on
690 * how "complicated" the author thought the type to be.
691 *
692 * - null: less than everything but null, which it is equal to.
693 * - boolean: false is less than true.
694 * - integer, decimal: compared by their exact numeric value. An integer is never converted to a decimal to
695 * compare it with one, so \c 9007199254740993 is greater than the decimal \c 9007199254740992.0 even though
696 * converting it would round to that decimal. Decimal comparison is exact, without an epsilon tolerance. Signed
697 * zeros compare equal to each other and to the integer \c 0; infinities follow numeric order. All NaNs compare
698 * equal to each other and greater than every other number, regardless of sign or payload.
699 * - string: compared lexicographically by character code (with basic char strings and non-ASCII encoding, this
700 * might lead to surprising results)
701 * - array: compared lexicographically by elements (recursively following this same technique)
702 * - object: entries in the object are sorted and compared lexicographically, first by key then by value
703 *
704 * \returns A negative number if this is less than other by the rules stated above; 0 if this is equal to other; a
705 * positive number otherwise. Only the sign is meaningful: strings and object keys pass on the result of
706 * \c std::string::compare, which need not be -1 or 1.
707 **/
709 int compare(const value& other) const;
710
712 bool operator< (const value& other) const;
714 bool operator> (const value& other) const;
716 bool operator<=(const value& other) const;
718 bool operator>=(const value& other) const;
719
720 /// Output this value to a stream, through an \c ostream_encoder. The stream's format flags, width, fill and locale
721 /// do not change the text written.
722 friend std::ostream& operator<<(std::ostream& stream, const value& val);
723
724 /// Get a string representation of the given \c value.
725 friend std::string to_string(const value&);
726
727 /// \{
728
729 /// Get an iterator to the beginning of this array.
730 ///
731 /// \throws kind_error if the kind is not an array.
736 /// \}
737
738 /// \{
739
740 /// Get an iterator to the end of this array.
741 ///
742 /// \throws kind_error if the kind is not an array.
747 /// \}
748
749 /// \{
750
751 /// View this instance as an array.
752 ///
753 /// \throws kind_error if the kind is not an array.
757 const_array_view as_array() const &;
759 owning_array_view as_array() &&;
760 /// \}
761
762 /// \{
763
764 /// Get the value in this array at the given \a idx. The overloads which accept an \c int are required to resolve
765 /// the type ambiguity of the literal \c 0 between a size_type and a char*.
766 ///
767 /// \throws kind_error if the kind is not an array.
768 value& operator[](size_type idx);
770 const value& operator[](size_type idx) const;
771 inline value& operator[](int idx) { return operator[](size_type(idx)); }
773 inline const value& operator[](int idx) const { return operator[](size_type(idx)); }
774 /// \}
775
776 /// \{
777
778 /// Get the value in this array at the given \a idx.
779 ///
780 /// \throws kind_error if the kind is not an array.
781 /// \throws std::out_of_range if the provided \a idx is above \c size.
782 ///
783 value& at(size_type idx);
785 const value& at(size_type idx) const;
786 /// \}
787
788 /// \{
789
790 /// Push \a item to the back of this array.
791 ///
792 /// \throws kind_error if the kind is not an array.
793 void push_back(value&& item);
794 void push_back(const value& item);
795 /// \}
796
797 /// Pop an item off the back of this array.
798 ///
799 /// \throws kind_error if the kind is not an array.
800 /// \throws std::logic_error if the array is empty.
801 void pop_back();
802
803 /// Insert an item into \a position on this array.
804 ///
805 /// \throws kind_error if the kind is not an array.
807
808 /// Insert the range defined by [\a first, \a last) at \a position in this array.
809 ///
810 /// \throws kind_error if the kind is not an array.
811 template <typename TForwardIterator>
812 array_iterator insert(const_array_iterator position, TForwardIterator first, TForwardIterator last)
813 {
814 difference_type orig_offset = std::distance(const_array_iterator(begin_array()), position);
815
816 for (difference_type offset = orig_offset ; first != last; ++first, ++offset)
817 insert(begin_array() + offset, *first);
818 return begin_array() + orig_offset;
819 }
820
821 /// Assign \a count elements to this array with \a val.
822 ///
823 /// \throws kind_error if the kind is not an array.
824 void assign(size_type count, const value& val);
825
826 /// Assign the contents of range [\a first, \a last) to this array.
827 ///
828 /// \throws kind_error if the kind is not an array.
829 template <typename TForwardIterator>
830 void assign(TForwardIterator first, TForwardIterator last)
831 {
832 resize(std::distance(first, last), value());
833 auto iter = begin_array();
834 while (first != last)
835 {
836 *iter = *first;
837 ++iter;
838 ++first;
839 }
840 }
841
842 /// Assign the given \a items to this array.
843 ///
844 /// \throws kind_error if the kind is not an array.
845 void assign(std::initializer_list<value> items);
846
847 /// Reserve at least \a count elements in the array.
848 ///
849 /// \throws kind_error if the kind is not an array.
850 void reserve(size_type count);
851
852 /// Resize the length of this array to \a count items. If the resize creates new elements, fill those newly-created
853 /// elements with \a val.
854 ///
855 /// \throws kind_error if the kind is not an array.
856 void resize(size_type count, const value& val = value());
857
858 /// Erase the item at this array's \a position.
859 ///
860 /// \throws kind_error if the kind is not an array.
862
863 /// Erase the range [\a first, \a last) from this array.
864 ///
865 /// \throws kind_error if the kind is not an array.
867
868 /// \{
869
870 /** Get an iterator to the first key-value pair in this object.
871 *
872 * \throws kind_error if the kind is not an object.
873 **/
878 /// \}
879
880 /// \{
881
882 /** Get an iterator to the one past the end of this object.
883 *
884 * \throws kind_error if the kind is not an object.
885 **/
890 /// \}
891
892 /// \{
893
894 /** View this instance as an object.
895 *
896 * \throws kind_error if the kind is not an object.
897 **/
901 const_object_view as_object() const &;
903 owning_object_view as_object() &&;
904 /// \}
905
906 /// \{
907
908 /** Get the value associated with the given \a key of this object. If the \a key does not exist, it will be created.
909 *
910 * \throws kind_error if the kind is not an object.
911 **/
912 value& operator[](const std::string& key);
913 value& operator[](std::string&& key);
914 value& operator[](const std::wstring& key);
915 /// \}
916
917 /// \{
918
919 /** Get the value associated with the given \a key of this object.
920 *
921 * \throws kind_error if the kind is not an object.
922 * \throws std::out_of_range if the \a key is not in this object.
923 **/
924 value& at(const std::string& key);
925 value& at(const std::wstring& key);
927 const value& at(const std::string& key) const;
929 const value& at(const std::wstring& key) const;
930 /// \}
931
932 /// \{
933
934 /** Check if the given \a key exists in this object.
935 *
936 * \throws kind_error if the kind is not an object.
937 **/
939 size_type count(const std::string& key) const;
941 size_type count(const std::wstring& key) const;
942 /// \}
943
944 /// \{
945
946 /** Attempt to locate a key-value pair with the provided \a key in this object.
947 *
948 * \throws kind_error if the kind is not an object.
949 **/
951 object_iterator find(const std::string& key);
953 object_iterator find(const std::wstring& key);
955 const_object_iterator find(const std::string& key) const;
957 const_object_iterator find(const std::wstring& key) const;
958 /// \}
959
960 /// \{
961
962 /// Insert \a pair into this object, unless an element with an equivalent key is already present.
963 ///
964 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
965 /// whose \c second is \c true if the insertion took place.
966 /// \throws kind_error if the kind is not an object.
967 std::pair<object_iterator, bool> insert(std::pair<std::string, value> pair);
968 std::pair<object_iterator, bool> insert(std::pair<std::wstring, value> pair);
969 /// \}
970
971 /// \{
972
973 /// Insert \a pair into this object, unless an element with an equivalent key is already present. As with
974 /// \c std::map::insert, the element is inserted as close as possible to the position just prior to \a hint, and a
975 /// good \a hint makes the insertion faster.
976 ///
977 /// \returns An iterator to the newly-inserted element (or the element which shares the key).
978 /// \throws kind_error if the kind is not an object.
979 object_iterator insert(const_object_iterator hint, std::pair<std::string, value> pair);
980 object_iterator insert(const_object_iterator hint, std::pair<std::wstring, value> pair);
981 /// \}
982
983 /// Insert range defined by [\a first, \a last) into this object.
984 ///
985 /// \throws kind_error if the kind is not an object.
986 template <typename TForwardIterator>
987 void insert(TForwardIterator first, TForwardIterator last)
988 {
989 // end_object() is not invalidated by insertion, so the hint can be hoisted out of the loop. It pays off for an
990 // ascending source of unique keys which all sort after what this object already holds -- most importantly when
991 // building a fresh object -- costing amortized constant time per element. Anything else just misses the hint
992 // and falls back to the usual logarithmic lookup: the hint is only taken for a key sorting strictly after the
993 // greatest one present, so a repeated key does not benefit.
994 const_object_iterator hint = end_object();
995
996 for ( ; first != last; ++first)
997 insert(hint, *first);
998 }
999
1000 /// Insert the contents of \a handle. If \a handle is empty, this does nothing. If the insertion succeeds, \a handle
1001 /// is moved from and left empty; otherwise it retains ownership of the element.
1002 ///
1003 /// \returns If \a handle is empty, \c inserted is \c false and \c position is `end_object()`. If the insertion took
1004 /// place, \c inserted is \c true and \c position points to the inserted element. If the insertion was attempted
1005 /// but failed, \c inserted is \c false and \c position points to an element with a key equivalent to
1006 /// `handle.key()`.
1007 /// \throws kind_error if the kind is not an object.
1009
1010 /// If \a handle is an empty node handle, does nothing and returns \ref end_object. Otherwise, inserts the element
1011 /// owned by \a handle into the container, if the container doesn't already contain an element with a key equivalent
1012 /// to `handle.key()` and returns the iterator pointing to the element with key equivalent to `handle.key()`. If the
1013 /// insertion succeeds, \a handle is moved from, otherwise it retains ownership of the element. The element is
1014 /// inserted as close as possible to the position just prior to \a hint.
1015 ///
1016 /// \returns An iterator pointing to an element with a key equivalent to `handle.key()` if \a handle was not empty.
1017 /// If \a handle was empty, `end_object()`.
1018 /// \throws kind_error if the kind is not an object.
1020
1021 /// \{
1022
1023 /// Insert \a items into this object.
1024 ///
1025 /// \throws kind_error if the kind is not an object.
1026 void insert(std::initializer_list<std::pair<std::string, value>> items);
1027 void insert(std::initializer_list<std::pair<std::wstring, value>> items);
1028 /// \}
1029
1030 /// \{
1031
1032 /// Construct an element from \a key and \a val and insert it into this object. If an element with an equivalent
1033 /// key is already present, the insertion does not happen and the existing element is not overwritten.
1034 ///
1035 /// \note
1036 /// As with \c std::map::emplace, the node is constructed before the key is looked up, so a call which does not
1037 /// insert has still allocated and destroyed one. Prefer \ref try_emplace when collisions are expected.
1038 ///
1039 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
1040 /// whose \c second is \c true if the insertion took place.
1041 /// \throws kind_error if the kind is not an object.
1042 ///
1043 /// \see insert
1044 /// \see try_emplace
1045 std::pair<object_iterator, bool> emplace(std::string key, value val);
1046 std::pair<object_iterator, bool> emplace(const std::wstring& key, value val);
1047 /// \}
1048
1049 /// \{
1050
1051 /// Insert \a val with the given \a key into this object, but only if no element with an equivalent key is already
1052 /// present. Unlike \ref emplace, \a key is left alone and no node is allocated when the key is already present.
1053 ///
1054 /// \note
1055 /// \a val is taken by value, so a caller who passes `std::move(x)` has moved from \c x by the time this function
1056 /// is entered whether or not the insertion happens. It is the key and the node which are spared, not \a val.
1057 ///
1058 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
1059 /// whose \c second is \c true if the insertion took place.
1060 /// \throws kind_error if the kind is not an object.
1061 ///
1062 /// \see insert
1063 /// \see insert_or_assign
1064 std::pair<object_iterator, bool> try_emplace(const std::string& key, value val);
1065 std::pair<object_iterator, bool> try_emplace(const std::wstring& key, value val);
1066 /// \}
1067
1068 /// \{
1069
1070 /// Insert \a val with the given \a key into this object if no element with an equivalent key is present;
1071 /// otherwise, assign \a val to the existing element. Unlike \ref try_emplace, \a val is stored either way.
1072 ///
1073 /// \returns A pair whose \c first refers to the inserted or assigned element and whose \c second is \c true if an
1074 /// insertion took place and \c false if an assignment took place. Unlike \ref insert, a \c second of \c false
1075 /// does \e not mean the operation failed -- this function always modifies the object.
1076 /// \throws kind_error if the kind is not an object.
1077 ///
1078 /// \see insert
1079 /// \see try_emplace
1080 std::pair<object_iterator, bool> insert_or_assign(const std::string& key, value val);
1081 std::pair<object_iterator, bool> insert_or_assign(const std::wstring& key, value val);
1082 /// \}
1083
1084 /// \{
1085
1086 /// Erase the item with the given \a key.
1087 ///
1088 /// \returns 1 if \a key was erased; 0 if it did not.
1089 /// \throws kind_error if the kind is not an object.
1090 size_type erase(const std::string& key);
1091 size_type erase(const std::wstring& key);
1092 /// \}
1093
1094 /// Erase the item at the given \a position.
1095 ///
1096 /// \throws kind_error if the kind is not an object.
1098
1099 /// Erase the range defined by [\a first, \a last).
1100 ///
1101 /// \throws kind_error if the kind is not an object.
1103
1104 /// Unlinks the node that contains the element pointed to by \a position and returns a node handle that owns it.
1105 ///
1106 /// \throws kind_error if the kind is not an object.
1108
1109 /// \{
1110
1111 /// If the container has an element with the given \a key, unlinks the node that contains that element from the
1112 /// container and returns a node handle that owns it. Otherwise, returns an empty node handle.
1113 ///
1114 /// \throws kind_error if the kind is not an object.
1115 object_node_handle extract(const std::string& key);
1116 object_node_handle extract(const std::wstring& key);
1117 /// \}
1118
1119 /** Is the underlying structure empty?
1120 *
1121 * - object: Are there no keys?
1122 * - array: Are there no values?
1123 * - string: Is the string 0 length?
1124 * - null: true (always)
1125 * - all other types: false (always)
1126 *
1127 * \throws nothing
1128 **/
1130 bool empty() const noexcept;
1131
1132 /** Get the number of items in this value.
1133 *
1134 * - object: The number of key/value pairs.
1135 * - array: The number of values.
1136 * - string: The number of code points in the string (including \c \\0 values and counting multi-byte encodings as
1137 * more than one value).
1138 *
1139 * \throws kind_error if the kind is not an object, array or string.
1140 **/
1142 size_type size() const;
1143
1144 /** \addtogroup Algorithm
1145 * \{
1146 **/
1147
1148 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1149 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1150 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1151 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1152 * transformed by \a func.
1153 *
1154 * \param func The function to apply to the element or elements of this instance.
1155 **/
1157 value map(const std::function<value (const value&)>& func) const&;
1158
1159 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1160 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1161 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1162 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1163 * transformed by \a func.
1164 *
1165 * \param func The function to apply to the element or elements of this instance.
1166 *
1167 * \note
1168 * This version of \c map provides only a basic exception-safety guarantee. If an exception is thrown while
1169 * transforming a non-scalar \c kind, there is no rollback action, so \c this is left in a usable, but
1170 * \e unpredictable state. If you need a strong exception guarantee, use the constant reference version of \c map.
1171 **/
1173 value map(const std::function<value (value)>& func) &&;
1174
1175 /** \} **/
1176
1177private:
1178 friend JSONV_PUBLIC value array();
1179 friend JSONV_PUBLIC value object();
1180
1181private:
1182 detail::value_storage _data;
1183 jsonv::kind _kind;
1184};
1185
1186/** An instance with \c kind::null. This is intended to be used for convenience and readability (as opposed to using the
1187 * default constructor of \c value.
1188**/
1189JSONV_PUBLIC extern const value null;
1190
1191/** A user-defined literal for parsing JSON. Uses the default (non-strict) \c parse_options.
1192 *
1193 * \code
1194 * R"({
1195 * "taco": "cat",
1196 * "burrito": "dog",
1197 * "whatever": [ "goes", "here", 1, 2, 3, 4 ]
1198 * })"_json;
1199 * \endcode
1200**/
1201JSONV_NODISCARD JSONV_PUBLIC value operator""_json(const char* str, std::size_t len);
1202
1203/** Swap the values \a a and \a b. **/
1204JSONV_PUBLIC void swap(value& a, value& b) noexcept;
1205
1206/** Create an empty array value. **/
1208
1209/** Create an array value from the given source. **/
1210JSONV_NODISCARD JSONV_PUBLIC value array(std::initializer_list<value> source);
1211
1212/** Create an array with contents defined by range [\a first, \a last). **/
1213template <typename TForwardIterator>
1214value array(TForwardIterator first, TForwardIterator last)
1215{
1216 value arr = array();
1217 arr.assign(first, last);
1218 return arr;
1219}
1220
1221/** Create an empty object. **/
1223
1224/** Create an object with key-value pairs from the given \a source. **/
1225JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::string, value>> source);
1226JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::wstring, value>> source);
1227
1228/** Create an object whose contents are defined by range [\a first, \a last). **/
1229template <typename TForwardIterator>
1230value object(TForwardIterator first, TForwardIterator last)
1231{
1232 value obj = object();
1233 obj.insert(first, last);
1234 return obj;
1235}
1236
1237/// A <a href="http://en.cppreference.com/w/cpp/container/node_handle">node handle</a> used when a value is
1238/// \ref kind::object to access elements of the object in potentially destructive manner. This makes it possible to
1239/// modify the contents of a node extracted from an object, and then re-insert it without having to copy the element.
1241{
1242public:
1243 /// The key type of the object.
1244 using key_type = std::string;
1245
1246 /// The mapped type of the object.
1248
1249public:
1250 explicit object_node_handle() noexcept :
1251 _has_value(false)
1252 { }
1253
1254 /// Take over the element owned by \a src, if any. \a src is left \ref empty.
1256
1257 /// Release the element this handle owns, if any, and take over the one owned by \a src, if any. \a src is left
1258 /// \ref empty. Self-assignment has no effect.
1260
1261 ~object_node_handle() noexcept;
1262
1263 /// \returns \c true if the node handle is empty; \c false if otherwise.
1265 bool empty() const noexcept { return !_has_value; }
1266
1267 /// \returns \c false if the node handle is empty; \c true if otherwise.
1269 explicit operator bool() const noexcept { return _has_value; }
1270
1271 /// Returns a non-const reference to the \ref key_type member of the element.
1272 ///
1273 /// \throws std::invalid_argument if the node handle is \ref empty.
1274 key_type& key() const;
1275
1276 /// Returns a non-const reference to the \ref mapped_type member of the element.
1277 ///
1278 /// \throws std::invalid_argument if the node handle is \ref empty.
1280
1281private:
1282 enum class purposeful_construction
1283 { };
1284
1285 explicit object_node_handle(purposeful_construction, key_type, mapped_type) noexcept;
1286
1287 friend class value;
1288
1289private:
1290 bool _has_value;
1291 mutable key_type _key;
1292 mutable mapped_type _value;
1293};
1294
1295/// \}
1296
1297}
1298
1299namespace std
1300{
1301
1302/// Explicit specialization of \c std::hash for \c jsonv::value types so you can store a \c value in an unordered
1303/// container. Values which compare equal hash equal. Since an integer compares equal to the decimal of the same number,
1304/// both \c kind::integer and \c kind::decimal hash through \c value::as_decimal: \c value(2) and \c value(2.0) share a
1305/// hash, as do distinct integers past 2^53 which convert to the same \c double. All NaNs share a hash. For aggregate
1306/// kinds \c array and \c object, hashing visits every sub-element recursively. This might be expensive, but is required
1307/// when storing multiple values with similar layouts in a set (which is the most common use case).
1308template <>
1309struct JSONV_PUBLIC hash<jsonv::value>
1310{
1312 std::size_t operator()(const jsonv::value& val) const noexcept;
1313};
1314
1315}
Copyright (c) 2014-2020 by Travis Gockel.
Thrown from various value methods when attempting to perform an operation which is not valid for the ...
Definition value.hpp:76
A node handle used when a value is kind::object to access elements of the object in potentially destr...
Definition value.hpp:1241
object_node_handle & operator=(object_node_handle &&src) noexcept
Release the element this handle owns, if any, and take over the one owned by src, if any.
key_type & key() const
Returns a non-const reference to the key_type member of the element.
mapped_type & mapped() const
Returns a non-const reference to the mapped_type member of the element.
std::string key_type
The key type of the object.
Definition value.hpp:1244
object_node_handle(object_node_handle &&src) noexcept
Take over the element owned by src, if any. src is left empty.
Represents an exact path in some JSON structure.
Definition path.hpp:107
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Definition value.hpp:113
void assign(TForwardIterator first, TForwardIterator last)
Assign the contents of range [first, last) to this array.
Definition value.hpp:830
const value & at_path(std::string_view p) const
Get the value specified by the path p.
value(const std::string_view &value)
Create a kind::string with the given value.
void insert(std::initializer_list< std::pair< std::wstring, value > > items)
Insert items into this object.
constexpr value()
Default-construct this to null.
Definition value.hpp:438
value(std::nullptr_t)=delete
The nullptr overload will fail to compile – use jsonv::null if you want a kind::null.
std::pair< object_iterator, bool > emplace(const std::wstring &key, value val)
Construct an element from key and val and insert it into this object.
array_iterator erase(const_array_iterator first, const_array_iterator last)
Erase the range [first, last) from this array.
value(float value)
Create a kind::decimal with the given value.
value & at_path(const path &p)
Get the value specified by the path p.
const value & at_path(size_type p) const
Get the value specified by the path p.
value & path(const path &p)
Get or create the value specified by the path p.
friend std::ostream & operator<<(std::ostream &stream, const value &val)
Output this value to a stream, through an ostream_encoder.
const_object_iterator end_object() const
Get an iterator to the one past the end of this object.
basic_object_iterator< object_value_type, std::map< std::string, value >::iterator > object_iterator
The object_iterator is applicable when kind is kind::object.
Definition value.hpp:412
std::pair< object_iterator, bool > try_emplace(const std::wstring &key, value val)
Insert val with the given key into this object, but only if no element with an equivalent key is alre...
value & at_path(std::string_view p)
Get the value specified by the path p.
void assign(size_type count, const value &val)
Assign count elements to this array with val.
object_iterator erase(const_object_iterator position)
Erase the item at the given position.
value & at_path(size_type p)
Get the value specified by the path p.
const value & at_path(const path &p) const
Get the value specified by the path p.
size_type count_path(const path &p) const
Similar to count, but walks the given path p to determine its presence.
bool operator!=(const value &other) const
Compares two JSON values for inequality.
detail::basic_view< object_iterator, const_object_iterator > object_view
If kind is kind::object, an object_view allows you to access a value as an associative container.
Definition value.hpp:418
array_view as_array() &
View this instance as an array.
object_iterator end_object()
Get an iterator to the one past the end of this object.
const value & operator[](int idx) const
Get the value in this array at the given idx.
Definition value.hpp:773
int compare(const value &other) const
Used to build a strict-ordering of JSON values.
object_node_handle extract(const_object_iterator position)
Unlinks the node that contains the element pointed to by position and returns a node handle that owns...
size_type count_path(std::string_view p) const
Similar to count, but walks the given path p to determine its presence.
void push_back(const value &item)
Push item to the back of this array.
const_object_iterator begin_object() const
Get an iterator to the first key-value pair in this object.
detail::basic_view< array_iterator, const_array_iterator > array_view
If kind is kind::array, an array_view allows you to access a value as a sequence container.
Definition value.hpp:281
object_node_handle extract(const std::string &key)
If the container has an element with the given key, unlinks the node that contains that element from ...
size_type count_path(size_type p) const
Similar to count, but walks the given path p to determine its presence.
value(const wchar_t *value)
Create a kind::string with the given value.
const_array_iterator begin_array() const
Get an iterator to the beginning of this array.
object_insert_return_type insert(object_node_handle &&handle)
Insert the contents of handle.
std::pair< object_iterator, bool > try_emplace(const std::string &key, value val)
Insert val with the given key into this object, but only if no element with an equivalent key is alre...
object_iterator insert(const_object_iterator hint, object_node_handle &&handle)
If handle is an empty node handle, does nothing and returns end_object.
array_iterator erase(const_array_iterator position)
Erase the item at this array's position.
std::pair< object_iterator, bool > insert_or_assign(const std::wstring &key, value val)
Insert val with the given key into this object if no element with an equivalent key is present; other...
bool operator==(const value &other) const
Compares two JSON values for equality.
array_iterator insert(const_array_iterator position, TForwardIterator first, TForwardIterator last)
Insert the range defined by [first, last) at position in this array.
Definition value.hpp:812
void push_back(value &&item)
Push item to the back of this array.
void resize(size_type count, const value &val=value())
Resize the length of this array to count items.
value & at(size_type idx)
Get the value in this array at the given idx.
std::pair< object_iterator, bool > emplace(std::string key, value val)
Construct an element from key and val and insert it into this object.
value(const std::wstring &value)
Create a kind::string with the given value.
const value & at(size_type idx) const
Get the value in this array at the given idx.
const_array_iterator end_array() const
Get an iterator to the end of this array.
value(bool value)
Create a kind::boolean with the given value.
basic_array_iterator< value, value > array_iterator
The array_iterator is applicable when kind is kind::array.
Definition value.hpp:275
~value() noexcept
Destruction will never throw.
value(const value &source)
Copy the contents of source into a new instance.
std::pair< object_iterator, bool > insert_or_assign(const std::string &key, value val)
Insert val with the given key into this object if no element with an equivalent key is present; other...
std::pair< const std::string, value > object_value_type
The type of value stored when kind is kind::object.
Definition value.hpp:407
size_type erase(const std::wstring &key)
Erase the item with the given key.
const_object_iterator position
The position of the inserted node or node with the duplicate key.
Definition value.hpp:429
value(const std::string &value)
Create a kind::string with the given value.
void swap(value &other) noexcept
Swap the value this instance represents with other.
object_iterator begin_object()
Get an iterator to the first key-value pair in this object.
value & operator[](int idx)
Get the value in this array at the given idx.
Definition value.hpp:771
void insert(std::initializer_list< std::pair< std::string, value > > items)
Insert items into this object.
bool inserted
Did the insert operation perform an insert? A value of false indicates there was a key already presen...
Definition value.hpp:433
object_view as_object() &
View this instance as an object.
bool empty() const noexcept
Is the underlying structure empty?
friend std::string to_string(const value &)
Get a string representation of the given value.
value(const char *value)
Create a kind::string with the given value.
void pop_back()
Pop an item off the back of this array.
object_iterator erase(const_object_iterator first, const_object_iterator last)
Erase the range defined by [first, last).
array_iterator insert(const_array_iterator position, value item)
Insert an item into position on this array.
const_object_view as_object() const &
View this instance as an object.
size_type erase(const std::string &key)
Erase the item with the given key.
value & path(size_type p)
Get or create the value specified by the path p.
object_node_handle extract(const std::wstring &key)
If the container has an element with the given key, unlinks the node that contains that element from ...
array_iterator begin_array()
Get an iterator to the beginning of this array.
array_iterator end_array()
Get an iterator to the end of this array.
value(double value)
Create a kind::decimal with the given value.
void assign(std::initializer_list< value > items)
Assign the given items to this array.
value & path(std::string_view p)
Get or create the value specified by the path p.
value(int64_t value)
Create a kind::integer with the given value.
void reserve(size_type count)
Reserve at least count elements in the array.
const_array_view as_array() const &
View this instance as an array.
Type returned from insert operations when this has kind::object.
Definition value.hpp:427
Copyright (c) 2014-2020 by Travis Gockel.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
Definition config.hpp:143
#define JSONV_INTEGER_ALTERNATES_LIST(item)
An item list of types to also consider as an integer.
Definition config.hpp:158
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
Definition config.hpp:124
@ insert
Insert the correct key/value pair as part of serialization.
kind
Describes the kind of data a value holds.
Definition kind.hpp:30
JSONV_PUBLIC std::string to_string(const ast_node_type &type)
Get what operator<< writes for type as a std::string.
JSONV_PUBLIC value object()
Create an empty object.
JSONV_PUBLIC const value null
An instance with kind::null.
JSONV_PUBLIC value array()
Create an empty array value.
Copyright (c) 2019-2020 by Travis Gockel.
STL namespace.
The base type for iterating over array values.
Definition value.hpp:121
The base iterator type for iterating over object types.
Definition value.hpp:290
basic_object_iterator(const basic_object_iterator< U, UIterator > &source, typename std::enable_if< std::is_convertible< U *, T * >::value >::type *=0)
This allows assignment from an object_iterator to a const_object_iterator.
Definition value.hpp:308