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.
70JSONV_NODISCARD JSONV_PUBLIC std::string to_string(const 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) const
153 {
155 ++clone;
156 return clone;
157 }
158
159 basic_array_iterator& operator--()
160 {
161 --_index;
162 return *this;
163 }
164
165 basic_array_iterator operator--(int) const
166 {
168 --clone;
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 {
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 {
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
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
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) const
334 {
335 basic_object_iterator clone(*this);
336 clone.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) const
347 {
348 basic_object_iterator clone(*this);
349 clone.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. **/
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 value(const std::wstring& value);
462
463 /** Create a \c kind::string with the given \a value. Keep in mind that it will be converted to and stored as a
464 * UTF-8 encoded string.
465 *
466 * \param value The value to create with. This must be null-terminated.
467 **/
468 value(const wchar_t* value);
469
470 /** Create a \c kind::integer with the given \a value. **/
472
473 /** Create a \c kind::decimal with the given \a value. **/
474 value(double value);
475
476 /** Create a \c kind::decimal with the given \a value. **/
477 value(float value);
478
479 /** Create a \c kind::boolean with the given \a value. **/
481
482 #define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR(type_) \
483 value(type_ val);
484 JSONV_INTEGER_ALTERNATES_LIST(JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR)
485
486 /** Destruction will never throw. **/
488
489 /** Copy-assigns \c source to this.
490 *
491 * If an exception is thrown during the copy, it is propagated out. This instance will remain unchanged.
492 **/
494
495 /** Move-construct this instance, leaving \a source as a null value. **/
497
498 /** Move-assigns \c source to this, leaving \a source as a null value.
499 *
500 * Unlike a copy, this will never throw.
501 **/
503
504 /** Get this value as a string.
505 *
506 * \throws kind_error if this value does not represent a string.
507 **/
509 const std::string& as_string() const;
510
511 /** Tests if this \c kind is \c kind::string. **/
513 bool is_string() const;
514
515 /** Get this value as a \c std::string_view. It is your responsibility to ensure the \c value instance remains valid.
516 *
517 * \throws kind_error if this value does not represent a string.
518 **/
520 std::string_view as_string_view() const &;
521
522 /** Get this value as a wide string. Keep in mind that this is slower than \c as_string, as the internal storage is
523 * the \c char base \c std::string.
524 *
525 * \throws kind_error if this value does not represent a string.
526 * \throws std::range_error if the stored string is not valid UTF-8.
527 **/
529 std::wstring as_wstring() const;
530
531 /** Get this value as an integer.
532 *
533 * \throws kind_error if this value does not represent an integer.
534 **/
536 int64_t as_integer() const;
537
538 /** Tests if this \c kind is \c kind::integer. **/
540 bool is_integer() const;
541
542 /** Get this value as a decimal. If the value's underlying kind is actually an integer type, cast the integer to a
543 * double before returning. This ignores the potential loss of precision.
544 *
545 * \throws kind_error if this value does not represent a decimal or integer.
546 **/
548 double as_decimal() const;
549
550 /** Tests if this \c kind is \c kind::integer or \c kind::decimal. **/
552 bool is_decimal() const;
553
554 /** Get this value as a boolean.
555 *
556 * \throws kind_error if this value does not represent a boolean.
557 **/
559 bool as_boolean() const;
560
561 /** Tests if this \c kind is \c kind::boolean. **/
563 bool is_boolean() const;
564
565 /** Tests if this \c kind is \c kind::array. **/
567 bool is_array() const;
568
569 /** Tests if this \c kind is \c kind::object. **/
571 bool is_object() const;
572
573 /** Tests if this \c kind is \c kind::null. **/
575 bool is_null() const;
576
577 /** Resets this value to null. **/
578 void clear();
579
580 /** Get this value's kind. **/
582 inline jsonv::kind kind() const
583 {
584 return _kind;
585 }
586
587 /** Get the value specified by the path \a p.
588 *
589 * \throws std::out_of_range if any path along the chain did not exist.
590 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
591 * index when the value is a string).
592 * \throws parse_error if a \c std::string_view was specified that did not have a valid specification (see
593 * \c path::create).
594 **/
595 value& at_path(const path& p);
596 value& at_path(std::string_view p);
597 value& at_path(size_type p);
599 const value& at_path(const path& p) const;
601 const value& at_path(std::string_view p) const;
603 const value& at_path(size_type p) const;
604
605 /** Similar to \c count, but walks the given path \a p to determine its presence.
606 *
607 * \returns \c 1 if the path finds an element; \c 0 if there is no such path in the tree.
608 *
609 * \throws parse_error if a \c std::string_view was specified that did not have a valid specification (see
610 * \c path::create).
611 **/
613 size_type count_path(const path& p) const;
615 size_type count_path(std::string_view p) const;
617 size_type count_path(size_type p) const;
618
619 /** Get or create the value specified by the path \a p. This is the moral equivalent to \c operator[] for paths. If
620 * no value exists at the path, a new one is created as the default (\c null) value. If any path along the way
621 * either does not exist or is \c null, it is created for you, based on the \e implications of the specification
622 * \a p. Unlike \c at_path, which will throw if accessing a non-existent key of an \c object or going past the end
623 * of an \c array, this will simply create that path and fill in the blanks with \c null values.
624 *
625 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
626 * index when the value is a string).
627 * \throws parse_error if a \c std::string_view was specified that did not have a valid specification (see
628 * \c path::create).
629 *
630 * \see at_path
631 **/
632 value& path(const path& p);
633 value& path(std::string_view p);
634 value& path(size_type p);
635
636 /** Swap the value this instance represents with \a other. **/
637 void swap(value& other) noexcept;
638
639 /** Compares two JSON values for equality. Two JSON values are equal if and only if all of the following conditions
640 * apply:
641 *
642 * 1. They have the same valid value for \c kind.
643 * - If \c kind is invalid (memory corruption), then two JSON values are \e not equal, even if they have been
644 * corrupted in the same way and even if they share \c this (a corrupt object is not equal to itself).
645 * 2. The kind comparison is also equal:
646 * - Two null values are always equivalent.
647 * - string, integer and boolean follow the classic rules for their type.
648 * - decimals compare exactly, with signed zeros equal and all NaNs equal (see \c compare).
649 * - objects are equal if they have the same keys and values corresponding with the same key are also equal.
650 * - arrays are equal if they have the same length and the values at each index are also equal.
651 *
652 * \note
653 * The rules for equality are based on Python \c dict and \c list.
654 **/
656 bool operator==(const value& other) const;
657
658 /** Compares two JSON values for inequality. The rules for inequality are the exact opposite of equality.
659 **/
661 bool operator!=(const value& other) const;
662
663 /** Used to build a strict-ordering of JSON values. When comparing values of the same kind, the ordering should
664 * align with your intuition. When comparing values of different kinds, some arbitrary rules were created based on
665 * how "complicated" the author thought the type to be.
666 *
667 * - null: less than everything but null, which it is equal to.
668 * - boolean: false is less than true.
669 * - integer, decimal: compared by their numeric value. Comparisons between two integers do not cast, but comparison
670 * between an integer and a decimal will coerce to decimal. Decimal comparison is exact, without an epsilon
671 * tolerance. Signed zeros compare equal; infinities follow numeric order. All NaNs compare equal to each
672 * other and greater than every non-NaN number, regardless of sign or payload.
673 * - string: compared lexicographically by character code (with basic char strings and non-ASCII encoding, this
674 * might lead to surprising results)
675 * - array: compared lexicographically by elements (recursively following this same technique)
676 * - object: entries in the object are sorted and compared lexicographically, first by key then by value
677 *
678 * \returns -1 if this is less than other by the rules stated above; 0 if this is equal to other; 1 if otherwise.
679 **/
681 int compare(const value& other) const;
682
684 bool operator< (const value& other) const;
686 bool operator> (const value& other) const;
688 bool operator<=(const value& other) const;
690 bool operator>=(const value& other) const;
691
692 /// Output this value to a stream.
693 friend std::ostream& operator<<(std::ostream& stream, const value& val);
694
695 /// Get a string representation of the given \c value.
696 friend std::string to_string(const value&);
697
698 /// \{
699 /// Get an iterator to the beginning of this array.
700 ///
701 /// \throws kind_error if the kind is not an array.
705 const_array_iterator begin_array() const;
706 /// \}
707
708 /// \{
709 /// Get an iterator to the end of this array.
710 ///
711 /// \throws kind_error if the kind is not an array.
715 const_array_iterator end_array() const;
716 /// \}
717
718 /// \{
719 /// View this instance as an array.
720 ///
721 /// \throws kind_error if the kind is not an array.
725 const_array_view as_array() const &;
727 owning_array_view as_array() &&;
728 /// \}
729
730 /// \{
731 /// Get the value in this array at the given \a idx. The overloads which accept an \c int are required to resolve
732 /// the type ambiguity of the literal \c 0 between a size_type and a char*.
733 ///
734 /// \throws kind_error if the kind is not an array.
735 value& operator[](size_type idx);
737 const value& operator[](size_type idx) const;
738 inline value& operator[](int idx) { return operator[](size_type(idx)); }
740 inline const value& operator[](int idx) const { return operator[](size_type(idx)); }
741 /// \}
742
743 /// \{
744 /// Get the value in this array at the given \a idx.
745 ///
746 /// \throws kind_error if the kind is not an array.
747 /// \throws std::out_of_range if the provided \a idx is above \c size.
748 ///
749 value& at(size_type idx);
751 const value& at(size_type idx) const;
752 /// \}
753
754 /// \{
755 /// Push \a item to the back of this array.
756 ///
757 /// \throws kind_error if the kind is not an array.
759 void push_back(const value& item);
760 /// \}
761
762 /// Pop an item off the back of this array.
763 ///
764 /// \throws kind_error if the kind is not an array.
765 /// \throws std::logic_error if the array is empty.
766 void pop_back();
767
768 /// Insert an item into \a position on this array.
769 ///
770 /// \throws kind_error if the kind is not an array.
772
773 /// Insert the range defined by [\a first, \a last) at \a position in this array.
774 ///
775 /// \throws kind_error if the kind is not an array.
776 template <typename TForwardIterator>
778 {
779 difference_type orig_offset = std::distance(const_array_iterator(begin_array()), position);
780
781 for (difference_type offset = orig_offset ; first != last; ++first, ++offset)
782 insert(begin_array() + offset, *first);
783 return begin_array() + orig_offset;
784 }
785
786 /// Assign \a count elements to this array with \a val.
787 ///
788 /// \throws kind_error if the kind is not an array.
789 void assign(size_type count, const value& val);
790
791 /// Assign the contents of range [\a first, \a last) to this array.
792 ///
793 /// \throws kind_error if the kind is not an array.
794 template <typename TForwardIterator>
796 {
797 resize(std::distance(first, last), value());
798 auto iter = begin_array();
799 while (first != last)
800 {
801 *iter = *first;
802 ++iter;
803 ++first;
804 }
805 }
806
807 /// Assign the given \a items to this array.
808 ///
809 /// \throws kind_error if the kind is not an array.
810 void assign(std::initializer_list<value> items);
811
812 /// Reserve at least \a count elements in the array.
813 ///
814 /// \throws kind_error if the kind is not an array.
815 void reserve(size_type count);
816
817 /// Resize the length of this array to \a count items. If the resize creates new elements, fill those newly-created
818 /// elements with \a val.
819 ///
820 /// \throws kind_error if the kind is not an array.
821 void resize(size_type count, const value& val = value());
822
823 /// Erase the item at this array's \a position.
824 ///
825 /// \throws kind_error if the kind is not an array.
827
828 /// Erase the range [\a first, \a last) from this array.
829 ///
830 /// \throws kind_error if the kind is not an array.
832
833 /** Get an iterator to the first key-value pair in this object.
834 *
835 * \throws kind_error if the kind is not an object.
836 **/
840 const_object_iterator begin_object() const;
841
842 /** Get an iterator to the one past the end of this object.
843 *
844 * \throws kind_error if the kind is not an object.
845 **/
849 const_object_iterator end_object() const;
850
851 /** View this instance as an object.
852 *
853 * \throws kind_error if the kind is not an object.
854 **/
858 const_object_view as_object() const &;
860 owning_object_view as_object() &&;
861
862 /** Get the value associated with the given \a key of this object. If the \a key does not exist, it will be created.
863 *
864 * \throws kind_error if the kind is not an object.
865 **/
866 value& operator[](const std::string& key);
867 value& operator[](std::string&& key);
868 value& operator[](const std::wstring& key);
869
870 /** Get the value associated with the given \a key of this object.
871 *
872 * \throws kind_error if the kind is not an object.
873 * \throws std::out_of_range if the \a key is not in this object.
874 **/
875 value& at(const std::string& key);
876 value& at(const std::wstring& key);
878 const value& at(const std::string& key) const;
880 const value& at(const std::wstring& key) const;
881
882 /** Check if the given \a key exists in this object.
883 *
884 * \throws kind_error if the kind is not an object.
885 **/
887 size_type count(const std::string& key) const;
889 size_type count(const std::wstring& key) const;
890
891 /** Attempt to locate a key-value pair with the provided \a key in this object.
892 *
893 * \throws kind_error if the kind is not an object.
894 **/
896 object_iterator find(const std::string& key);
898 object_iterator find(const std::wstring& key);
900 const_object_iterator find(const std::string& key) const;
902 const_object_iterator find(const std::wstring& key) const;
903
904 /// \{
905 /// Insert \a pair into this object. If \a hint is provided, this insertion could be optimized.
906 ///
907 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key).
908 /// \throws kind_error if the kind is not an object.
909 std::pair<object_iterator, bool> insert(std::pair<std::string, value> pair);
910 std::pair<object_iterator, bool> insert(std::pair<std::wstring, value> pair);
913
914 /// Insert range defined by [\a first, \a last) into this object.
915 ///
916 /// \throws kind_error if the kind is not an object.
919 {
920 // end_object() is not invalidated by insertion, so the hint can be hoisted out of the loop. It pays off for an
921 // ascending source of unique keys which all sort after what this object already holds -- most importantly when
922 // building a fresh object -- costing amortized constant time per element. Anything else just misses the hint
923 // and falls back to the usual logarithmic lookup: the hint is only taken for a key sorting strictly after the
924 // greatest one present, so a repeated key does not benefit.
925 const_object_iterator hint = end_object();
926
927 for ( ; first != last; ++first)
928 insert(hint, *first);
929 }
930
931 /// Insert the contents of \a handle. If \a handle is empty, this does nothing. If the insertion succeeds, \a handle
932 /// is moved from and left empty; otherwise it retains ownership of the element.
933 ///
934 /// \returns If \a handle is empty, \c inserted is \c false and \c position is `end_object()`. If the insertion took
935 /// place, \c inserted is \c true and \c position points to the inserted element. If the insertion was attempted
936 /// but failed, \c inserted is \c false and \c position points to an element with a key equivalent to
937 /// `handle.key()`.
938 /// \throws kind_error if the kind is not an object.
940
941 /// If \a handle is an empty node handle, does nothing and returns \ref end_object. Otherwise, inserts the element
942 /// owned by \a handle into the container, if the container doesn't already contain an element with a key equivalent
943 /// to `handle.key()` and returns the iterator pointing to the element with key equivalent to `handle.key()`. If the
944 /// insertion succeeds, \a handle is moved from, otherwise it retains ownership of the element. The element is
945 /// inserted as close as possible to the position just prior to \a hint.
946 ///
947 /// \returns An iterator pointing to an element with a key equivalent to `handle.key()` if \a handle was not empty.
948 /// If \a handle was empty, `end_object()`.
949 /// \throws kind_error if the kind is not an object.
951
952 /// Insert \a items into this object.
953 ///
954 /// \throws kind_error if the kind is not an object.
955 void insert(std::initializer_list<std::pair<std::string, value>> items);
956 void insert(std::initializer_list<std::pair<std::wstring, value>> items);
957 /// \}
958
959 /// \{
960 /// Construct an element from \a key and \a val and insert it into this object. If an element with an equivalent
961 /// key is already present, the insertion does not happen and the existing element is not overwritten.
962 ///
963 /// \note
964 /// As with \c std::map::emplace, the node is constructed before the key is looked up, so a call which does not
965 /// insert has still allocated and destroyed one. Prefer \ref try_emplace when collisions are expected.
966 ///
967 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
968 /// whose \c second is \c true if the insertion took place.
969 /// \throws kind_error if the kind is not an object.
970 ///
971 /// \see insert
972 /// \see try_emplace
973 std::pair<object_iterator, bool> emplace(std::string key, value val);
974 std::pair<object_iterator, bool> emplace(const std::wstring& key, value val);
975 /// \}
976
977 /// \{
978 /// Insert \a val with the given \a key into this object, but only if no element with an equivalent key is already
979 /// present. Unlike \ref emplace, \a key is left alone and no node is allocated when the key is already present.
980 ///
981 /// \note
982 /// \a val is taken by value, so a caller who passes `std::move(x)` has moved from \c x by the time this function
983 /// is entered whether or not the insertion happens. It is the key and the node which are spared, not \a val.
984 ///
985 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
986 /// whose \c second is \c true if the insertion took place.
987 /// \throws kind_error if the kind is not an object.
988 ///
989 /// \see insert
990 /// \see insert_or_assign
991 std::pair<object_iterator, bool> try_emplace(const std::string& key, value val);
992 std::pair<object_iterator, bool> try_emplace(const std::wstring& key, value val);
993 /// \}
994
995 /// \{
996 /// Insert \a val with the given \a key into this object if no element with an equivalent key is present;
997 /// otherwise, assign \a val to the existing element. Unlike \ref try_emplace, \a val is stored either way.
998 ///
999 /// \returns A pair whose \c first refers to the inserted or assigned element and whose \c second is \c true if an
1000 /// insertion took place and \c false if an assignment took place. Unlike \ref insert, a \c second of \c false
1001 /// does \e not mean the operation failed -- this function always modifies the object.
1002 /// \throws kind_error if the kind is not an object.
1003 ///
1004 /// \see insert
1005 /// \see try_emplace
1006 std::pair<object_iterator, bool> insert_or_assign(const std::string& key, value val);
1007 std::pair<object_iterator, bool> insert_or_assign(const std::wstring& key, value val);
1008 /// \}
1009
1010 /// \{
1011 /// Erase the item with the given \a key.
1012 ///
1013 /// \returns 1 if \a key was erased; 0 if it did not.
1014 /// \throws kind_error if the kind is not an object.
1015 size_type erase(const std::string& key);
1016 size_type erase(const std::wstring& key);
1017
1018 /// Erase the item at the given \a position.
1019 ///
1020 /// \throws kind_error if the kind is not an object.
1022
1023 /// Erase the range defined by [\a first, \a last).
1024 ///
1025 /// \throws kind_error if the kind is not an object.
1027 /// \}
1028
1029 /// \{
1030 /// Unlinks the node that contains the element pointed to by position and returns a node handle that owns it.
1031 ///
1032 /// \throws kind_error if the kind is not an object.
1034
1035 /// If the container has an element with the given \a key, unlinks the node that contains that element from the
1036 /// container and returns a node handle that owns it. Otherwise, returns an empty node handle.
1037 ///
1038 /// \throws kind_error if the kind is not an object.
1039 object_node_handle extract(const std::string& key);
1040 object_node_handle extract(const std::wstring& key);
1041 /// \}
1042
1043 /** Is the underlying structure empty?
1044 *
1045 * - object: Are there no keys?
1046 * - array: Are there no values?
1047 * - string: Is the string 0 length?
1048 * - null: true (always)
1049 * - all other types: false (always)
1050 *
1051 * \throws nothing
1052 **/
1055
1056 /** Get the number of items in this value.
1057 *
1058 * - object: The number of key/value pairs.
1059 * - array: The number of values.
1060 * - string: The number of code points in the string (including \c \\0 values and counting multi-byte encodings as
1061 * more than one value).
1062 *
1063 * \throws kind_error if the kind is not an object, array or string.
1064 **/
1066 size_type size() const;
1067
1068 /** \addtogroup Algorithm
1069 * \{
1070 **/
1071
1072 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1073 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1074 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1075 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1076 * transformed by \a func.
1077 *
1078 * \param func The function to apply to the element or elements of this instance.
1079 **/
1082
1083 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1084 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1085 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1086 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1087 * transformed by \a func.
1088 *
1089 * \param func The function to apply to the element or elements of this instance.
1090 *
1091 * \note
1092 * This version of \c map provides only a basic exception-safety guarantee. If an exception is thrown while
1093 * transforming a non-scalar \c kind, there is no rollback action, so \c this is left in a usable, but
1094 * \e unpredictable state. If you need a strong exception guarantee, use the constant reference version of \c map.
1095 **/
1098
1099 /** \} **/
1100
1101private:
1104
1105private:
1106 detail::value_storage _data;
1107 jsonv::kind _kind;
1108};
1109
1110/** An instance with \c kind::null. This is intended to be used for convenience and readability (as opposed to using the
1111 * default constructor of \c value.
1112**/
1114
1115/** A user-defined literal for parsing JSON. Uses the default (non-strict) \c parse_options.
1116 *
1117 * \code
1118 * R"({
1119 * "taco": "cat",
1120 * "burrito": "dog",
1121 * "whatever": [ "goes", "here", 1, 2, 3, 4 ]
1122 * })"_json;
1123 * \endcode
1124**/
1126
1127/** Swap the values \a a and \a b. **/
1129
1130/** Create an empty array value. **/
1132
1133/** Create an array value from the given source. **/
1135
1136/** Create an array with contents defined by range [\a first, \a last). **/
1139{
1140 value arr = array();
1141 arr.assign(first, last);
1142 return arr;
1143}
1144
1145/** Create an empty object. **/
1147
1148/** Create an object with key-value pairs from the given \a source. **/
1149JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::string, value>> source);
1150JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::wstring, value>> source);
1151
1152/** Create an object whose contents are defined by range [\a first, \a last). **/
1153template <typename TForwardIterator>
1155{
1156 value obj = object();
1157 obj.insert(first, last);
1158 return obj;
1159}
1160
1161/// A <a href="http://en.cppreference.com/w/cpp/container/node_handle">node handle</a> used when a value is
1162/// \ref kind::object to access elements of the object in potentially destructive manner. This makes it possible to
1163/// modify the contents of a node extracted from an object, and then re-insert it without having to copy the element.
1165{
1166public:
1167 /// The key type of the object.
1168 using key_type = std::string;
1169
1170 /// The mapped type of the object.
1172
1173public:
1174 explicit object_node_handle() noexcept :
1175 _has_value(false)
1176 { }
1177
1178 /// Take over the element owned by \a src, if any. \a src is left \ref empty.
1180
1181 /// Release the element this handle owns, if any, and take over the one owned by \a src, if any. \a src is left
1182 /// \ref empty. Self-assignment has no effect.
1184
1186
1187 /// \returns \c true if the node handle is empty; \c false if otherwise.
1189 bool empty() const noexcept { return !_has_value; }
1190
1191 /// \returns \c false if the node handle is empty; \c true if otherwise.
1193 explicit operator bool() const noexcept { return _has_value; }
1194
1195 /// Returns a non-const reference to the \ref key_type member of the element.
1196 ///
1197 /// \throws std::invalid_argument if the node handle is \ref empty.
1198 key_type& key() const;
1199
1200 /// Returns a non-const reference to the \ref mapped_type member of the element.
1201 ///
1202 /// \throws std::invalid_argument if the node handle is \ref empty.
1204
1205private:
1206 enum class purposeful_construction
1207 { };
1208
1209 explicit object_node_handle(purposeful_construction, key_type, mapped_type) noexcept;
1210
1211 friend class value;
1212
1213private:
1214 bool _has_value;
1215 mutable key_type _key;
1216 mutable mapped_type _value;
1217};
1218
1219/// \}
1220
1221}
1222
1223namespace std
1224{
1225
1226/// Explicit specialization of \c std::hash for \c jsonv::value types so you can store a \c value in an unordered
1227/// container. Hashing results depend on the \c kind for the provided value -- most kinds directly use the hasher for
1228/// their kind (hashing a \c jsonv::value for integer \c 5 should have the same hash value as directly hashing the same
1229/// integer). For aggregate kinds \c array and \c object, hashing visits every sub-element recursively. This might be
1230/// expensive, but is required when storing multiple values with similar layouts in the a set (which is the most common
1231/// use case).
1232template <>
1233struct JSONV_PUBLIC hash<jsonv::value>
1234{
1236 std::size_t operator()(const jsonv::value& val) const noexcept;
1237};
1238
1239}
Copyright (c) 2014-2020 by Travis Gockel.
An adapter for enumeration types.
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:1165
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:1168
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:87
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:795
value(const std::string_view &value)
Create a kind::string with the given value.
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.
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.
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.
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
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.
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() &
object_iterator end_object()
Get an iterator to the one past the end of this object.
int compare(const value &other) const
Used to build a strict-ordering of JSON values.
object_node_handle extract(const_object_iterator position)
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 ...
value(const wchar_t *value)
Create a kind::string with the given value.
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)
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.
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:777
void push_back(value &&item)
void resize(size_type count, const value &val=value())
Resize the length of this array to count items.
value & at(size_type idx)
std::pair< object_iterator, bool > emplace(std::string key, value val)
value(const std::wstring &value)
Create a kind::string with the given value.
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)
std::pair< const std::string, value > object_value_type
The type of value stored when kind is kind::object.
Definition value.hpp:407
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.
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.
size_type erase(const std::string &key)
array_iterator begin_array()
array_iterator end_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(int64_t value)
Create a kind::integer with the given value.
void reserve(size_type count)
Reserve at least count elements in the 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:121
#define JSONV_INTEGER_ALTERNATES_LIST(item)
An item list of types to also consider as an integer.
Definition config.hpp:146
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
Definition config.hpp:102
T extract(const value &from, const formats &fmts)
Extract a C++ value from from using the provided fmts.
Definition extract.hpp:919
@ 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 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