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 <compare>
18#include <cstddef>
19#include <cstdint>
20#include <initializer_list>
21#include <iosfwd>
22#include <iterator>
23#include <functional>
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;
42struct value_access;
43
44union value_storage
45{
46 object_impl* object;
47 array_impl* array;
48 string_impl* string;
49 int64_t integer;
50 double decimal;
51 bool boolean;
52};
53
54/// The longest string a \c value holds in itself rather than in a block of its own.
55inline constexpr std::size_t value_inline_string_capacity = 14U;
56
57/// The \c string_length of a \c kind::string whose text is in a block of its own.
58inline constexpr unsigned char value_string_out_of_line = 0xffU;
59
60/// How a \c value lays out everything but a string short enough to keep in itself.
61struct value_words
62{
64 /// For a \c kind::string, \c value_string_out_of_line; ignored otherwise.
65 unsigned char string_length;
66 value_storage data;
67};
68
69/// How a \c value lays out a string of at most \c value_inline_string_capacity bytes.
70struct value_short_string
71{
73 unsigned char string_length;
74 char text[value_inline_string_capacity];
75};
76
77/// The 16 bytes of a \c value. Both layouts start with the same \c kind and \c string_length, so those can be read
78/// through \c words whichever layout is in use. Both have trivial default constructors, so assigning to either one
79/// makes it the one in use.
80union value_representation
81{
82 value_words words;
83 value_short_string short_string;
84
85 constexpr value_representation() :
86 words{ jsonv::kind::null, 0U, { .object = nullptr } }
87 { }
88};
89
90static_assert(sizeof(value_representation) == 16U, "a value is 16 bytes");
91
92}
93
94/// \defgroup Value
95/// JSON \ref value instances.
96///
97/// The side-effect-free parts of this API -- the predicates, the accessors, the constant lookups and everything which
98/// returns a freshly built \ref value -- are \c JSONV_NODISCARD. Calling one and dropping the result does nothing at
99/// all, so the compiler says so. The accessors which create on demand (non-`const` \ref value::path and
100/// \ref value::operator[] for an object key) and the mutators are deliberately left alone, since discarding those is
101/// how they are normally used.
102/// \{
103
104/// Get a string representation of the given \c value.
106
107/// Thrown from various \c value methods when attempting to perform an operation which is not valid for the \c kind of
108/// value.
110 public std::logic_error
111{
112public:
113 explicit kind_error(const std::string& description);
114
115 virtual ~kind_error() noexcept;
116};
117
118/// Represents a single JSON value, which can be any one of a potential \c kind, each behaving slightly differently.
119/// Instances will vary their behavior based on their kind -- functions will throw a \c kind_error if the operation does
120/// not apply to the value's kind. For example, it does not make sense to call \c find on an \c integer.
121///
122/// - \c kind::null
123/// You cannot do anything with this...it is just null.
124/// - \c kind::boolean
125/// These values can be \c true or \c false.
126/// - \c kind::integer
127/// A numeric value which can be added, subtracted and all the other things you would expect.
128/// - \c kind::decimal
129/// Floating-point values should be considered "more general" than integers -- you may request an integer value as a
130/// decimal, but you cannot request a decimal as an integer, even when doing so would not require rounding. The
131/// literal \c 20.0 will always have \c kind::decimal.
132/// - \c kind::string
133/// A UTF-8 encoded string, read through the \c std::string_view which \c as_string returns. Some random functions
134/// work in the cases where it makes sense (for example: \c empty and \c size), but in general, string manipulation
135/// should be done after calling \c as_string. A string of up to 14 bytes is kept in the \c value itself, and a longer
136/// one in a single allocation of its own.
137/// - \c kind::array
138/// An array behaves like a \c std::vector: its elements are contiguous, growing it may move them all, and inserting
139/// or erasing shifts the elements after the position. Element references are invalidated when \c std::vector's
140/// would be. The elements share one allocation with the array's size and capacity, and an empty array may hold no
141/// allocation at all. If you feel the documentation is lacking, read this:
142/// http://en.cppreference.com/w/cpp/container/vector.
143/// - \c kind::object
144/// An object behaves like a \c std::flat_map: its members are kept sorted by key in one contiguous array, so it
145/// iterates in key order, looking a key up is a binary search, and inserting or erasing shifts the members after
146/// the position and invalidates iterators and references to them. Dereferencing an \c object_iterator gives an
147/// \c object_reference, a proxy like \c std::flat_map::reference. The members share one allocation with the
148/// object's size and capacity, and an empty object may hold no allocation at all. If you feel the documentation is
149/// lacking, read this: http://en.cppreference.com/w/cpp/container/flat_map. This library follows the recommendation in RFC 7159
150/// to not allow for duplicate keys because most other libraries can not deal with it. It would also make the AST
151/// significantly more painful.
152///
153/// \see http://json.org/
154/// \see http://tools.ietf.org/html/rfc7159
156{
157public:
158 typedef std::size_t size_type;
159 typedef std::ptrdiff_t difference_type;
160
161 /** The base type for iterating over array values. **/
162 template <typename T, typename TArrayView>
164 {
165 public:
166 using iterator_category = std::random_access_iterator_tag;
167 using value_type = T;
168 using difference_type = std::ptrdiff_t;
169 using pointer = T*;
170 using reference = T&;
172 _owner(0),
173 _index(0)
174 { }
175
176 basic_array_iterator(TArrayView* owner, size_type index) :
177 _owner(owner),
178 _index(index)
179 { }
180
181 template <typename U, typename UArrayView>
183 typename std::enable_if<std::is_convertible<U*, T*>::value>::type* = 0
184 ) :
185 _owner(source._owner),
186 _index(source._index)
187 { }
188
189 basic_array_iterator& operator++()
190 {
191 ++_index;
192 return *this;
193 }
194
195 basic_array_iterator operator++(int)
196 {
197 basic_array_iterator clone = *this;
198 ++*this;
199 return clone;
200 }
201
202 basic_array_iterator& operator--()
203 {
204 --_index;
205 return *this;
206 }
207
208 basic_array_iterator operator--(int)
209 {
210 basic_array_iterator clone = *this;
211 --*this;
212 return clone;
213 }
214
215 template <typename U, typename UArrayView>
217 bool operator==(const basic_array_iterator<U, UArrayView>& other) const
218 {
219 return _owner == other._owner && _index == other._index;
220 }
221
222 template <typename U, typename UArrayView>
224 bool operator!=(const basic_array_iterator<U, UArrayView>& other) const
225 {
226 return !operator==(other);
227 }
228
230 T& operator*() const
231 {
232 return _owner->operator[](_index);
233 }
234
236 T* operator->() const
237 {
238 return &_owner->operator[](_index);
239 }
240
241 basic_array_iterator& operator+=(size_type n)
242 {
243 _index += n;
244 return *this;
245 }
246
248 basic_array_iterator operator+(size_type n) const
249 {
250 basic_array_iterator clone = *this;
251 clone += n;
252 return clone;
253 }
254
255 basic_array_iterator& operator-=(size_type n)
256 {
257 _index -= n;
258 return *this;
259 }
260
262 basic_array_iterator operator-(size_type n) const
263 {
264 basic_array_iterator clone = *this;
265 clone -= n;
266 return clone;
267 }
268
270 difference_type operator-(const basic_array_iterator& other) const
271 {
272 return difference_type(_index) - difference_type(other._index);
273 }
274
276 bool operator<(const basic_array_iterator& rhs) const
277 {
278 return _index < rhs._index;
279 }
280
282 bool operator<=(const basic_array_iterator& rhs) const
283 {
284 return _index <= rhs._index;
285 }
286
288 bool operator>(const basic_array_iterator& rhs) const
289 {
290 return _index > rhs._index;
291 }
292
294 bool operator>=(const basic_array_iterator& rhs) const
295 {
296 return _index >= rhs._index;
297 }
298
300 T& operator[](size_type n) const
301 {
302 return _owner->operator[](_index + n);
303 }
304 private:
305 template <typename U, typename UArrayView>
306 friend struct basic_array_iterator;
307
308 friend class value;
309
310 private:
311 TArrayView* _owner;
312 size_type _index;
313 };
314
315 /** The \c array_iterator is applicable when \c kind is \c kind::array. It allows you to use algorithms as if
316 * a \c value was a normal sequence container.
317 **/
320
321 /** If \c kind is \c kind::array, an \c array_view allows you to access a value as a sequence container. This is
322 * most useful for range-based for loops.
323 **/
324 typedef detail::basic_view<array_iterator, const_array_iterator> array_view;
325 typedef detail::basic_view<const_array_iterator> const_array_view;
326 typedef detail::basic_owning_view<value, array_iterator, const_array_iterator> owning_array_view;
327
328 /** The type of value stored when \c kind is \c kind::object, as an owning pair. Iterating an object does not give
329 * references to this type: members are stored sorted by key in contiguous memory, and an iterator gives an
330 * \ref object_reference instead. Converting one into this type copies the member, so it has to be asked for.
331 **/
332 typedef std::pair<const std::string, value> object_value_type;
333
334 /** What dereferencing an \c object_iterator (\c TValue of \c value) or a \c const_object_iterator
335 * (\c TValue of `const value`) gives: references to the key and value of one member. Like the \c reference of
336 * \c std::flat_map, it is a proxy returned by value, so `auto& m : obj.as_object()` does not compile -- write
337 * `auto&& m`, `const auto& m` or `auto&& [key, val]`. The key is always \c const, since changing it would break
338 * the order members are kept in.
339 *
340 * The conversion to \ref object_value_type is \c explicit because it copies the value. A loop written as
341 * `const value::object_value_type& m : obj.as_object()` -- which before members were stored contiguously bound
342 * straight to the member -- would otherwise still compile and deep-copy every one of them.
343 **/
344 template <typename TValue>
346 {
347 public:
348 /// The type of \ref first, as in \c std::pair, which this stands in for.
349 using first_type = const std::string;
350
351 /// The type of \ref second, as in \c std::pair.
352 using second_type = TValue;
353
354 public:
355 /// The key of the member.
356 const std::string& first;
357
358 /// The value of the member.
359 TValue& second;
360
361 public:
362 /// Refer to \a key and \a val.
363 basic_object_reference(const std::string& key, TValue& val) noexcept :
364 first(key),
365 second(val)
366 { }
367
368 /// Refer to the key and value of \a pair.
369 basic_object_reference(std::conditional_t<std::is_const_v<TValue>, const object_value_type&, object_value_type&>
370 pair
371 ) noexcept :
372 first(pair.first),
373 second(pair.second)
374 { }
375
376 /// This allows conversion from an \c object_reference to a \c const_object_reference.
377 template <typename UValue,
378 typename = std::enable_if_t< !std::is_same_v<UValue, TValue>
379 && std::is_convertible_v<UValue&, TValue&>
380 >
381 >
383 first(source.first),
384 second(source.second)
385 { }
386
387 /// Copy the member into an \ref object_value_type.
388 ///
389 /// \tparam TPair Always \ref object_value_type. It is a parameter so that nothing names that pair until the
390 /// conversion is used: MSVC instantiates a type a template's body names when it reads the body, and here that
391 /// is before \c value is complete.
392 template <typename TPair, typename = std::enable_if_t<std::is_same_v<TPair, object_value_type>>>
394 explicit operator TPair() const
395 {
396 return TPair(first, second);
397 }
398 };
399
400 /** \see basic_object_reference **/
402
403 /** \see basic_object_reference **/
405
406 /** The base iterator type for iterating over object types. It is a random-access iterator over the members of an
407 * object, which are kept sorted by key, and dereferences to a \ref basic_object_reference. Like
408 * \c std::vector<bool>::iterator, it gives \c std::random_access_iterator_tag as its \c iterator_category although
409 * its \c reference is a proxy: the functions which dispatch on the category, like \c std::prev and
410 * \c std::advance, need it to step backward or jump.
411 *
412 * Like the iterators of a \c std::vector, these are invalidated by inserting into or erasing from the object.
413 **/
414 template <typename TValue, typename TMember>
416 {
417 public:
418 /// What this models in C++20 terms: a random-access iterator, whose \c reference may be a proxy.
419 using iterator_concept = std::random_access_iterator_tag;
420
421 /// What this gives the functions which dispatch on the category. \see basic_object_iterator
422 using iterator_category = std::random_access_iterator_tag;
423 using value_type = object_value_type;
424 using difference_type = std::ptrdiff_t;
426
427 /// What \c operator-> returns: it holds the \c reference, so `iter->first` and `iter->second` work.
428 struct pointer
429 {
430 /// The member the iterator was at.
432
433 /// The member the iterator was at, for the built-in \c -> to reach into.
434 const reference* operator->() const noexcept
435 {
436 return &ref;
437 }
438 };
439
440 public:
441 basic_object_iterator() noexcept :
442 _member(nullptr)
443 { }
444
445 /** This allows conversion from an \c object_iterator to a \c const_object_iterator. **/
446 template <typename UValue,
447 typename UMember,
448 typename = std::enable_if_t< !std::is_same_v<UMember, TMember>
449 && std::is_convertible_v<UMember*, TMember*>
450 >
451 >
453 _member(source._member)
454 { }
455
456 basic_object_iterator& operator++() noexcept
457 {
458 ++_member;
459 return *this;
460 }
461
462 basic_object_iterator operator++(int) noexcept
463 {
464 basic_object_iterator clone(*this);
465 ++_member;
466 return clone;
467 }
468
469 basic_object_iterator& operator--() noexcept
470 {
471 --_member;
472 return *this;
473 }
474
475 basic_object_iterator operator--(int) noexcept
476 {
477 basic_object_iterator clone(*this);
478 --_member;
479 return clone;
480 }
481
482 basic_object_iterator& operator+=(difference_type n) noexcept
483 {
484 _member += n;
485 return *this;
486 }
487
488 basic_object_iterator& operator-=(difference_type n) noexcept
489 {
490 _member -= n;
491 return *this;
492 }
493
495 basic_object_iterator operator+(difference_type n) const noexcept
496 {
497 return basic_object_iterator(_member + n);
498 }
499
501 friend basic_object_iterator operator+(difference_type n, const basic_object_iterator& iter) noexcept
502 {
503 return iter + n;
504 }
505
507 basic_object_iterator operator-(difference_type n) const noexcept
508 {
509 return basic_object_iterator(_member - n);
510 }
511
512 template <typename UValue, typename UMember>
514 difference_type operator-(const basic_object_iterator<UValue, UMember>& other) const noexcept
515 {
516 return _member - other._member;
517 }
518
519 template <typename UValue, typename UMember>
521 bool operator==(const basic_object_iterator<UValue, UMember>& other) const noexcept
522 {
523 return _member == other._member;
524 }
525
526 template <typename UValue, typename UMember>
528 auto operator<=>(const basic_object_iterator<UValue, UMember>& other) const noexcept
529 {
530 return _member <=> other._member;
531 }
532
534 reference operator*() const noexcept
535 {
536 return reference(_member->first, _member->second);
537 }
538
540 pointer operator->() const noexcept
541 {
542 return pointer{ **this };
543 }
544
546 reference operator[](difference_type n) const noexcept
547 {
548 return *(*this + n);
549 }
550
551 private:
552 template <typename UValue, typename UMember>
553 friend struct basic_object_iterator;
554
555 friend class value;
556
557 explicit basic_object_iterator(TMember* member) noexcept :
558 _member(member)
559 { }
560
561 private:
562 TMember* _member;
563 };
564
565 /** The \c object_iterator is applicable when \c kind is \c kind::object. It allows you to use algorithms as if
566 * a \c value was a normal associative container.
567 **/
570
571 /** If \c kind is \c kind::object, an \c object_view allows you to access a value as an associative container.
572 * This is most useful for range-based for loops.
573 **/
574 typedef detail::basic_view<object_iterator, const_object_iterator> object_view;
575 typedef detail::basic_view<const_object_iterator> const_object_view;
576 typedef detail::basic_owning_view<value, object_iterator, const_object_iterator> owning_object_view;
577
578 /// Type returned from \c insert operations when this has \ref kind::object. It is generally compatible with the
579 /// \c insert_return_type of \c std::map, with the notable lack of \c node.
580 ///
581 /// \see insert
583 {
584 /// The position of the inserted member or the member with the duplicate key.
586
587 /// Did the insert operation perform an insert? A value of \c false indicates there was a key already present
588 /// with the same name.
590 };
591
592public:
593 /** Default-construct this to null. **/
594 constexpr value() = default;
595
596 /// The nullptr overload will fail to compile -- use \c jsonv::null if you want a \c kind::null.
597 value(std::nullptr_t) = delete;
598
599 /** Copy the contents of \a source into a new instance. **/
600 value(const value& source);
601
602 /** Create a \c kind::string with the given \a value. **/
603 value(const std::string& value);
604
605 /** Create a \c kind::string with the given \a value. **/
606 value(const std::string_view& value);
607
608 /// Create a \c kind::string with the given \a value.
609 ///
610 /// \param value The value to create with. This must be null-terminated.
611 value(const char* value);
612
613 /// Create a \c kind::string with the given \a value. Keep in mind that it will be converted to and stored as a
614 /// UTF-8 encoded string.
615 ///
616 /// \throws std::range_error if \a value is not valid UTF-16, such as when it holds an unpaired surrogate or, where
617 /// \c wchar_t is 32 bits, a code unit above 0xFFFF.
618 value(const std::wstring& value);
619
620 /** Create a \c kind::string with the given \a value. Keep in mind that it will be converted to and stored as a
621 * UTF-8 encoded string.
622 *
623 * \param value The value to create with. This must be null-terminated.
624 * \throws std::range_error if \a value is not valid UTF-16, such as when it holds an unpaired surrogate or, where
625 * \c wchar_t is 32 bits, a code unit above 0xFFFF.
626 **/
627 value(const wchar_t* value);
628
629 /** Create a \c kind::integer with the given \a value. **/
630 value(int64_t value);
631
632 /** Create a \c kind::decimal with the given \a value. **/
633 value(double value);
634
635 /** Create a \c kind::decimal with the given \a value. **/
636 value(float value);
637
638 /** Create a \c kind::boolean with the given \a value. **/
640
641 #define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR(type_) \
642 value(type_ val);
643 JSONV_INTEGER_ALTERNATES_LIST(JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR)
644 #undef JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR
645
646 /** Destruction will never throw. **/
647 ~value() noexcept;
648
649 /** Copy-assigns \c source to this.
650 *
651 * If an exception is thrown during the copy, it is propagated out. This instance will remain unchanged.
652 **/
653 value& operator=(const value& source);
654
655 /** Move-construct this instance, leaving \a source as a null value. **/
656 value(value&& source) noexcept;
657
658 /** Move-assigns \c source to this, leaving \a source as a null value.
659 *
660 * Unlike a copy, this will never throw.
661 **/
662 value& operator=(value&& source) noexcept;
663
664 /** Get this value as a string. The view is into this \c value, so it is good until the value changes or goes away:
665 * `auto text = parse(input).as_string();` leaves \c text referring to a destroyed temporary. Make a
666 * \c std::string from it to keep the text, or to get a NUL-terminated \c c_str.
667 *
668 * \throws kind_error if this value does not represent a string.
669 **/
671 std::string_view as_string() const;
672
673 /** Tests if this \c kind is \c kind::string. **/
675 bool is_string() const;
676
677 /** The same as \c as_string. It is your responsibility to ensure the \c value instance remains valid.
678 *
679 * \throws kind_error if this value does not represent a string.
680 **/
682 std::string_view as_string_view() const &;
683
684 /** Get this value as a wide string. Keep in mind that this is slower than \c as_string, as the text is stored as
685 * UTF-8 and has to be converted. The result is UTF-16 even where \c wchar_t is 32 bits, so a code point outside
686 * the BMP takes a surrogate pair there too.
687 *
688 * \throws kind_error if this value does not represent a string.
689 * \throws std::range_error if the stored string is not valid UTF-8.
690 **/
692 std::wstring as_wstring() const;
693
694 /** Get this value as an integer.
695 *
696 * \throws kind_error if this value does not represent an integer.
697 **/
699 int64_t as_integer() const;
700
701 /** Tests if this \c kind is \c kind::integer. **/
703 bool is_integer() const;
704
705 /** Get this value as a decimal. If the value's underlying kind is actually an integer type, cast the integer to a
706 * double before returning. This ignores the potential loss of precision.
707 *
708 * \throws kind_error if this value does not represent a decimal or integer.
709 **/
711 double as_decimal() const;
712
713 /** Tests if this \c kind is \c kind::integer or \c kind::decimal. **/
715 bool is_decimal() const;
716
717 /** Get this value as a boolean.
718 *
719 * \throws kind_error if this value does not represent a boolean.
720 **/
722 bool as_boolean() const;
723
724 /** Tests if this \c kind is \c kind::boolean. **/
726 bool is_boolean() const;
727
728 /** Tests if this \c kind is \c kind::array. **/
730 bool is_array() const;
731
732 /** Tests if this \c kind is \c kind::object. **/
734 bool is_object() const;
735
736 /** Tests if this \c kind is \c kind::null. **/
738 bool is_null() const;
739
740 /** Resets this value to null. **/
741 void clear();
742
743 /** Get this value's kind. **/
745 inline jsonv::kind kind() const
746 {
747 return _repr.words.kind;
748 }
749
750 /// \{
751
752 /** Get the value specified by the path \a p.
753 *
754 * \throws std::out_of_range if any path along the chain did not exist.
755 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
756 * index when the value is a string).
757 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
758 * (see \c path::create).
759 **/
760 value& at_path(const path& p);
761 value& at_path(std::string_view p);
762 value& at_path(size_type p);
764 const value& at_path(const path& p) const;
766 const value& at_path(std::string_view p) const;
768 const value& at_path(size_type p) const;
769 /// \}
770
771 /// \{
772
773 /** Similar to \c count, but walks the given path \a p to determine its presence.
774 *
775 * \returns \c 1 if the path finds an element; \c 0 if there is no such path in the tree.
776 *
777 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
778 * (see \c path::create).
779 **/
781 size_type count_path(const path& p) const;
783 size_type count_path(std::string_view p) const;
785 size_type count_path(size_type p) const;
786 /// \}
787
788 /// \{
789
790 /** Get or create the value specified by the path \a p. This is the moral equivalent to \c operator[] for paths. If
791 * no value exists at the path, a new one is created as the default (\c null) value. If any path along the way
792 * either does not exist or is \c null, it is created for you, based on the \e implications of the specification
793 * \a p. Unlike \c at_path, which will throw if accessing a non-existent key of an \c object or going past the end
794 * of an \c array, this will simply create that path and fill in the blanks with \c null values.
795 *
796 * \throws kind_error if the path traversal is not valid for the value (for example: if the path specifies an array
797 * index when the value is a string).
798 * \throws std::invalid_argument if a \c std::string_view was specified that did not have a valid specification
799 * (see \c path::create).
800 * \throws std::length_error if the path has an array index which no array can hold, such as the largest
801 * \c std::size_t.
802 * \throws std::bad_alloc if there is not enough memory to create what the path needs.
803 *
804 * If this throws, for any reason, \c *this is left as it was. What the path needs is built apart from the tree and
805 * 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
806 * key on the way to the failing index is not created. A path which already exists is only followed, with nothing
807 * allocated.
808 *
809 * \see at_path
810 **/
811 value& path(const path& p);
812 value& path(std::string_view p);
813 value& path(size_type p);
814 /// \}
815
816 /** Swap the value this instance represents with \a other. **/
817 void swap(value& other) noexcept;
818
819 /** Compares two JSON values for equality. Two JSON values are equal if and only if all of the following conditions
820 * apply:
821 *
822 * 1. They have the same valid value for \c kind, where \c kind::integer and \c kind::decimal count as the same.
823 * - If \c kind is invalid (memory corruption), then two JSON values are \e not equal, even if they have been
824 * corrupted in the same way and even if they share \c this (a corrupt object is not equal to itself).
825 * 2. The kind comparison is also equal:
826 * - Two null values are always equivalent.
827 * - string, integer and boolean follow the classic rules for their type.
828 * - decimals compare exactly, with signed zeros equal and all NaNs equal (see \c compare).
829 * - an integer and a decimal are equal only when the decimal holds exactly that integer (see \c compare).
830 * - objects are equal if they have the same keys and values corresponding with the same key are also equal.
831 * - arrays are equal if they have the same length and the values at each index are also equal.
832 *
833 * \note
834 * The rules for equality are based on Python \c dict and \c list.
835 **/
837 bool operator==(const value& other) const;
838
839 /** Compares two JSON values for inequality. The rules for inequality are the exact opposite of equality.
840 **/
842 bool operator!=(const value& other) const;
843
844 /** Used to build a strict-ordering of JSON values. When comparing values of the same kind, the ordering should
845 * align with your intuition. When comparing values of different kinds, some arbitrary rules were created based on
846 * how "complicated" the author thought the type to be.
847 *
848 * - null: less than everything but null, which it is equal to.
849 * - boolean: false is less than true.
850 * - integer, decimal: compared by their exact numeric value. An integer is never converted to a decimal to
851 * compare it with one, so \c 9007199254740993 is greater than the decimal \c 9007199254740992.0 even though
852 * converting it would round to that decimal. Decimal comparison is exact, without an epsilon tolerance. Signed
853 * zeros compare equal to each other and to the integer \c 0; infinities follow numeric order. All NaNs compare
854 * equal to each other and greater than every other number, regardless of sign or payload.
855 * - string: compared lexicographically by character code (with basic char strings and non-ASCII encoding, this
856 * might lead to surprising results)
857 * - array: compared lexicographically by elements (recursively following this same technique)
858 * - object: entries in the object are sorted and compared lexicographically, first by key then by value
859 *
860 * \returns A negative number if this is less than other by the rules stated above; 0 if this is equal to other; a
861 * positive number otherwise. Only the sign is meaningful: strings and object keys pass on the result of
862 * \c std::string::compare, which need not be -1 or 1.
863 **/
865 int compare(const value& other) const;
866
868 bool operator< (const value& other) const;
870 bool operator> (const value& other) const;
872 bool operator<=(const value& other) const;
874 bool operator>=(const value& other) const;
875
876 /// Output this value to a stream, through an \c ostream_encoder. The stream's format flags, width, fill and locale
877 /// do not change the text written.
878 friend std::ostream& operator<<(std::ostream& stream, const value& val);
879
880 /// Get a string representation of the given \c value.
881 friend std::string to_string(const value&);
882
883 /// \{
884
885 /// Get an iterator to the beginning of this array.
886 ///
887 /// \throws kind_error if the kind is not an array.
892 /// \}
893
894 /// \{
895
896 /// Get an iterator to the end of this array.
897 ///
898 /// \throws kind_error if the kind is not an array.
903 /// \}
904
905 /// \{
906
907 /// View this instance as an array.
908 ///
909 /// \throws kind_error if the kind is not an array.
913 const_array_view as_array() const &;
915 owning_array_view as_array() &&;
916 /// \}
917
918 /// \{
919
920 /// Get the value in this array at the given \a idx. The overloads which accept an \c int are required to resolve
921 /// the type ambiguity of the literal \c 0 between a size_type and a char*.
922 ///
923 /// \throws kind_error if the kind is not an array.
924 value& operator[](size_type idx);
926 const value& operator[](size_type idx) const;
927 inline value& operator[](int idx) { return operator[](size_type(idx)); }
929 inline const value& operator[](int idx) const { return operator[](size_type(idx)); }
930 /// \}
931
932 /// \{
933
934 /// Get the value in this array at the given \a idx.
935 ///
936 /// \throws kind_error if the kind is not an array.
937 /// \throws std::out_of_range if the provided \a idx is above \c size.
938 ///
939 value& at(size_type idx);
941 const value& at(size_type idx) const;
942 /// \}
943
944 /// \{
945
946 /// Push \a item to the back of this array.
947 ///
948 /// \throws kind_error if the kind is not an array.
949 void push_back(value&& item);
950 void push_back(const value& item);
951 /// \}
952
953 /// Pop an item off the back of this array.
954 ///
955 /// \throws kind_error if the kind is not an array.
956 /// \throws std::logic_error if the array is empty.
957 void pop_back();
958
959 /// Insert an item into \a position on this array.
960 ///
961 /// \throws kind_error if the kind is not an array.
963
964 /// Insert the range defined by [\a first, \a last) at \a position in this array.
965 ///
966 /// \throws kind_error if the kind is not an array.
967 template <typename TForwardIterator>
968 array_iterator insert(const_array_iterator position, TForwardIterator first, TForwardIterator last)
969 {
970 difference_type orig_offset = std::distance(const_array_iterator(begin_array()), position);
971
972 for (difference_type offset = orig_offset ; first != last; ++first, ++offset)
973 insert(begin_array() + offset, *first);
974 return begin_array() + orig_offset;
975 }
976
977 /// Assign \a count elements to this array with \a val.
978 ///
979 /// \throws kind_error if the kind is not an array.
980 void assign(size_type count, const value& val);
981
982 /// Assign the contents of range [\a first, \a last) to this array.
983 ///
984 /// \throws kind_error if the kind is not an array.
985 template <typename TForwardIterator>
986 void assign(TForwardIterator first, TForwardIterator last)
987 {
988 resize(std::distance(first, last), value());
989 auto iter = begin_array();
990 while (first != last)
991 {
992 *iter = *first;
993 ++iter;
994 ++first;
995 }
996 }
997
998 /// Assign the given \a items to this array.
999 ///
1000 /// \throws kind_error if the kind is not an array.
1001 void assign(std::initializer_list<value> items);
1002
1003 /// Reserve at least \a count elements in the array.
1004 ///
1005 /// \throws kind_error if the kind is not an array.
1006 void reserve(size_type count);
1007
1008 /// Resize the length of this array to \a count items. If the resize creates new elements, fill those newly-created
1009 /// elements with \a val.
1010 ///
1011 /// \throws kind_error if the kind is not an array.
1012 void resize(size_type count, const value& val = value());
1013
1014 /// Erase the item at this array's \a position.
1015 ///
1016 /// \throws kind_error if the kind is not an array.
1018
1019 /// Erase the range [\a first, \a last) from this array.
1020 ///
1021 /// \throws kind_error if the kind is not an array.
1023
1024 /// \{
1025
1026 /** Get an iterator to the first key-value pair in this object.
1027 *
1028 * \throws kind_error if the kind is not an object.
1029 **/
1034 /// \}
1035
1036 /// \{
1037
1038 /** Get an iterator to the one past the end of this object.
1039 *
1040 * \throws kind_error if the kind is not an object.
1041 **/
1046 /// \}
1047
1048 /// \{
1049
1050 /** View this instance as an object.
1051 *
1052 * \throws kind_error if the kind is not an object.
1053 **/
1057 const_object_view as_object() const &;
1059 owning_object_view as_object() &&;
1060 /// \}
1061
1062 /// \{
1063
1064 /** Get the value associated with the given \a key of this object. If the \a key does not exist, it will be created.
1065 * Creating it invalidates iterators and references as \ref insert does.
1066 *
1067 * \throws kind_error if the kind is not an object.
1068 **/
1069 value& operator[](const std::string& key);
1070 value& operator[](std::string&& key);
1071 value& operator[](const std::wstring& key);
1072 /// \}
1073
1074 /// \{
1075
1076 /** Get the value associated with the given \a key of this object.
1077 *
1078 * \throws kind_error if the kind is not an object.
1079 * \throws std::out_of_range if the \a key is not in this object.
1080 **/
1081 value& at(const std::string& key);
1082 value& at(const std::wstring& key);
1084 const value& at(const std::string& key) const;
1086 const value& at(const std::wstring& key) const;
1087 /// \}
1088
1089 /// \{
1090
1091 /** Check if the given \a key exists in this object.
1092 *
1093 * \throws kind_error if the kind is not an object.
1094 **/
1096 size_type count(const std::string& key) const;
1098 size_type count(const std::wstring& key) const;
1099 /// \}
1100
1101 /// \{
1102
1103 /** Attempt to locate a key-value pair with the provided \a key in this object.
1104 *
1105 * \throws kind_error if the kind is not an object.
1106 **/
1108 object_iterator find(const std::string& key);
1110 object_iterator find(const std::wstring& key);
1112 const_object_iterator find(const std::string& key) const;
1114 const_object_iterator find(const std::wstring& key) const;
1115 /// \}
1116
1117 /// \{
1118
1119 /// Insert \a pair into this object, unless an element with an equivalent key is already present.
1120 ///
1121 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1122 /// one of them if the object has to grow.
1123 ///
1124 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
1125 /// whose \c second is \c true if the insertion took place.
1126 /// \throws kind_error if the kind is not an object.
1127 std::pair<object_iterator, bool> insert(std::pair<std::string, value> pair);
1128 std::pair<object_iterator, bool> insert(std::pair<std::wstring, value> pair);
1129 /// \}
1130
1131 /// \{
1132
1133 /// Insert \a pair into this object, unless an element with an equivalent key is already present. If \a hint is
1134 /// where the key goes -- every member before it has a lesser key and \a hint itself a greater one -- the key is not
1135 /// searched for. A \a hint of \ref end_object for a key greater than every one present appends in amortized
1136 /// constant time; any other insertion shifts the members after it. A wrong \a hint costs a binary search.
1137 ///
1138 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1139 /// one of them if the object has to grow.
1140 ///
1141 /// \returns An iterator to the newly-inserted element (or the element which shares the key).
1142 /// \throws kind_error if the kind is not an object.
1143 object_iterator insert(const_object_iterator hint, std::pair<std::string, value> pair);
1144 object_iterator insert(const_object_iterator hint, std::pair<std::wstring, value> pair);
1145 /// \}
1146
1147 /// Insert range defined by [\a first, \a last) into this object. Each element is hinted just past the previous one,
1148 /// so a source in ascending key order needs no searching, and one whose keys all sort after what this object holds
1149 /// is appended in amortized constant time per element. Any element which does not go at the end shifts the
1150 /// members after it.
1151 ///
1152 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1153 /// one of them if the object has to grow.
1154 ///
1155 /// \throws kind_error if the kind is not an object.
1156 template <typename TForwardIterator>
1157 void insert(TForwardIterator first, TForwardIterator last)
1158 {
1159 // Each element is hinted just past the one before it, which is right for any ascending source -- most
1160 // importantly one building a fresh object, where that is the end. Reading end_object() also rejects a
1161 // non-object when the range is empty.
1162 const_object_iterator hint = end_object();
1163 for ( ; first != last; ++first)
1164 hint = insert(hint, *first) + 1;
1165 }
1166
1167 /// Insert the contents of \a handle. If \a handle is empty, this does nothing. If the insertion succeeds, \a handle
1168 /// is moved from and left empty; otherwise it retains ownership of the element.
1169 ///
1170 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1171 /// one of them if the object has to grow.
1172 ///
1173 /// \returns If \a handle is empty, \c inserted is \c false and \c position is `end_object()`. If the insertion took
1174 /// place, \c inserted is \c true and \c position points to the inserted element. If the insertion was attempted
1175 /// but failed, \c inserted is \c false and \c position points to an element with a key equivalent to
1176 /// `handle.key()`.
1177 /// \throws kind_error if the kind is not an object.
1179
1180 /// If \a handle is an empty node handle, does nothing and returns \ref end_object. Otherwise, inserts the element
1181 /// owned by \a handle into the container, if the container doesn't already contain an element with a key equivalent
1182 /// to `handle.key()` and returns the iterator pointing to the element with key equivalent to `handle.key()`. If the
1183 /// insertion succeeds, \a handle is moved from, otherwise it retains ownership of the element. \a hint works as it
1184 /// does for \ref insert of a pair.
1185 ///
1186 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1187 /// one of them if the object has to grow.
1188 ///
1189 /// \returns An iterator pointing to an element with a key equivalent to `handle.key()` if \a handle was not empty.
1190 /// If \a handle was empty, `end_object()`.
1191 /// \throws kind_error if the kind is not an object.
1193
1194 /// \{
1195
1196 /// Insert \a items into this object.
1197 ///
1198 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1199 /// one of them if the object has to grow.
1200 ///
1201 /// \throws kind_error if the kind is not an object.
1202 void insert(std::initializer_list<std::pair<std::string, value>> items);
1203 void insert(std::initializer_list<std::pair<std::wstring, value>> items);
1204 /// \}
1205
1206 /// \{
1207
1208 /// Construct an element from \a key and \a val and insert it into this object. If an element with an equivalent
1209 /// key is already present, the insertion does not happen and the existing element is not overwritten.
1210 ///
1211 /// \note
1212 /// \a key is taken by value, so a call which does not insert has still built and destroyed it. Prefer
1213 /// \ref try_emplace when collisions are expected.
1214 ///
1215 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1216 /// one of them if the object has to grow.
1217 ///
1218 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
1219 /// whose \c second is \c true if the insertion took place.
1220 /// \throws kind_error if the kind is not an object.
1221 ///
1222 /// \see insert
1223 /// \see try_emplace
1224 std::pair<object_iterator, bool> emplace(std::string key, value val);
1225 std::pair<object_iterator, bool> emplace(const std::wstring& key, value val);
1226 /// \}
1227
1228 /// \{
1229
1230 /// Insert \a val with the given \a key into this object, but only if no element with an equivalent key is already
1231 /// present. Unlike \ref emplace, \a key is not copied when the key is already present.
1232 ///
1233 /// \note
1234 /// \a val is taken by value, so a caller who passes `std::move(x)` has moved from \c x by the time this function
1235 /// is entered whether or not the insertion happens. It is the key which is spared, not \a val.
1236 ///
1237 /// Inserting invalidates every iterator and reference to a member at or after the position inserted at, and every
1238 /// one of them if the object has to grow.
1239 ///
1240 /// \returns A pair whose \c first refers to the newly-inserted element (or the element which shares the key) and
1241 /// whose \c second is \c true if the insertion took place.
1242 /// \throws kind_error if the kind is not an object.
1243 ///
1244 /// \see insert
1245 /// \see insert_or_assign
1246 std::pair<object_iterator, bool> try_emplace(const std::string& key, value val);
1247 std::pair<object_iterator, bool> try_emplace(const std::wstring& key, value val);
1248 /// \}
1249
1250 /// \{
1251
1252 /// Insert \a val with the given \a key into this object if no element with an equivalent key is present;
1253 /// otherwise, assign \a val to the existing element. Unlike \ref try_emplace, \a val is stored either way.
1254 ///
1255 /// \returns A pair whose \c first refers to the inserted or assigned element and whose \c second is \c true if an
1256 /// insertion took place and \c false if an assignment took place. Unlike \ref insert, a \c second of \c false
1257 /// does \e not mean the operation failed -- this function always modifies the object.
1258 /// \throws kind_error if the kind is not an object.
1259 ///
1260 /// An insertion invalidates iterators and references as \ref insert does; an assignment invalidates none.
1261 ///
1262 /// \see insert
1263 /// \see try_emplace
1264 std::pair<object_iterator, bool> insert_or_assign(const std::string& key, value val);
1265 std::pair<object_iterator, bool> insert_or_assign(const std::wstring& key, value val);
1266 /// \}
1267
1268 /// \{
1269
1270 /// Erase the item with the given \a key.
1271 ///
1272 /// Erasing invalidates every iterator and reference to a member at or after the position erased from.
1273 ///
1274 /// \returns 1 if \a key was erased; 0 if it did not.
1275 /// \throws kind_error if the kind is not an object.
1276 size_type erase(const std::string& key);
1277 size_type erase(const std::wstring& key);
1278 /// \}
1279
1280 /// Erase the item at the given \a position.
1281 ///
1282 /// Erasing invalidates every iterator and reference to a member at or after the position erased from.
1283 ///
1284 /// \returns An iterator to the member which followed the erased one.
1285 /// \throws kind_error if the kind is not an object.
1287
1288 /// Erase the range defined by [\a first, \a last).
1289 ///
1290 /// Erasing invalidates every iterator and reference to a member at or after the position erased from.
1291 ///
1292 /// \returns An iterator to the member which followed the erased range.
1293 /// \throws kind_error if the kind is not an object.
1295
1296 /// Move the key and value of the member at \a position into a node handle, erase the member, and return the handle.
1297 ///
1298 /// Erasing invalidates every iterator and reference to a member at or after the position erased from.
1299 ///
1300 /// \throws kind_error if the kind is not an object.
1302
1303 /// \{
1304
1305 /// If the container has an element with the given \a key, moves its key and value into a node handle, erases it,
1306 /// and returns the handle. Otherwise, returns an empty node handle.
1307 ///
1308 /// Erasing invalidates every iterator and reference to a member at or after the position erased from.
1309 ///
1310 /// \throws kind_error if the kind is not an object.
1311 object_node_handle extract(const std::string& key);
1312 object_node_handle extract(const std::wstring& key);
1313 /// \}
1314
1315 /** Is the underlying structure empty?
1316 *
1317 * - object: Are there no keys?
1318 * - array: Are there no values?
1319 * - string: Is the string 0 length?
1320 * - null: true (always)
1321 * - all other types: false (always)
1322 *
1323 * \throws nothing
1324 **/
1326 bool empty() const noexcept;
1327
1328 /** Get the number of items in this value.
1329 *
1330 * - object: The number of key/value pairs.
1331 * - array: The number of values.
1332 * - string: The number of code points in the string (including \c \\0 values and counting multi-byte encodings as
1333 * more than one value).
1334 *
1335 * \throws kind_error if the kind is not an object, array or string.
1336 **/
1338 size_type size() const;
1339
1340 /** \addtogroup Algorithm
1341 * \{
1342 **/
1343
1344 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1345 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1346 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1347 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1348 * transformed by \a func.
1349 *
1350 * \param func The function to apply to the element or elements of this instance.
1351 **/
1353 value map(const std::function<value (const value&)>& func) const&;
1354
1355 /** Run a function over the values of this instance. The behavior of this function is different, depending on the
1356 * \c kind. For scalar kinds (\c kind::integer, \c kind::null, etc), \a func is called once with the value. If this
1357 * is \c kind::array, \c func is called for every value in the array and the output will be an array with each
1358 * element transformed by \a func. If this is \c kind::object, the result will be an object with each key
1359 * transformed by \a func.
1360 *
1361 * \param func The function to apply to the element or elements of this instance.
1362 *
1363 * \note
1364 * This version of \c map provides only a basic exception-safety guarantee. If an exception is thrown while
1365 * transforming a non-scalar \c kind, there is no rollback action, so \c this is left in a usable, but
1366 * \e unpredictable state. If you need a strong exception guarantee, use the constant reference version of \c map.
1367 **/
1369 value map(const std::function<value (value)>& func) &&;
1370
1371 /** \} **/
1372
1373private:
1374 friend JSONV_PUBLIC value array();
1375 friend JSONV_PUBLIC value object();
1376 friend struct detail::value_access;
1377
1378private:
1379 detail::value_representation _repr;
1380};
1381
1382/** An instance with \c kind::null. This is intended to be used for convenience and readability (as opposed to using the
1383 * default constructor of \c value.
1384**/
1385JSONV_PUBLIC extern const value null;
1386
1387/** A user-defined literal for parsing JSON. Uses the default (non-strict) \c parse_options.
1388 *
1389 * \code
1390 * R"({
1391 * "taco": "cat",
1392 * "burrito": "dog",
1393 * "whatever": [ "goes", "here", 1, 2, 3, 4 ]
1394 * })"_json;
1395 * \endcode
1396**/
1397JSONV_NODISCARD JSONV_PUBLIC value operator""_json(const char* str, std::size_t len);
1398
1399/** Swap the values \a a and \a b. **/
1400JSONV_PUBLIC void swap(value& a, value& b) noexcept;
1401
1402/** Create an empty array value. **/
1404
1405/** Create an array value from the given source. **/
1406JSONV_NODISCARD JSONV_PUBLIC value array(std::initializer_list<value> source);
1407
1408/** Create an array with contents defined by range [\a first, \a last). **/
1409template <typename TForwardIterator>
1410value array(TForwardIterator first, TForwardIterator last)
1411{
1412 value arr = array();
1413 arr.assign(first, last);
1414 return arr;
1415}
1416
1417/** Create an empty object. **/
1419
1420/** Create an object with key-value pairs from the given \a source. **/
1421JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::string, value>> source);
1422JSONV_NODISCARD JSONV_PUBLIC value object(std::initializer_list<std::pair<std::wstring, value>> source);
1423
1424/** Create an object whose contents are defined by range [\a first, \a last). **/
1425template <typename TForwardIterator>
1426value object(TForwardIterator first, TForwardIterator last)
1427{
1428 value obj = object();
1429 obj.insert(first, last);
1430 return obj;
1431}
1432
1433/// A <a href="http://en.cppreference.com/w/cpp/container/node_handle">node handle</a> used when a value is
1434/// \ref kind::object to access elements of the object in potentially destructive manner. This makes it possible to
1435/// modify the contents of a node extracted from an object, and then re-insert it without having to copy the element.
1437{
1438public:
1439 /// The key type of the object.
1440 using key_type = std::string;
1441
1442 /// The mapped type of the object.
1444
1445public:
1446 explicit object_node_handle() noexcept :
1447 _has_value(false)
1448 { }
1449
1450 /// Take over the element owned by \a src, if any. \a src is left \ref empty.
1452
1453 /// Release the element this handle owns, if any, and take over the one owned by \a src, if any. \a src is left
1454 /// \ref empty. Self-assignment has no effect.
1456
1457 ~object_node_handle() noexcept;
1458
1459 /// \returns \c true if the node handle is empty; \c false if otherwise.
1461 bool empty() const noexcept { return !_has_value; }
1462
1463 /// \returns \c false if the node handle is empty; \c true if otherwise.
1465 explicit operator bool() const noexcept { return _has_value; }
1466
1467 /// Returns a non-const reference to the \ref key_type member of the element.
1468 ///
1469 /// \throws std::invalid_argument if the node handle is \ref empty.
1470 key_type& key() const;
1471
1472 /// Returns a non-const reference to the \ref mapped_type member of the element.
1473 ///
1474 /// \throws std::invalid_argument if the node handle is \ref empty.
1476
1477private:
1478 enum class purposeful_construction
1479 { };
1480
1481 explicit object_node_handle(purposeful_construction, key_type, mapped_type) noexcept;
1482
1483 friend class value;
1484
1485private:
1486 bool _has_value;
1487 mutable key_type _key;
1488 mutable mapped_type _value;
1489};
1490
1491/// \}
1492
1493}
1494
1495namespace std
1496{
1497
1498/// Explicit specialization of \c std::hash for \c jsonv::value types so you can store a \c value in an unordered
1499/// container. Values which compare equal hash equal. Since an integer compares equal to the decimal of the same number,
1500/// both \c kind::integer and \c kind::decimal hash through \c value::as_decimal: \c value(2) and \c value(2.0) share a
1501/// hash, as do distinct integers past 2^53 which convert to the same \c double. All NaNs share a hash. For aggregate
1502/// kinds \c array and \c object, hashing visits every sub-element recursively. This might be expensive, but is required
1503/// when storing multiple values with similar layouts in a set (which is the most common use case).
1504template <>
1505struct JSONV_PUBLIC hash<jsonv::value>
1506{
1508 std::size_t operator()(const jsonv::value& val) const noexcept;
1509};
1510
1511/// A member reference and an owning member have \c jsonv::value::const_object_reference in common: both convert to it.
1512/// This is what makes the object iterators, whose \c reference is a proxy, model \c std::random_access_iterator.
1513template <typename TValue, template <typename> class TQual, template <typename> class UQual>
1514struct basic_common_reference<jsonv::value::basic_object_reference<TValue>,
1516 TQual,
1517 UQual
1518 >
1519{
1521};
1522
1523/// The same, with the arguments the other way around.
1524template <typename TValue, template <typename> class TQual, template <typename> class UQual>
1525struct basic_common_reference<jsonv::value::object_value_type,
1527 TQual,
1528 UQual
1529 >
1530{
1532};
1533
1534}
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:111
A node handle used when a value is kind::object to access elements of the object in potentially destr...
Definition value.hpp:1437
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:1440
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:156
void assign(TForwardIterator first, TForwardIterator last)
Assign the contents of range [first, last) to this array.
Definition value.hpp:986
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.
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.
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:574
basic_object_reference< const value > const_object_reference
Definition value.hpp:404
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:929
int compare(const value &other) const
Used to build a strict-ordering of JSON values.
object_node_handle extract(const_object_iterator position)
Move the key and value of the member at position into a node handle, erase the member,...
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:324
object_node_handle extract(const std::string &key)
If the container has an element with the given key, moves its key and value into a node handle,...
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.
constexpr value()=default
Default-construct this to null.
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...
basic_object_reference< value > object_reference
Definition value.hpp:401
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:968
friend JSONV_PUBLIC value object()
Create an empty object.
void push_back(value &&item)
Push item to the back of this array.
basic_object_iterator< value, std::pair< std::string, value > > object_iterator
The object_iterator is applicable when kind is kind::object.
Definition value.hpp:568
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:318
~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, as an owning pair.
Definition value.hpp:332
size_type erase(const std::wstring &key)
Erase the item with the given key.
const_object_iterator position
The position of the inserted member or the member with the duplicate key.
Definition value.hpp:585
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:927
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:589
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, moves its key and value into a node handle,...
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:583
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:164
What operator-> returns: it holds the reference, so iter->first and iter->second work.
Definition value.hpp:429
const reference * operator->() const noexcept
The member the iterator was at, for the built-in -> to reach into.
Definition value.hpp:434
reference ref
The member the iterator was at.
Definition value.hpp:431
The base iterator type for iterating over object types.
Definition value.hpp:416
std::random_access_iterator_tag iterator_category
What this gives the functions which dispatch on the category.
Definition value.hpp:422
std::random_access_iterator_tag iterator_concept
What this models in C++20 terms: a random-access iterator, whose reference may be a proxy.
Definition value.hpp:419
basic_object_iterator(const basic_object_iterator< UValue, UMember > &source) noexcept
This allows conversion from an object_iterator to a const_object_iterator.
Definition value.hpp:452
What dereferencing an object_iterator (TValue of value) or a const_object_iterator (TValue of const v...
Definition value.hpp:346
basic_object_reference(const basic_object_reference< UValue > &source) noexcept
This allows conversion from an object_reference to a const_object_reference.
Definition value.hpp:382
const std::string first_type
The type of first, as in std::pair, which this stands in for.
Definition value.hpp:349
TValue second_type
The type of second, as in std::pair.
Definition value.hpp:352
const std::string & first
The key of the member.
Definition value.hpp:356
TValue & second
The value of the member.
Definition value.hpp:359
basic_object_reference(const std::string &key, TValue &val) noexcept
Refer to key and val.
Definition value.hpp:363
basic_object_reference(std::conditional_t< std::is_const_v< TValue >, const object_value_type &, object_value_type & > pair) noexcept
Refer to the key and value of pair.
Definition value.hpp:369