1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 2.0.5
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28
29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
31
32 #include <algorithm>
33 #include <array>
34 #include <cassert>
35 #include <ciso646>
36 #include <cmath>
37 #include <cstddef>
38 #include <cstdint>
39 #include <cstdlib>
40 #include <cstring>
41 #include <functional>
42 #include <initializer_list>
43 #include <iomanip>
44 #include <iostream>
45 #include <iterator>
46 #include <limits>
47 #include <locale>
48 #include <map>
49 #include <memory>
50 #include <numeric>
51 #include <sstream>
52 #include <stdexcept>
53 #include <string>
54 #include <type_traits>
55 #include <utility>
56 #include <vector>
57
58 // exclude unsupported compilers
59 #if defined(__clang__)
60 #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
61 #if CLANG_VERSION < 30400
62 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
63 #endif
64 #elif defined(__GNUC__)
65 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
66 #if GCC_VERSION < 40900
67 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
68 #endif
69 #endif
70
71 // disable float-equal warnings on GCC/clang
72 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
73 #pragma GCC diagnostic push
74 #pragma GCC diagnostic ignored "-Wfloat-equal"
75 #endif
76
77 // allow for portable deprecation warnings
78 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
79 #define JSON_DEPRECATED __attribute__((deprecated))
80 #elif defined(_MSC_VER)
81 #define JSON_DEPRECATED __declspec(deprecated)
82 #else
83 #define JSON_DEPRECATED
84 #endif
85
86 /*!
87 @brief namespace for Niels Lohmann
88 @see https://github.com/nlohmann
89 @since version 1.0.0
90 */
91 namespace nlohmann
92 {
93
94
95 /*!
96 @brief unnamed namespace with internal helper functions
97 @since version 1.0.0
98 */
99 namespace
100 {
101 /*!
102 @brief Helper to determine whether there's a key_type for T.
103
104 Thus helper is used to tell associative containers apart from other containers
105 such as sequence containers. For instance, `std::map` passes the test as it
106 contains a `mapped_type`, whereas `std::vector` fails the test.
107
108 @sa http://stackoverflow.com/a/7728728/266378
109 @since version 1.0.0
110 */
111 template<typename T>
112 struct has_mapped_type
113 {
114 private:
115 template<typename C> static char test(typename C::mapped_type*);
116 template<typename C> static char (&test(...))[2];
117 public:
118 static constexpr bool value = sizeof(test<T>(0)) == 1;
119 };
120
121 /*!
122 @brief helper class to create locales with decimal point
123
124 This struct is used a default locale during the JSON serialization. JSON
125 requires the decimal point to be `.`, so this function overloads the
126 `do_decimal_point()` function to return `.`. This function is called by
127 float-to-string conversions to retrieve the decimal separator between integer
128 and fractional parts.
129
130 @sa https://github.com/nlohmann/json/issues/51#issuecomment-86869315
131 @since version 2.0.0
132 */
133 struct DecimalSeparator : std::numpunct<char>
134 {
do_decimal_pointnlohmann::__anon197e37760111::DecimalSeparator135 char do_decimal_point() const
136 {
137 return '.';
138 }
139 };
140
141 }
142
143 /*!
144 @brief a class to store JSON values
145
146 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
147 in @ref object_t)
148 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
149 in @ref array_t)
150 @tparam StringType type for JSON strings and object keys (`std::string` by
151 default; will be used in @ref string_t)
152 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
153 in @ref boolean_t)
154 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
155 default; will be used in @ref number_integer_t)
156 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
157 `uint64_t` by default; will be used in @ref number_unsigned_t)
158 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
159 default; will be used in @ref number_float_t)
160 @tparam AllocatorType type of the allocator to use (`std::allocator` by
161 default)
162
163 @requirement The class satisfies the following concept requirements:
164 - Basic
165 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
166 JSON values can be default constructed. The result will be a JSON null value.
167 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
168 A JSON value can be constructed from an rvalue argument.
169 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
170 A JSON value can be copy-constructed from an lvalue expression.
171 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
172 A JSON value van be assigned from an rvalue argument.
173 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
174 A JSON value can be copy-assigned from an lvalue expression.
175 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
176 JSON values can be destructed.
177 - Layout
178 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
179 JSON values have
180 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
181 All non-static data members are private and standard layout types, the class
182 has no virtual functions or (virtual) base classes.
183 - Library-wide
184 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
185 JSON values can be compared with `==`, see @ref
186 operator==(const_reference,const_reference).
187 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
188 JSON values can be compared with `<`, see @ref
189 operator<(const_reference,const_reference).
190 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
191 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
192 other compatible types, using unqualified function call @ref swap().
193 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
194 JSON values can be compared against `std::nullptr_t` objects which are used
195 to model the `null` value.
196 - Container
197 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
198 JSON values can be used like STL containers and provide iterator access.
199 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
200 JSON values can be used like STL containers and provide reverse iterator
201 access.
202
203 @invariant The member variables @a m_value and @a m_type have the following
204 relationship:
205 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
206 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
207 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
208 The invariants are checked by member function assert_invariant().
209
210 @internal
211 @note ObjectType trick from http://stackoverflow.com/a/9860911
212 @endinternal
213
214 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
215 Format](http://rfc7159.net/rfc7159)
216
217 @since version 1.0.0
218
219 @nosubgrouping
220 */
221 template <
222 template<typename U, typename V, typename... Args> class ObjectType = std::map,
223 template<typename U, typename... Args> class ArrayType = std::vector,
224 class StringType = std::string,
225 class BooleanType = bool,
226 class NumberIntegerType = std::int64_t,
227 class NumberUnsignedType = std::uint64_t,
228 class NumberFloatType = double,
229 template<typename U> class AllocatorType = std::allocator
230 >
231 class basic_json
232 {
233 private:
234 /// workaround type for MSVC
235 using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
236 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
237 AllocatorType>;
238
239 public:
240 // forward declarations
241 template<typename Base> class json_reverse_iterator;
242 class json_pointer;
243
244 /////////////////////
245 // container types //
246 /////////////////////
247
248 /// @name container types
249 /// The canonic container types to use @ref basic_json like any other STL
250 /// container.
251 /// @{
252
253 /// the type of elements in a basic_json container
254 using value_type = basic_json;
255
256 /// the type of an element reference
257 using reference = value_type&;
258 /// the type of an element const reference
259 using const_reference = const value_type&;
260
261 /// a type to represent differences between iterators
262 using difference_type = std::ptrdiff_t;
263 /// a type to represent container sizes
264 using size_type = std::size_t;
265
266 /// the allocator type
267 using allocator_type = AllocatorType<basic_json>;
268
269 /// the type of an element pointer
270 using pointer = typename std::allocator_traits<allocator_type>::pointer;
271 /// the type of an element const pointer
272 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
273
274 /// an iterator for a basic_json container
275 class iterator;
276 /// a const iterator for a basic_json container
277 class const_iterator;
278 /// a reverse iterator for a basic_json container
279 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
280 /// a const reverse iterator for a basic_json container
281 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
282
283 /// @}
284
285
286 /*!
287 @brief returns the allocator associated with the container
288 */
get_allocator()289 static allocator_type get_allocator()
290 {
291 return allocator_type();
292 }
293
294
295 ///////////////////////////
296 // JSON value data types //
297 ///////////////////////////
298
299 /// @name JSON value data types
300 /// The data types to store a JSON value. These types are derived from
301 /// the template arguments passed to class @ref basic_json.
302 /// @{
303
304 /*!
305 @brief a type for an object
306
307 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
308 > An object is an unordered collection of zero or more name/value pairs,
309 > where a name is a string and a value is a string, number, boolean, null,
310 > object, or array.
311
312 To store objects in C++, a type is defined by the template parameters
313 described below.
314
315 @tparam ObjectType the container to store objects (e.g., `std::map` or
316 `std::unordered_map`)
317 @tparam StringType the type of the keys or names (e.g., `std::string`).
318 The comparison function `std::less<StringType>` is used to order elements
319 inside the container.
320 @tparam AllocatorType the allocator to use for objects (e.g.,
321 `std::allocator`)
322
323 #### Default type
324
325 With the default values for @a ObjectType (`std::map`), @a StringType
326 (`std::string`), and @a AllocatorType (`std::allocator`), the default
327 value for @a object_t is:
328
329 @code {.cpp}
330 std::map<
331 std::string, // key_type
332 basic_json, // value_type
333 std::less<std::string>, // key_compare
334 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
335 >
336 @endcode
337
338 #### Behavior
339
340 The choice of @a object_t influences the behavior of the JSON class. With
341 the default type, objects have the following behavior:
342
343 - When all names are unique, objects will be interoperable in the sense
344 that all software implementations receiving that object will agree on
345 the name-value mappings.
346 - When the names within an object are not unique, later stored name/value
347 pairs overwrite previously stored name/value pairs, leaving the used
348 names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
349 be treated as equal and both stored as `{"key": 1}`.
350 - Internally, name/value pairs are stored in lexicographical order of the
351 names. Objects will also be serialized (see @ref dump) in this order.
352 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
353 and serialized as `{"a": 2, "b": 1}`.
354 - When comparing objects, the order of the name/value pairs is irrelevant.
355 This makes objects interoperable in the sense that they will not be
356 affected by these differences. For instance, `{"b": 1, "a": 2}` and
357 `{"a": 2, "b": 1}` will be treated as equal.
358
359 #### Limits
360
361 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
362 > An implementation may set limits on the maximum depth of nesting.
363
364 In this class, the object's limit of nesting is not constraint explicitly.
365 However, a maximum depth of nesting may be introduced by the compiler or
366 runtime environment. A theoretical limit can be queried by calling the
367 @ref max_size function of a JSON object.
368
369 #### Storage
370
371 Objects are stored as pointers in a @ref basic_json type. That is, for any
372 access to object values, a pointer of type `object_t*` must be
373 dereferenced.
374
375 @sa @ref array_t -- type for an array value
376
377 @since version 1.0.0
378
379 @note The order name/value pairs are added to the object is *not*
380 preserved by the library. Therefore, iterating an object may return
381 name/value pairs in a different order than they were originally stored. In
382 fact, keys will be traversed in alphabetical order as `std::map` with
383 `std::less` is used by default. Please note this behavior conforms to [RFC
384 7159](http://rfc7159.net/rfc7159), because any order implements the
385 specified "unordered" nature of JSON objects.
386 */
387 using object_t = ObjectType<StringType,
388 basic_json,
389 std::less<StringType>,
390 AllocatorType<std::pair<const StringType,
391 basic_json>>>;
392
393 /*!
394 @brief a type for an array
395
396 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
397 > An array is an ordered sequence of zero or more values.
398
399 To store objects in C++, a type is defined by the template parameters
400 explained below.
401
402 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
403 `std::list`)
404 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
405
406 #### Default type
407
408 With the default values for @a ArrayType (`std::vector`) and @a
409 AllocatorType (`std::allocator`), the default value for @a array_t is:
410
411 @code {.cpp}
412 std::vector<
413 basic_json, // value_type
414 std::allocator<basic_json> // allocator_type
415 >
416 @endcode
417
418 #### Limits
419
420 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
421 > An implementation may set limits on the maximum depth of nesting.
422
423 In this class, the array's limit of nesting is not constraint explicitly.
424 However, a maximum depth of nesting may be introduced by the compiler or
425 runtime environment. A theoretical limit can be queried by calling the
426 @ref max_size function of a JSON array.
427
428 #### Storage
429
430 Arrays are stored as pointers in a @ref basic_json type. That is, for any
431 access to array values, a pointer of type `array_t*` must be dereferenced.
432
433 @sa @ref object_t -- type for an object value
434
435 @since version 1.0.0
436 */
437 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
438
439 /*!
440 @brief a type for a string
441
442 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
443 > A string is a sequence of zero or more Unicode characters.
444
445 To store objects in C++, a type is defined by the template parameter
446 described below. Unicode values are split by the JSON class into
447 byte-sized characters during deserialization.
448
449 @tparam StringType the container to store strings (e.g., `std::string`).
450 Note this container is used for keys/names in objects, see @ref object_t.
451
452 #### Default type
453
454 With the default values for @a StringType (`std::string`), the default
455 value for @a string_t is:
456
457 @code {.cpp}
458 std::string
459 @endcode
460
461 #### String comparison
462
463 [RFC 7159](http://rfc7159.net/rfc7159) states:
464 > Software implementations are typically required to test names of object
465 > members for equality. Implementations that transform the textual
466 > representation into sequences of Unicode code units and then perform the
467 > comparison numerically, code unit by code unit, are interoperable in the
468 > sense that implementations will agree in all cases on equality or
469 > inequality of two strings. For example, implementations that compare
470 > strings with escaped characters unconverted may incorrectly find that
471 > `"a\\b"` and `"a\u005Cb"` are not equal.
472
473 This implementation is interoperable as it does compare strings code unit
474 by code unit.
475
476 #### Storage
477
478 String values are stored as pointers in a @ref basic_json type. That is,
479 for any access to string values, a pointer of type `string_t*` must be
480 dereferenced.
481
482 @since version 1.0.0
483 */
484 using string_t = StringType;
485
486 /*!
487 @brief a type for a boolean
488
489 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
490 type which differentiates the two literals `true` and `false`.
491
492 To store objects in C++, a type is defined by the template parameter @a
493 BooleanType which chooses the type to use.
494
495 #### Default type
496
497 With the default values for @a BooleanType (`bool`), the default value for
498 @a boolean_t is:
499
500 @code {.cpp}
501 bool
502 @endcode
503
504 #### Storage
505
506 Boolean values are stored directly inside a @ref basic_json type.
507
508 @since version 1.0.0
509 */
510 using boolean_t = BooleanType;
511
512 /*!
513 @brief a type for a number (integer)
514
515 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
516 > The representation of numbers is similar to that used in most
517 > programming languages. A number is represented in base 10 using decimal
518 > digits. It contains an integer component that may be prefixed with an
519 > optional minus sign, which may be followed by a fraction part and/or an
520 > exponent part. Leading zeros are not allowed. (...) Numeric values that
521 > cannot be represented in the grammar below (such as Infinity and NaN)
522 > are not permitted.
523
524 This description includes both integer and floating-point numbers.
525 However, C++ allows more precise storage if it is known whether the number
526 is a signed integer, an unsigned integer or a floating-point number.
527 Therefore, three different types, @ref number_integer_t, @ref
528 number_unsigned_t and @ref number_float_t are used.
529
530 To store integer numbers in C++, a type is defined by the template
531 parameter @a NumberIntegerType which chooses the type to use.
532
533 #### Default type
534
535 With the default values for @a NumberIntegerType (`int64_t`), the default
536 value for @a number_integer_t is:
537
538 @code {.cpp}
539 int64_t
540 @endcode
541
542 #### Default behavior
543
544 - The restrictions about leading zeros is not enforced in C++. Instead,
545 leading zeros in integer literals lead to an interpretation as octal
546 number. Internally, the value will be stored as decimal number. For
547 instance, the C++ integer literal `010` will be serialized to `8`.
548 During deserialization, leading zeros yield an error.
549 - Not-a-number (NaN) values will be serialized to `null`.
550
551 #### Limits
552
553 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
554 > An implementation may set limits on the range and precision of numbers.
555
556 When the default type is used, the maximal integer number that can be
557 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
558 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
559 that are out of range will yield over/underflow when used in a
560 constructor. During deserialization, too large or small integer numbers
561 will be automatically be stored as @ref number_unsigned_t or @ref
562 number_float_t.
563
564 [RFC 7159](http://rfc7159.net/rfc7159) further states:
565 > Note that when such software is used, numbers that are integers and are
566 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
567 > that implementations will agree exactly on their numeric values.
568
569 As this range is a subrange of the exactly supported range [INT64_MIN,
570 INT64_MAX], this class's integer type is interoperable.
571
572 #### Storage
573
574 Integer number values are stored directly inside a @ref basic_json type.
575
576 @sa @ref number_float_t -- type for number values (floating-point)
577
578 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
579
580 @since version 1.0.0
581 */
582 using number_integer_t = NumberIntegerType;
583
584 /*!
585 @brief a type for a number (unsigned)
586
587 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
588 > The representation of numbers is similar to that used in most
589 > programming languages. A number is represented in base 10 using decimal
590 > digits. It contains an integer component that may be prefixed with an
591 > optional minus sign, which may be followed by a fraction part and/or an
592 > exponent part. Leading zeros are not allowed. (...) Numeric values that
593 > cannot be represented in the grammar below (such as Infinity and NaN)
594 > are not permitted.
595
596 This description includes both integer and floating-point numbers.
597 However, C++ allows more precise storage if it is known whether the number
598 is a signed integer, an unsigned integer or a floating-point number.
599 Therefore, three different types, @ref number_integer_t, @ref
600 number_unsigned_t and @ref number_float_t are used.
601
602 To store unsigned integer numbers in C++, a type is defined by the
603 template parameter @a NumberUnsignedType which chooses the type to use.
604
605 #### Default type
606
607 With the default values for @a NumberUnsignedType (`uint64_t`), the
608 default value for @a number_unsigned_t is:
609
610 @code {.cpp}
611 uint64_t
612 @endcode
613
614 #### Default behavior
615
616 - The restrictions about leading zeros is not enforced in C++. Instead,
617 leading zeros in integer literals lead to an interpretation as octal
618 number. Internally, the value will be stored as decimal number. For
619 instance, the C++ integer literal `010` will be serialized to `8`.
620 During deserialization, leading zeros yield an error.
621 - Not-a-number (NaN) values will be serialized to `null`.
622
623 #### Limits
624
625 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
626 > An implementation may set limits on the range and precision of numbers.
627
628 When the default type is used, the maximal integer number that can be
629 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
630 number that can be stored is `0`. Integer numbers that are out of range
631 will yield over/underflow when used in a constructor. During
632 deserialization, too large or small integer numbers will be automatically
633 be stored as @ref number_integer_t or @ref number_float_t.
634
635 [RFC 7159](http://rfc7159.net/rfc7159) further states:
636 > Note that when such software is used, numbers that are integers and are
637 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
638 > that implementations will agree exactly on their numeric values.
639
640 As this range is a subrange (when considered in conjunction with the
641 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
642 this class's integer type is interoperable.
643
644 #### Storage
645
646 Integer number values are stored directly inside a @ref basic_json type.
647
648 @sa @ref number_float_t -- type for number values (floating-point)
649 @sa @ref number_integer_t -- type for number values (integer)
650
651 @since version 2.0.0
652 */
653 using number_unsigned_t = NumberUnsignedType;
654
655 /*!
656 @brief a type for a number (floating-point)
657
658 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
659 > The representation of numbers is similar to that used in most
660 > programming languages. A number is represented in base 10 using decimal
661 > digits. It contains an integer component that may be prefixed with an
662 > optional minus sign, which may be followed by a fraction part and/or an
663 > exponent part. Leading zeros are not allowed. (...) Numeric values that
664 > cannot be represented in the grammar below (such as Infinity and NaN)
665 > are not permitted.
666
667 This description includes both integer and floating-point numbers.
668 However, C++ allows more precise storage if it is known whether the number
669 is a signed integer, an unsigned integer or a floating-point number.
670 Therefore, three different types, @ref number_integer_t, @ref
671 number_unsigned_t and @ref number_float_t are used.
672
673 To store floating-point numbers in C++, a type is defined by the template
674 parameter @a NumberFloatType which chooses the type to use.
675
676 #### Default type
677
678 With the default values for @a NumberFloatType (`double`), the default
679 value for @a number_float_t is:
680
681 @code {.cpp}
682 double
683 @endcode
684
685 #### Default behavior
686
687 - The restrictions about leading zeros is not enforced in C++. Instead,
688 leading zeros in floating-point literals will be ignored. Internally,
689 the value will be stored as decimal number. For instance, the C++
690 floating-point literal `01.2` will be serialized to `1.2`. During
691 deserialization, leading zeros yield an error.
692 - Not-a-number (NaN) values will be serialized to `null`.
693
694 #### Limits
695
696 [RFC 7159](http://rfc7159.net/rfc7159) states:
697 > This specification allows implementations to set limits on the range and
698 > precision of numbers accepted. Since software that implements IEEE
699 > 754-2008 binary64 (double precision) numbers is generally available and
700 > widely used, good interoperability can be achieved by implementations
701 > that expect no more precision or range than these provide, in the sense
702 > that implementations will approximate JSON numbers within the expected
703 > precision.
704
705 This implementation does exactly follow this approach, as it uses double
706 precision floating-point numbers. Note values smaller than
707 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
708 will be stored as NaN internally and be serialized to `null`.
709
710 #### Storage
711
712 Floating-point number values are stored directly inside a @ref basic_json
713 type.
714
715 @sa @ref number_integer_t -- type for number values (integer)
716
717 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
718
719 @since version 1.0.0
720 */
721 using number_float_t = NumberFloatType;
722
723 /// @}
724
725
726 ///////////////////////////
727 // JSON type enumeration //
728 ///////////////////////////
729
730 /*!
731 @brief the JSON type enumeration
732
733 This enumeration collects the different JSON types. It is internally used
734 to distinguish the stored values, and the functions @ref is_null(), @ref
735 is_object(), @ref is_array(), @ref is_string(), @ref is_boolean(), @ref
736 is_number() (with @ref is_number_integer(), @ref is_number_unsigned(), and
737 @ref is_number_float()), @ref is_discarded(), @ref is_primitive(), and
738 @ref is_structured() rely on it.
739
740 @note There are three enumeration entries (number_integer,
741 number_unsigned, and number_float), because the library distinguishes
742 these three types for numbers: @ref number_unsigned_t is used for unsigned
743 integers, @ref number_integer_t is used for signed integers, and @ref
744 number_float_t is used for floating-point numbers or to approximate
745 integers which do not fit in the limits of their respective type.
746
747 @sa @ref basic_json(const value_t value_type) -- create a JSON value with
748 the default value for a given type
749
750 @since version 1.0.0
751 */
752 enum class value_t : uint8_t
753 {
754 null, ///< null value
755 object, ///< object (unordered set of name/value pairs)
756 array, ///< array (ordered collection of values)
757 string, ///< string value
758 boolean, ///< boolean value
759 number_integer, ///< number value (signed integer)
760 number_unsigned, ///< number value (unsigned integer)
761 number_float, ///< number value (floating-point)
762 discarded ///< discarded by the the parser callback function
763 };
764
765
766 private:
767
768 /// helper for exception-safe object creation
769 template<typename T, typename... Args>
create(Args &&...args)770 static T* create(Args&& ... args)
771 {
772 AllocatorType<T> alloc;
773 auto deleter = [&](T * object)
774 {
775 alloc.deallocate(object, 1);
776 };
777 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
778 alloc.construct(object.get(), std::forward<Args>(args)...);
779 assert(object.get() != nullptr);
780 return object.release();
781 }
782
783 ////////////////////////
784 // JSON value storage //
785 ////////////////////////
786
787 /*!
788 @brief a JSON value
789
790 The actual storage for a JSON value of the @ref basic_json class. This
791 union combines the different storage types for the JSON value types
792 defined in @ref value_t.
793
794 JSON type | value_t type | used type
795 --------- | --------------- | ------------------------
796 object | object | pointer to @ref object_t
797 array | array | pointer to @ref array_t
798 string | string | pointer to @ref string_t
799 boolean | boolean | @ref boolean_t
800 number | number_integer | @ref number_integer_t
801 number | number_unsigned | @ref number_unsigned_t
802 number | number_float | @ref number_float_t
803 null | null | *no value is stored*
804
805 @note Variable-length types (objects, arrays, and strings) are stored as
806 pointers. The size of the union should not exceed 64 bits if the default
807 value types are used.
808
809 @since version 1.0.0
810 */
811 union json_value
812 {
813 /// object (stored with pointer to save storage)
814 object_t* object;
815 /// array (stored with pointer to save storage)
816 array_t* array;
817 /// string (stored with pointer to save storage)
818 string_t* string;
819 /// boolean
820 boolean_t boolean;
821 /// number (integer)
822 number_integer_t number_integer;
823 /// number (unsigned integer)
824 number_unsigned_t number_unsigned;
825 /// number (floating-point)
826 number_float_t number_float;
827
828 /// default constructor (for null values)
829 json_value() = default;
830 /// constructor for booleans
json_value(boolean_t v)831 json_value(boolean_t v) noexcept : boolean(v) {}
832 /// constructor for numbers (integer)
json_value(number_integer_t v)833 json_value(number_integer_t v) noexcept : number_integer(v) {}
834 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)835 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
836 /// constructor for numbers (floating-point)
json_value(number_float_t v)837 json_value(number_float_t v) noexcept : number_float(v) {}
838 /// constructor for empty values of a given type
json_value(value_t t)839 json_value(value_t t)
840 {
841 switch (t)
842 {
843 case value_t::object:
844 {
845 object = create<object_t>();
846 break;
847 }
848
849 case value_t::array:
850 {
851 array = create<array_t>();
852 break;
853 }
854
855 case value_t::string:
856 {
857 string = create<string_t>("");
858 break;
859 }
860
861 case value_t::boolean:
862 {
863 boolean = boolean_t(false);
864 break;
865 }
866
867 case value_t::number_integer:
868 {
869 number_integer = number_integer_t(0);
870 break;
871 }
872
873 case value_t::number_unsigned:
874 {
875 number_unsigned = number_unsigned_t(0);
876 break;
877 }
878
879 case value_t::number_float:
880 {
881 number_float = number_float_t(0.0);
882 break;
883 }
884
885 default:
886 {
887 break;
888 }
889 }
890 }
891
892 /// constructor for strings
json_value(const string_t & value)893 json_value(const string_t& value)
894 {
895 string = create<string_t>(value);
896 }
897
898 /// constructor for objects
json_value(const object_t & value)899 json_value(const object_t& value)
900 {
901 object = create<object_t>(value);
902 }
903
904 /// constructor for arrays
json_value(const array_t & value)905 json_value(const array_t& value)
906 {
907 array = create<array_t>(value);
908 }
909 };
910
911 /*!
912 @brief checks the class invariants
913
914 This function asserts the class invariants. It needs to be called at the
915 end of every constructor to make sure that created objects respect the
916 invariant. Furthermore, it has to be called each time the type of a JSON
917 value is changed, because the invariant expresses a relationship between
918 @a m_type and @a m_value.
919 */
assert_invariant() const920 void assert_invariant() const
921 {
922 assert(m_type != value_t::object or m_value.object != nullptr);
923 assert(m_type != value_t::array or m_value.array != nullptr);
924 assert(m_type != value_t::string or m_value.string != nullptr);
925 }
926
927 public:
928 //////////////////////////
929 // JSON parser callback //
930 //////////////////////////
931
932 /*!
933 @brief JSON callback events
934
935 This enumeration lists the parser events that can trigger calling a
936 callback function of type @ref parser_callback_t during parsing.
937
938 @image html callback_events.png "Example when certain parse events are triggered"
939
940 @since version 1.0.0
941 */
942 enum class parse_event_t : uint8_t
943 {
944 /// the parser read `{` and started to process a JSON object
945 object_start,
946 /// the parser read `}` and finished processing a JSON object
947 object_end,
948 /// the parser read `[` and started to process a JSON array
949 array_start,
950 /// the parser read `]` and finished processing a JSON array
951 array_end,
952 /// the parser read a key of a value in an object
953 key,
954 /// the parser finished reading a JSON value
955 value
956 };
957
958 /*!
959 @brief per-element parser callback type
960
961 With a parser callback function, the result of parsing a JSON text can be
962 influenced. When passed to @ref parse(std::istream&, const
963 parser_callback_t) or @ref parse(const char*, const parser_callback_t),
964 it is called on certain events (passed as @ref parse_event_t via parameter
965 @a event) with a set recursion depth @a depth and context JSON value
966 @a parsed. The return value of the callback function is a boolean
967 indicating whether the element that emitted the callback shall be kept or
968 not.
969
970 We distinguish six scenarios (determined by the event type) in which the
971 callback function can be called. The following table describes the values
972 of the parameters @a depth, @a event, and @a parsed.
973
974 parameter @a event | description | parameter @a depth | parameter @a parsed
975 ------------------ | ----------- | ------------------ | -------------------
976 parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
977 parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
978 parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
979 parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
980 parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
981 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
982
983 @image html callback_events.png "Example when certain parse events are triggered"
984
985 Discarding a value (i.e., returning `false`) has different effects
986 depending on the context in which function was called:
987
988 - Discarded values in structured types are skipped. That is, the parser
989 will behave as if the discarded value was never read.
990 - In case a value outside a structured type is skipped, it is replaced
991 with `null`. This case happens if the top-level element is skipped.
992
993 @param[in] depth the depth of the recursion during parsing
994
995 @param[in] event an event of type parse_event_t indicating the context in
996 the callback function has been called
997
998 @param[in,out] parsed the current intermediate parse result; note that
999 writing to this value has no effect for parse_event_t::key events
1000
1001 @return Whether the JSON value which called the function during parsing
1002 should be kept (`true`) or not (`false`). In the latter case, it is either
1003 skipped completely or replaced by an empty discarded object.
1004
1005 @sa @ref parse(std::istream&, parser_callback_t) or
1006 @ref parse(const char*, parser_callback_t) for examples
1007
1008 @since version 1.0.0
1009 */
1010 using parser_callback_t = std::function<bool(int depth,
1011 parse_event_t event,
1012 basic_json& parsed)>;
1013
1014
1015 //////////////////
1016 // constructors //
1017 //////////////////
1018
1019 /// @name constructors and destructors
1020 /// Constructors of class @ref basic_json, copy/move constructor, copy
1021 /// assignment, static functions creating objects, and the destructor.
1022 /// @{
1023
1024 /*!
1025 @brief create an empty value with a given type
1026
1027 Create an empty JSON value with a given type. The value will be default
1028 initialized with an empty value which depends on the type:
1029
1030 Value type | initial value
1031 ----------- | -------------
1032 null | `null`
1033 boolean | `false`
1034 string | `""`
1035 number | `0`
1036 object | `{}`
1037 array | `[]`
1038
1039 @param[in] value_type the type of the value to create
1040
1041 @complexity Constant.
1042
1043 @throw std::bad_alloc if allocation for object, array, or string value
1044 fails
1045
1046 @liveexample{The following code shows the constructor for different @ref
1047 value_t values,basic_json__value_t}
1048
1049 @sa @ref basic_json(std::nullptr_t) -- create a `null` value
1050 @sa @ref basic_json(boolean_t value) -- create a boolean value
1051 @sa @ref basic_json(const string_t&) -- create a string value
1052 @sa @ref basic_json(const object_t&) -- create a object value
1053 @sa @ref basic_json(const array_t&) -- create a array value
1054 @sa @ref basic_json(const number_float_t) -- create a number
1055 (floating-point) value
1056 @sa @ref basic_json(const number_integer_t) -- create a number (integer)
1057 value
1058 @sa @ref basic_json(const number_unsigned_t) -- create a number (unsigned)
1059 value
1060
1061 @since version 1.0.0
1062 */
basic_json(const value_t value_type)1063 basic_json(const value_t value_type)
1064 : m_type(value_type), m_value(value_type)
1065 {
1066 assert_invariant();
1067 }
1068
1069 /*!
1070 @brief create a null object
1071
1072 Create a `null` JSON value. It either takes a null pointer as parameter
1073 (explicitly creating `null`) or no parameter (implicitly creating `null`).
1074 The passed null pointer itself is not read -- it is only used to choose
1075 the right constructor.
1076
1077 @complexity Constant.
1078
1079 @exceptionsafety No-throw guarantee: this constructor never throws
1080 exceptions.
1081
1082 @liveexample{The following code shows the constructor with and without a
1083 null pointer parameter.,basic_json__nullptr_t}
1084
1085 @since version 1.0.0
1086 */
basic_json(std::nullptr_t=nullptr)1087 basic_json(std::nullptr_t = nullptr) noexcept
1088 : basic_json(value_t::null)
1089 {
1090 assert_invariant();
1091 }
1092
1093 /*!
1094 @brief create an object (explicit)
1095
1096 Create an object JSON value with a given content.
1097
1098 @param[in] val a value for the object
1099
1100 @complexity Linear in the size of the passed @a val.
1101
1102 @throw std::bad_alloc if allocation for object value fails
1103
1104 @liveexample{The following code shows the constructor with an @ref
1105 object_t parameter.,basic_json__object_t}
1106
1107 @sa @ref basic_json(const CompatibleObjectType&) -- create an object value
1108 from a compatible STL container
1109
1110 @since version 1.0.0
1111 */
basic_json(const object_t & val)1112 basic_json(const object_t& val)
1113 : m_type(value_t::object), m_value(val)
1114 {
1115 assert_invariant();
1116 }
1117
1118 /*!
1119 @brief create an object (implicit)
1120
1121 Create an object JSON value with a given content. This constructor allows
1122 any type @a CompatibleObjectType that can be used to construct values of
1123 type @ref object_t.
1124
1125 @tparam CompatibleObjectType An object type whose `key_type` and
1126 `value_type` is compatible to @ref object_t. Examples include `std::map`,
1127 `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with
1128 a `key_type` of `std::string`, and a `value_type` from which a @ref
1129 basic_json value can be constructed.
1130
1131 @param[in] val a value for the object
1132
1133 @complexity Linear in the size of the passed @a val.
1134
1135 @throw std::bad_alloc if allocation for object value fails
1136
1137 @liveexample{The following code shows the constructor with several
1138 compatible object type parameters.,basic_json__CompatibleObjectType}
1139
1140 @sa @ref basic_json(const object_t&) -- create an object value
1141
1142 @since version 1.0.0
1143 */
1144 template<class CompatibleObjectType, typename std::enable_if<
1145 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1146 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type = 0>
basic_json(const CompatibleObjectType & val)1147 basic_json(const CompatibleObjectType& val)
1148 : m_type(value_t::object)
1149 {
1150 using std::begin;
1151 using std::end;
1152 m_value.object = create<object_t>(begin(val), end(val));
1153 assert_invariant();
1154 }
1155
1156 /*!
1157 @brief create an array (explicit)
1158
1159 Create an array JSON value with a given content.
1160
1161 @param[in] val a value for the array
1162
1163 @complexity Linear in the size of the passed @a val.
1164
1165 @throw std::bad_alloc if allocation for array value fails
1166
1167 @liveexample{The following code shows the constructor with an @ref array_t
1168 parameter.,basic_json__array_t}
1169
1170 @sa @ref basic_json(const CompatibleArrayType&) -- create an array value
1171 from a compatible STL containers
1172
1173 @since version 1.0.0
1174 */
basic_json(const array_t & val)1175 basic_json(const array_t& val)
1176 : m_type(value_t::array), m_value(val)
1177 {
1178 assert_invariant();
1179 }
1180
1181 /*!
1182 @brief create an array (implicit)
1183
1184 Create an array JSON value with a given content. This constructor allows
1185 any type @a CompatibleArrayType that can be used to construct values of
1186 type @ref array_t.
1187
1188 @tparam CompatibleArrayType An object type whose `value_type` is
1189 compatible to @ref array_t. Examples include `std::vector`, `std::deque`,
1190 `std::list`, `std::forward_list`, `std::array`, `std::set`,
1191 `std::unordered_set`, `std::multiset`, and `unordered_multiset` with a
1192 `value_type` from which a @ref basic_json value can be constructed.
1193
1194 @param[in] val a value for the array
1195
1196 @complexity Linear in the size of the passed @a val.
1197
1198 @throw std::bad_alloc if allocation for array value fails
1199
1200 @liveexample{The following code shows the constructor with several
1201 compatible array type parameters.,basic_json__CompatibleArrayType}
1202
1203 @sa @ref basic_json(const array_t&) -- create an array value
1204
1205 @since version 1.0.0
1206 */
1207 template<class CompatibleArrayType, typename std::enable_if<
1208 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1209 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1210 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1211 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1212 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1213 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1214 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type = 0>
basic_json(const CompatibleArrayType & val)1215 basic_json(const CompatibleArrayType& val)
1216 : m_type(value_t::array)
1217 {
1218 using std::begin;
1219 using std::end;
1220 m_value.array = create<array_t>(begin(val), end(val));
1221 assert_invariant();
1222 }
1223
1224 /*!
1225 @brief create a string (explicit)
1226
1227 Create an string JSON value with a given content.
1228
1229 @param[in] val a value for the string
1230
1231 @complexity Linear in the size of the passed @a val.
1232
1233 @throw std::bad_alloc if allocation for string value fails
1234
1235 @liveexample{The following code shows the constructor with an @ref
1236 string_t parameter.,basic_json__string_t}
1237
1238 @sa @ref basic_json(const typename string_t::value_type*) -- create a
1239 string value from a character pointer
1240 @sa @ref basic_json(const CompatibleStringType&) -- create a string value
1241 from a compatible string container
1242
1243 @since version 1.0.0
1244 */
basic_json(const string_t & val)1245 basic_json(const string_t& val)
1246 : m_type(value_t::string), m_value(val)
1247 {
1248 assert_invariant();
1249 }
1250
1251 /*!
1252 @brief create a string (explicit)
1253
1254 Create a string JSON value with a given content.
1255
1256 @param[in] val a literal value for the string
1257
1258 @complexity Linear in the size of the passed @a val.
1259
1260 @throw std::bad_alloc if allocation for string value fails
1261
1262 @liveexample{The following code shows the constructor with string literal
1263 parameter.,basic_json__string_t_value_type}
1264
1265 @sa @ref basic_json(const string_t&) -- create a string value
1266 @sa @ref basic_json(const CompatibleStringType&) -- create a string value
1267 from a compatible string container
1268
1269 @since version 1.0.0
1270 */
basic_json(const typename string_t::value_type * val)1271 basic_json(const typename string_t::value_type* val)
1272 : basic_json(string_t(val))
1273 {
1274 assert_invariant();
1275 }
1276
1277 /*!
1278 @brief create a string (implicit)
1279
1280 Create a string JSON value with a given content.
1281
1282 @param[in] val a value for the string
1283
1284 @tparam CompatibleStringType an string type which is compatible to @ref
1285 string_t, for instance `std::string`.
1286
1287 @complexity Linear in the size of the passed @a val.
1288
1289 @throw std::bad_alloc if allocation for string value fails
1290
1291 @liveexample{The following code shows the construction of a string value
1292 from a compatible type.,basic_json__CompatibleStringType}
1293
1294 @sa @ref basic_json(const string_t&) -- create a string value
1295 @sa @ref basic_json(const typename string_t::value_type*) -- create a
1296 string value from a character pointer
1297
1298 @since version 1.0.0
1299 */
1300 template<class CompatibleStringType, typename std::enable_if<
1301 std::is_constructible<string_t, CompatibleStringType>::value, int>::type = 0>
basic_json(const CompatibleStringType & val)1302 basic_json(const CompatibleStringType& val)
1303 : basic_json(string_t(val))
1304 {
1305 assert_invariant();
1306 }
1307
1308 /*!
1309 @brief create a boolean (explicit)
1310
1311 Creates a JSON boolean type from a given value.
1312
1313 @param[in] val a boolean value to store
1314
1315 @complexity Constant.
1316
1317 @liveexample{The example below demonstrates boolean
1318 values.,basic_json__boolean_t}
1319
1320 @since version 1.0.0
1321 */
basic_json(boolean_t val)1322 basic_json(boolean_t val) noexcept
1323 : m_type(value_t::boolean), m_value(val)
1324 {
1325 assert_invariant();
1326 }
1327
1328 /*!
1329 @brief create an integer number (explicit)
1330
1331 Create an integer number JSON value with a given content.
1332
1333 @tparam T A helper type to remove this function via SFINAE in case @ref
1334 number_integer_t is the same as `int`. In this case, this constructor
1335 would have the same signature as @ref basic_json(const int value). Note
1336 the helper type @a T is not visible in this constructor's interface.
1337
1338 @param[in] val an integer to create a JSON number from
1339
1340 @complexity Constant.
1341
1342 @liveexample{The example below shows the construction of an integer
1343 number value.,basic_json__number_integer_t}
1344
1345 @sa @ref basic_json(const int) -- create a number value (integer)
1346 @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number
1347 value (integer) from a compatible number type
1348
1349 @since version 1.0.0
1350 */
1351 template<typename T, typename std::enable_if<
1352 not (std::is_same<T, int>::value) and
1353 std::is_same<T, number_integer_t>::value, int>::type = 0>
basic_json(const number_integer_t val)1354 basic_json(const number_integer_t val) noexcept
1355 : m_type(value_t::number_integer), m_value(val)
1356 {
1357 assert_invariant();
1358 }
1359
1360 /*!
1361 @brief create an integer number from an enum type (explicit)
1362
1363 Create an integer number JSON value with a given content.
1364
1365 @param[in] val an integer to create a JSON number from
1366
1367 @note This constructor allows to pass enums directly to a constructor. As
1368 C++ has no way of specifying the type of an anonymous enum explicitly, we
1369 can only rely on the fact that such values implicitly convert to int. As
1370 int may already be the same type of number_integer_t, we may need to
1371 switch off the constructor @ref basic_json(const number_integer_t).
1372
1373 @complexity Constant.
1374
1375 @liveexample{The example below shows the construction of an integer
1376 number value from an anonymous enum.,basic_json__const_int}
1377
1378 @sa @ref basic_json(const number_integer_t) -- create a number value
1379 (integer)
1380 @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number
1381 value (integer) from a compatible number type
1382
1383 @since version 1.0.0
1384 */
basic_json(const int val)1385 basic_json(const int val) noexcept
1386 : m_type(value_t::number_integer),
1387 m_value(static_cast<number_integer_t>(val))
1388 {
1389 assert_invariant();
1390 }
1391
1392 /*!
1393 @brief create an integer number (implicit)
1394
1395 Create an integer number JSON value with a given content. This constructor
1396 allows any type @a CompatibleNumberIntegerType that can be used to
1397 construct values of type @ref number_integer_t.
1398
1399 @tparam CompatibleNumberIntegerType An integer type which is compatible to
1400 @ref number_integer_t. Examples include the types `int`, `int32_t`,
1401 `long`, and `short`.
1402
1403 @param[in] val an integer to create a JSON number from
1404
1405 @complexity Constant.
1406
1407 @liveexample{The example below shows the construction of several integer
1408 number values from compatible
1409 types.,basic_json__CompatibleIntegerNumberType}
1410
1411 @sa @ref basic_json(const number_integer_t) -- create a number value
1412 (integer)
1413 @sa @ref basic_json(const int) -- create a number value (integer)
1414
1415 @since version 1.0.0
1416 */
1417 template<typename CompatibleNumberIntegerType, typename std::enable_if<
1418 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1419 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1420 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1421 CompatibleNumberIntegerType>::type = 0>
basic_json(const CompatibleNumberIntegerType val)1422 basic_json(const CompatibleNumberIntegerType val) noexcept
1423 : m_type(value_t::number_integer),
1424 m_value(static_cast<number_integer_t>(val))
1425 {
1426 assert_invariant();
1427 }
1428
1429 /*!
1430 @brief create an unsigned integer number (explicit)
1431
1432 Create an unsigned integer number JSON value with a given content.
1433
1434 @tparam T helper type to compare number_unsigned_t and unsigned int (not
1435 visible in) the interface.
1436
1437 @param[in] val an integer to create a JSON number from
1438
1439 @complexity Constant.
1440
1441 @sa @ref basic_json(const CompatibleNumberUnsignedType) -- create a number
1442 value (unsigned integer) from a compatible number type
1443
1444 @since version 2.0.0
1445 */
1446 template<typename T, typename std::enable_if<
1447 not (std::is_same<T, int>::value) and
1448 std::is_same<T, number_unsigned_t>::value, int>::type = 0>
basic_json(const number_unsigned_t val)1449 basic_json(const number_unsigned_t val) noexcept
1450 : m_type(value_t::number_unsigned), m_value(val)
1451 {
1452 assert_invariant();
1453 }
1454
1455 /*!
1456 @brief create an unsigned number (implicit)
1457
1458 Create an unsigned number JSON value with a given content. This
1459 constructor allows any type @a CompatibleNumberUnsignedType that can be
1460 used to construct values of type @ref number_unsigned_t.
1461
1462 @tparam CompatibleNumberUnsignedType An integer type which is compatible
1463 to @ref number_unsigned_t. Examples may include the types `unsigned int`,
1464 `uint32_t`, or `unsigned short`.
1465
1466 @param[in] val an unsigned integer to create a JSON number from
1467
1468 @complexity Constant.
1469
1470 @sa @ref basic_json(const number_unsigned_t) -- create a number value
1471 (unsigned)
1472
1473 @since version 2.0.0
1474 */
1475 template<typename CompatibleNumberUnsignedType, typename std::enable_if <
1476 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1477 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1478 not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1479 CompatibleNumberUnsignedType>::type = 0>
basic_json(const CompatibleNumberUnsignedType val)1480 basic_json(const CompatibleNumberUnsignedType val) noexcept
1481 : m_type(value_t::number_unsigned),
1482 m_value(static_cast<number_unsigned_t>(val))
1483 {
1484 assert_invariant();
1485 }
1486
1487 /*!
1488 @brief create a floating-point number (explicit)
1489
1490 Create a floating-point number JSON value with a given content.
1491
1492 @param[in] val a floating-point value to create a JSON number from
1493
1494 @note [RFC 7159](http://www.rfc-editor.org/rfc/rfc7159.txt), section 6
1495 disallows NaN values:
1496 > Numeric values that cannot be represented in the grammar below (such as
1497 > Infinity and NaN) are not permitted.
1498 In case the parameter @a val is not a number, a JSON null value is created
1499 instead.
1500
1501 @complexity Constant.
1502
1503 @liveexample{The following example creates several floating-point
1504 values.,basic_json__number_float_t}
1505
1506 @sa @ref basic_json(const CompatibleNumberFloatType) -- create a number
1507 value (floating-point) from a compatible number type
1508
1509 @since version 1.0.0
1510 */
basic_json(const number_float_t val)1511 basic_json(const number_float_t val) noexcept
1512 : m_type(value_t::number_float), m_value(val)
1513 {
1514 // replace infinity and NAN by null
1515 if (not std::isfinite(val))
1516 {
1517 m_type = value_t::null;
1518 m_value = json_value();
1519 }
1520
1521 assert_invariant();
1522 }
1523
1524 /*!
1525 @brief create an floating-point number (implicit)
1526
1527 Create an floating-point number JSON value with a given content. This
1528 constructor allows any type @a CompatibleNumberFloatType that can be used
1529 to construct values of type @ref number_float_t.
1530
1531 @tparam CompatibleNumberFloatType A floating-point type which is
1532 compatible to @ref number_float_t. Examples may include the types `float`
1533 or `double`.
1534
1535 @param[in] val a floating-point to create a JSON number from
1536
1537 @note [RFC 7159](http://www.rfc-editor.org/rfc/rfc7159.txt), section 6
1538 disallows NaN values:
1539 > Numeric values that cannot be represented in the grammar below (such as
1540 > Infinity and NaN) are not permitted.
1541 In case the parameter @a val is not a number, a JSON null value is
1542 created instead.
1543
1544 @complexity Constant.
1545
1546 @liveexample{The example below shows the construction of several
1547 floating-point number values from compatible
1548 types.,basic_json__CompatibleNumberFloatType}
1549
1550 @sa @ref basic_json(const number_float_t) -- create a number value
1551 (floating-point)
1552
1553 @since version 1.0.0
1554 */
1555 template<typename CompatibleNumberFloatType, typename = typename std::enable_if<
1556 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1557 std::is_floating_point<CompatibleNumberFloatType>::value>::type>
basic_json(const CompatibleNumberFloatType val)1558 basic_json(const CompatibleNumberFloatType val) noexcept
1559 : basic_json(number_float_t(val))
1560 {
1561 assert_invariant();
1562 }
1563
1564 /*!
1565 @brief create a container (array or object) from an initializer list
1566
1567 Creates a JSON value of type array or object from the passed initializer
1568 list @a init. In case @a type_deduction is `true` (default), the type of
1569 the JSON value to be created is deducted from the initializer list @a init
1570 according to the following rules:
1571
1572 1. If the list is empty, an empty JSON object value `{}` is created.
1573 2. If the list consists of pairs whose first element is a string, a JSON
1574 object value is created where the first elements of the pairs are
1575 treated as keys and the second elements are as values.
1576 3. In all other cases, an array is created.
1577
1578 The rules aim to create the best fit between a C++ initializer list and
1579 JSON values. The rationale is as follows:
1580
1581 1. The empty initializer list is written as `{}` which is exactly an empty
1582 JSON object.
1583 2. C++ has now way of describing mapped types other than to list a list of
1584 pairs. As JSON requires that keys must be of type string, rule 2 is the
1585 weakest constraint one can pose on initializer lists to interpret them
1586 as an object.
1587 3. In all other cases, the initializer list could not be interpreted as
1588 JSON object type, so interpreting it as JSON array type is safe.
1589
1590 With the rules described above, the following JSON values cannot be
1591 expressed by an initializer list:
1592
1593 - the empty array (`[]`): use @ref array(std::initializer_list<basic_json>)
1594 with an empty initializer list in this case
1595 - arrays whose elements satisfy rule 2: use @ref
1596 array(std::initializer_list<basic_json>) with the same initializer list
1597 in this case
1598
1599 @note When used without parentheses around an empty initializer list, @ref
1600 basic_json() is called instead of this function, yielding the JSON null
1601 value.
1602
1603 @param[in] init initializer list with JSON values
1604
1605 @param[in] type_deduction internal parameter; when set to `true`, the type
1606 of the JSON value is deducted from the initializer list @a init; when set
1607 to `false`, the type provided via @a manual_type is forced. This mode is
1608 used by the functions @ref array(std::initializer_list<basic_json>) and
1609 @ref object(std::initializer_list<basic_json>).
1610
1611 @param[in] manual_type internal parameter; when @a type_deduction is set
1612 to `false`, the created JSON value will use the provided type (only @ref
1613 value_t::array and @ref value_t::object are valid); when @a type_deduction
1614 is set to `true`, this parameter has no effect
1615
1616 @throw std::domain_error if @a type_deduction is `false`, @a manual_type
1617 is `value_t::object`, but @a init contains an element which is not a pair
1618 whose first element is a string; example: `"cannot create object from
1619 initializer list"`
1620
1621 @complexity Linear in the size of the initializer list @a init.
1622
1623 @liveexample{The example below shows how JSON values are created from
1624 initializer lists.,basic_json__list_init_t}
1625
1626 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
1627 value from an initializer list
1628 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
1629 value from an initializer list
1630
1631 @since version 1.0.0
1632 */
basic_json(std::initializer_list<basic_json> init,bool type_deduction=true,value_t manual_type=value_t::array)1633 basic_json(std::initializer_list<basic_json> init,
1634 bool type_deduction = true,
1635 value_t manual_type = value_t::array)
1636 {
1637 // check if each element is an array with two elements whose first
1638 // element is a string
1639 bool is_an_object = std::all_of(init.begin(), init.end(),
1640 [](const basic_json & element)
1641 {
1642 return element.is_array() and element.size() == 2 and element[0].is_string();
1643 });
1644
1645 // adjust type if type deduction is not wanted
1646 if (not type_deduction)
1647 {
1648 // if array is wanted, do not create an object though possible
1649 if (manual_type == value_t::array)
1650 {
1651 is_an_object = false;
1652 }
1653
1654 // if object is wanted but impossible, throw an exception
1655 if (manual_type == value_t::object and not is_an_object)
1656 {
1657 throw std::domain_error("cannot create object from initializer list");
1658 }
1659 }
1660
1661 if (is_an_object)
1662 {
1663 // the initializer list is a list of pairs -> create object
1664 m_type = value_t::object;
1665 m_value = value_t::object;
1666
1667 std::for_each(init.begin(), init.end(), [this](const basic_json & element)
1668 {
1669 m_value.object->emplace(*(element[0].m_value.string), element[1]);
1670 });
1671 }
1672 else
1673 {
1674 // the initializer list describes an array -> create array
1675 m_type = value_t::array;
1676 m_value.array = create<array_t>(init);
1677 }
1678
1679 assert_invariant();
1680 }
1681
1682 /*!
1683 @brief explicitly create an array from an initializer list
1684
1685 Creates a JSON array value from a given initializer list. That is, given a
1686 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
1687 initializer list is empty, the empty array `[]` is created.
1688
1689 @note This function is only needed to express two edge cases that cannot
1690 be realized with the initializer list constructor (@ref
1691 basic_json(std::initializer_list<basic_json>, bool, value_t)). These cases
1692 are:
1693 1. creating an array whose elements are all pairs whose first element is a
1694 string -- in this case, the initializer list constructor would create an
1695 object, taking the first elements as keys
1696 2. creating an empty array -- passing the empty initializer list to the
1697 initializer list constructor yields an empty object
1698
1699 @param[in] init initializer list with JSON values to create an array from
1700 (optional)
1701
1702 @return JSON array value
1703
1704 @complexity Linear in the size of @a init.
1705
1706 @liveexample{The following code shows an example for the `array`
1707 function.,array}
1708
1709 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
1710 create a JSON value from an initializer list
1711 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
1712 value from an initializer list
1713
1714 @since version 1.0.0
1715 */
array(std::initializer_list<basic_json> init=std::initializer_list<basic_json> ())1716 static basic_json array(std::initializer_list<basic_json> init =
1717 std::initializer_list<basic_json>())
1718 {
1719 return basic_json(init, false, value_t::array);
1720 }
1721
1722 /*!
1723 @brief explicitly create an object from an initializer list
1724
1725 Creates a JSON object value from a given initializer list. The initializer
1726 lists elements must be pairs, and their first elements must be strings. If
1727 the initializer list is empty, the empty object `{}` is created.
1728
1729 @note This function is only added for symmetry reasons. In contrast to the
1730 related function @ref array(std::initializer_list<basic_json>), there are
1731 no cases which can only be expressed by this function. That is, any
1732 initializer list @a init can also be passed to the initializer list
1733 constructor @ref basic_json(std::initializer_list<basic_json>, bool,
1734 value_t).
1735
1736 @param[in] init initializer list to create an object from (optional)
1737
1738 @return JSON object value
1739
1740 @throw std::domain_error if @a init is not a pair whose first elements are
1741 strings; thrown by
1742 @ref basic_json(std::initializer_list<basic_json>, bool, value_t)
1743
1744 @complexity Linear in the size of @a init.
1745
1746 @liveexample{The following code shows an example for the `object`
1747 function.,object}
1748
1749 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
1750 create a JSON value from an initializer list
1751 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
1752 value from an initializer list
1753
1754 @since version 1.0.0
1755 */
object(std::initializer_list<basic_json> init=std::initializer_list<basic_json> ())1756 static basic_json object(std::initializer_list<basic_json> init =
1757 std::initializer_list<basic_json>())
1758 {
1759 return basic_json(init, false, value_t::object);
1760 }
1761
1762 /*!
1763 @brief construct an array with count copies of given value
1764
1765 Constructs a JSON array value by creating @a cnt copies of a passed value.
1766 In case @a cnt is `0`, an empty array is created. As postcondition,
1767 `std::distance(begin(),end()) == cnt` holds.
1768
1769 @param[in] cnt the number of JSON copies of @a val to create
1770 @param[in] val the JSON value to copy
1771
1772 @complexity Linear in @a cnt.
1773
1774 @liveexample{The following code shows examples for the @ref
1775 basic_json(size_type\, const basic_json&)
1776 constructor.,basic_json__size_type_basic_json}
1777
1778 @since version 1.0.0
1779 */
basic_json(size_type cnt,const basic_json & val)1780 basic_json(size_type cnt, const basic_json& val)
1781 : m_type(value_t::array)
1782 {
1783 m_value.array = create<array_t>(cnt, val);
1784 assert_invariant();
1785 }
1786
1787 /*!
1788 @brief construct a JSON container given an iterator range
1789
1790 Constructs the JSON value with the contents of the range `[first, last)`.
1791 The semantics depends on the different types a JSON value can have:
1792 - In case of primitive types (number, boolean, or string), @a first must
1793 be `begin()` and @a last must be `end()`. In this case, the value is
1794 copied. Otherwise, std::out_of_range is thrown.
1795 - In case of structured types (array, object), the constructor behaves as
1796 similar versions for `std::vector`.
1797 - In case of a null type, std::domain_error is thrown.
1798
1799 @tparam InputIT an input iterator type (@ref iterator or @ref
1800 const_iterator)
1801
1802 @param[in] first begin of the range to copy from (included)
1803 @param[in] last end of the range to copy from (excluded)
1804
1805 @pre Iterators @a first and @a last must be initialized. **This
1806 precondition is enforced with an assertion.**
1807
1808 @throw std::domain_error if iterators are not compatible; that is, do not
1809 belong to the same JSON value; example: `"iterators are not compatible"`
1810 @throw std::out_of_range if iterators are for a primitive type (number,
1811 boolean, or string) where an out of range error can be detected easily;
1812 example: `"iterators out of range"`
1813 @throw std::bad_alloc if allocation for object, array, or string fails
1814 @throw std::domain_error if called with a null value; example: `"cannot
1815 use construct with iterators from null"`
1816
1817 @complexity Linear in distance between @a first and @a last.
1818
1819 @liveexample{The example below shows several ways to create JSON values by
1820 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
1821
1822 @since version 1.0.0
1823 */
1824 template<class InputIT, typename std::enable_if<
1825 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1826 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)1827 basic_json(InputIT first, InputIT last)
1828 {
1829 assert(first.m_object != nullptr);
1830 assert(last.m_object != nullptr);
1831
1832 // make sure iterator fits the current value
1833 if (first.m_object != last.m_object)
1834 {
1835 throw std::domain_error("iterators are not compatible");
1836 }
1837
1838 // copy type from first iterator
1839 m_type = first.m_object->m_type;
1840
1841 // check if iterator range is complete for primitive values
1842 switch (m_type)
1843 {
1844 case value_t::boolean:
1845 case value_t::number_float:
1846 case value_t::number_integer:
1847 case value_t::number_unsigned:
1848 case value_t::string:
1849 {
1850 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1851 {
1852 throw std::out_of_range("iterators out of range");
1853 }
1854 break;
1855 }
1856
1857 default:
1858 {
1859 break;
1860 }
1861 }
1862
1863 switch (m_type)
1864 {
1865 case value_t::number_integer:
1866 {
1867 m_value.number_integer = first.m_object->m_value.number_integer;
1868 break;
1869 }
1870
1871 case value_t::number_unsigned:
1872 {
1873 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1874 break;
1875 }
1876
1877 case value_t::number_float:
1878 {
1879 m_value.number_float = first.m_object->m_value.number_float;
1880 break;
1881 }
1882
1883 case value_t::boolean:
1884 {
1885 m_value.boolean = first.m_object->m_value.boolean;
1886 break;
1887 }
1888
1889 case value_t::string:
1890 {
1891 m_value = *first.m_object->m_value.string;
1892 break;
1893 }
1894
1895 case value_t::object:
1896 {
1897 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1898 break;
1899 }
1900
1901 case value_t::array:
1902 {
1903 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1904 break;
1905 }
1906
1907 default:
1908 {
1909 throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
1910 }
1911 }
1912
1913 assert_invariant();
1914 }
1915
1916 /*!
1917 @brief construct a JSON value given an input stream
1918
1919 @param[in,out] i stream to read a serialized JSON value from
1920 @param[in] cb a parser callback function of type @ref parser_callback_t
1921 which is used to control the deserialization by filtering unwanted values
1922 (optional)
1923
1924 @complexity Linear in the length of the input. The parser is a predictive
1925 LL(1) parser. The complexity can be higher if the parser callback function
1926 @a cb has a super-linear complexity.
1927
1928 @note A UTF-8 byte order mark is silently ignored.
1929
1930 @deprecated This constructor is deprecated and will be removed in version
1931 3.0.0 to unify the interface of the library. Deserialization will be
1932 done by stream operators or by calling one of the `parse` functions,
1933 e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
1934 like `json j(i);` for an input stream @a i need to be replaced by
1935 `json j = json::parse(i);`. See the example below.
1936
1937 @liveexample{The example below demonstrates constructing a JSON value from
1938 a `std::stringstream` with and without callback
1939 function.,basic_json__istream}
1940
1941 @since version 2.0.0, deprecated in version 2.0.3, to be removed in
1942 version 3.0.0
1943 */
1944 JSON_DEPRECATED
basic_json(std::istream & i,const parser_callback_t cb=nullptr)1945 explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
1946 {
1947 *this = parser(i, cb).parse();
1948 assert_invariant();
1949 }
1950
1951 ///////////////////////////////////////
1952 // other constructors and destructor //
1953 ///////////////////////////////////////
1954
1955 /*!
1956 @brief copy constructor
1957
1958 Creates a copy of a given JSON value.
1959
1960 @param[in] other the JSON value to copy
1961
1962 @complexity Linear in the size of @a other.
1963
1964 @requirement This function helps `basic_json` satisfying the
1965 [Container](http://en.cppreference.com/w/cpp/concept/Container)
1966 requirements:
1967 - The complexity is linear.
1968 - As postcondition, it holds: `other == basic_json(other)`.
1969
1970 @throw std::bad_alloc if allocation for object, array, or string fails.
1971
1972 @liveexample{The following code shows an example for the copy
1973 constructor.,basic_json__basic_json}
1974
1975 @since version 1.0.0
1976 */
basic_json(const basic_json & other)1977 basic_json(const basic_json& other)
1978 : m_type(other.m_type)
1979 {
1980 // check of passed value is valid
1981 other.assert_invariant();
1982
1983 switch (m_type)
1984 {
1985 case value_t::object:
1986 {
1987 m_value = *other.m_value.object;
1988 break;
1989 }
1990
1991 case value_t::array:
1992 {
1993 m_value = *other.m_value.array;
1994 break;
1995 }
1996
1997 case value_t::string:
1998 {
1999 m_value = *other.m_value.string;
2000 break;
2001 }
2002
2003 case value_t::boolean:
2004 {
2005 m_value = other.m_value.boolean;
2006 break;
2007 }
2008
2009 case value_t::number_integer:
2010 {
2011 m_value = other.m_value.number_integer;
2012 break;
2013 }
2014
2015 case value_t::number_unsigned:
2016 {
2017 m_value = other.m_value.number_unsigned;
2018 break;
2019 }
2020
2021 case value_t::number_float:
2022 {
2023 m_value = other.m_value.number_float;
2024 break;
2025 }
2026
2027 default:
2028 {
2029 break;
2030 }
2031 }
2032
2033 assert_invariant();
2034 }
2035
2036 /*!
2037 @brief move constructor
2038
2039 Move constructor. Constructs a JSON value with the contents of the given
2040 value @a other using move semantics. It "steals" the resources from @a
2041 other and leaves it as JSON null value.
2042
2043 @param[in,out] other value to move to this object
2044
2045 @post @a other is a JSON null value
2046
2047 @complexity Constant.
2048
2049 @liveexample{The code below shows the move constructor explicitly called
2050 via std::move.,basic_json__moveconstructor}
2051
2052 @since version 1.0.0
2053 */
basic_json(basic_json && other)2054 basic_json(basic_json&& other) noexcept
2055 : m_type(std::move(other.m_type)),
2056 m_value(std::move(other.m_value))
2057 {
2058 // check that passed value is valid
2059 other.assert_invariant();
2060
2061 // invalidate payload
2062 other.m_type = value_t::null;
2063 other.m_value = {};
2064
2065 assert_invariant();
2066 }
2067
2068 /*!
2069 @brief copy assignment
2070
2071 Copy assignment operator. Copies a JSON value via the "copy and swap"
2072 strategy: It is expressed in terms of the copy constructor, destructor,
2073 and the swap() member function.
2074
2075 @param[in] other value to copy from
2076
2077 @complexity Linear.
2078
2079 @requirement This function helps `basic_json` satisfying the
2080 [Container](http://en.cppreference.com/w/cpp/concept/Container)
2081 requirements:
2082 - The complexity is linear.
2083
2084 @liveexample{The code below shows and example for the copy assignment. It
2085 creates a copy of value `a` which is then swapped with `b`. Finally\, the
2086 copy of `a` (which is the null value after the swap) is
2087 destroyed.,basic_json__copyassignment}
2088
2089 @since version 1.0.0
2090 */
operator =(basic_json other)2091 reference& operator=(basic_json other) noexcept (
2092 std::is_nothrow_move_constructible<value_t>::value and
2093 std::is_nothrow_move_assignable<value_t>::value and
2094 std::is_nothrow_move_constructible<json_value>::value and
2095 std::is_nothrow_move_assignable<json_value>::value
2096 )
2097 {
2098 // check that passed value is valid
2099 other.assert_invariant();
2100
2101 using std::swap;
2102 swap(m_type, other.m_type);
2103 swap(m_value, other.m_value);
2104
2105 assert_invariant();
2106 return *this;
2107 }
2108
2109 /*!
2110 @brief destructor
2111
2112 Destroys the JSON value and frees all allocated memory.
2113
2114 @complexity Linear.
2115
2116 @requirement This function helps `basic_json` satisfying the
2117 [Container](http://en.cppreference.com/w/cpp/concept/Container)
2118 requirements:
2119 - The complexity is linear.
2120 - All stored elements are destroyed and all memory is freed.
2121
2122 @since version 1.0.0
2123 */
~basic_json()2124 ~basic_json()
2125 {
2126 assert_invariant();
2127
2128 switch (m_type)
2129 {
2130 case value_t::object:
2131 {
2132 AllocatorType<object_t> alloc;
2133 alloc.destroy(m_value.object);
2134 alloc.deallocate(m_value.object, 1);
2135 break;
2136 }
2137
2138 case value_t::array:
2139 {
2140 AllocatorType<array_t> alloc;
2141 alloc.destroy(m_value.array);
2142 alloc.deallocate(m_value.array, 1);
2143 break;
2144 }
2145
2146 case value_t::string:
2147 {
2148 AllocatorType<string_t> alloc;
2149 alloc.destroy(m_value.string);
2150 alloc.deallocate(m_value.string, 1);
2151 break;
2152 }
2153
2154 default:
2155 {
2156 // all other types need no specific destructor
2157 break;
2158 }
2159 }
2160 }
2161
2162 /// @}
2163
2164 public:
2165 ///////////////////////
2166 // object inspection //
2167 ///////////////////////
2168
2169 /// @name object inspection
2170 /// Functions to inspect the type of a JSON value.
2171 /// @{
2172
2173 /*!
2174 @brief serialization
2175
2176 Serialization function for JSON values. The function tries to mimic
2177 Python's `json.dumps()` function, and currently supports its @a indent
2178 parameter.
2179
2180 @param[in] indent If indent is nonnegative, then array elements and object
2181 members will be pretty-printed with that indent level. An indent level of
2182 `0` will only insert newlines. `-1` (the default) selects the most compact
2183 representation.
2184
2185 @return string containing the serialization of the JSON value
2186
2187 @complexity Linear.
2188
2189 @liveexample{The following example shows the effect of different @a indent
2190 parameters to the result of the serialization.,dump}
2191
2192 @see https://docs.python.org/2/library/json.html#json.dump
2193
2194 @since version 1.0.0
2195 */
dump(const int indent=-1) const2196 string_t dump(const int indent = -1) const
2197 {
2198 std::stringstream ss;
2199 // fix locale problems
2200 const static std::locale loc(std::locale(), new DecimalSeparator);
2201 ss.imbue(loc);
2202
2203 // 6, 15 or 16 digits of precision allows round-trip IEEE 754
2204 // string->float->string, string->double->string or string->long
2205 // double->string; to be safe, we read this value from
2206 // std::numeric_limits<number_float_t>::digits10
2207 ss.precision(std::numeric_limits<double>::digits10);
2208
2209 if (indent >= 0)
2210 {
2211 dump(ss, true, static_cast<unsigned int>(indent));
2212 }
2213 else
2214 {
2215 dump(ss, false, 0);
2216 }
2217
2218 return ss.str();
2219 }
2220
2221 /*!
2222 @brief return the type of the JSON value (explicit)
2223
2224 Return the type of the JSON value as a value from the @ref value_t
2225 enumeration.
2226
2227 @return the type of the JSON value
2228
2229 @complexity Constant.
2230
2231 @exceptionsafety No-throw guarantee: this member function never throws
2232 exceptions.
2233
2234 @liveexample{The following code exemplifies `type()` for all JSON
2235 types.,type}
2236
2237 @since version 1.0.0
2238 */
type() const2239 constexpr value_t type() const noexcept
2240 {
2241 return m_type;
2242 }
2243
2244 /*!
2245 @brief return whether type is primitive
2246
2247 This function returns true iff the JSON type is primitive (string, number,
2248 boolean, or null).
2249
2250 @return `true` if type is primitive (string, number, boolean, or null),
2251 `false` otherwise.
2252
2253 @complexity Constant.
2254
2255 @exceptionsafety No-throw guarantee: this member function never throws
2256 exceptions.
2257
2258 @liveexample{The following code exemplifies `is_primitive()` for all JSON
2259 types.,is_primitive}
2260
2261 @sa @ref is_structured() -- returns whether JSON value is structured
2262 @sa @ref is_null() -- returns whether JSON value is `null`
2263 @sa @ref is_string() -- returns whether JSON value is a string
2264 @sa @ref is_boolean() -- returns whether JSON value is a boolean
2265 @sa @ref is_number() -- returns whether JSON value is a number
2266
2267 @since version 1.0.0
2268 */
is_primitive() const2269 constexpr bool is_primitive() const noexcept
2270 {
2271 return is_null() or is_string() or is_boolean() or is_number();
2272 }
2273
2274 /*!
2275 @brief return whether type is structured
2276
2277 This function returns true iff the JSON type is structured (array or
2278 object).
2279
2280 @return `true` if type is structured (array or object), `false` otherwise.
2281
2282 @complexity Constant.
2283
2284 @exceptionsafety No-throw guarantee: this member function never throws
2285 exceptions.
2286
2287 @liveexample{The following code exemplifies `is_structured()` for all JSON
2288 types.,is_structured}
2289
2290 @sa @ref is_primitive() -- returns whether value is primitive
2291 @sa @ref is_array() -- returns whether value is an array
2292 @sa @ref is_object() -- returns whether value is an object
2293
2294 @since version 1.0.0
2295 */
is_structured() const2296 constexpr bool is_structured() const noexcept
2297 {
2298 return is_array() or is_object();
2299 }
2300
2301 /*!
2302 @brief return whether value is null
2303
2304 This function returns true iff the JSON value is null.
2305
2306 @return `true` if type is null, `false` otherwise.
2307
2308 @complexity Constant.
2309
2310 @exceptionsafety No-throw guarantee: this member function never throws
2311 exceptions.
2312
2313 @liveexample{The following code exemplifies `is_null()` for all JSON
2314 types.,is_null}
2315
2316 @since version 1.0.0
2317 */
is_null() const2318 constexpr bool is_null() const noexcept
2319 {
2320 return m_type == value_t::null;
2321 }
2322
2323 /*!
2324 @brief return whether value is a boolean
2325
2326 This function returns true iff the JSON value is a boolean.
2327
2328 @return `true` if type is boolean, `false` otherwise.
2329
2330 @complexity Constant.
2331
2332 @exceptionsafety No-throw guarantee: this member function never throws
2333 exceptions.
2334
2335 @liveexample{The following code exemplifies `is_boolean()` for all JSON
2336 types.,is_boolean}
2337
2338 @since version 1.0.0
2339 */
is_boolean() const2340 constexpr bool is_boolean() const noexcept
2341 {
2342 return m_type == value_t::boolean;
2343 }
2344
2345 /*!
2346 @brief return whether value is a number
2347
2348 This function returns true iff the JSON value is a number. This includes
2349 both integer and floating-point values.
2350
2351 @return `true` if type is number (regardless whether integer, unsigned
2352 integer or floating-type), `false` otherwise.
2353
2354 @complexity Constant.
2355
2356 @exceptionsafety No-throw guarantee: this member function never throws
2357 exceptions.
2358
2359 @liveexample{The following code exemplifies `is_number()` for all JSON
2360 types.,is_number}
2361
2362 @sa @ref is_number_integer() -- check if value is an integer or unsigned
2363 integer number
2364 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2365 number
2366 @sa @ref is_number_float() -- check if value is a floating-point number
2367
2368 @since version 1.0.0
2369 */
is_number() const2370 constexpr bool is_number() const noexcept
2371 {
2372 return is_number_integer() or is_number_float();
2373 }
2374
2375 /*!
2376 @brief return whether value is an integer number
2377
2378 This function returns true iff the JSON value is an integer or unsigned
2379 integer number. This excludes floating-point values.
2380
2381 @return `true` if type is an integer or unsigned integer number, `false`
2382 otherwise.
2383
2384 @complexity Constant.
2385
2386 @exceptionsafety No-throw guarantee: this member function never throws
2387 exceptions.
2388
2389 @liveexample{The following code exemplifies `is_number_integer()` for all
2390 JSON types.,is_number_integer}
2391
2392 @sa @ref is_number() -- check if value is a number
2393 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2394 number
2395 @sa @ref is_number_float() -- check if value is a floating-point number
2396
2397 @since version 1.0.0
2398 */
is_number_integer() const2399 constexpr bool is_number_integer() const noexcept
2400 {
2401 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2402 }
2403
2404 /*!
2405 @brief return whether value is an unsigned integer number
2406
2407 This function returns true iff the JSON value is an unsigned integer
2408 number. This excludes floating-point and (signed) integer values.
2409
2410 @return `true` if type is an unsigned integer number, `false` otherwise.
2411
2412 @complexity Constant.
2413
2414 @exceptionsafety No-throw guarantee: this member function never throws
2415 exceptions.
2416
2417 @liveexample{The following code exemplifies `is_number_unsigned()` for all
2418 JSON types.,is_number_unsigned}
2419
2420 @sa @ref is_number() -- check if value is a number
2421 @sa @ref is_number_integer() -- check if value is an integer or unsigned
2422 integer number
2423 @sa @ref is_number_float() -- check if value is a floating-point number
2424
2425 @since version 2.0.0
2426 */
is_number_unsigned() const2427 constexpr bool is_number_unsigned() const noexcept
2428 {
2429 return m_type == value_t::number_unsigned;
2430 }
2431
2432 /*!
2433 @brief return whether value is a floating-point number
2434
2435 This function returns true iff the JSON value is a floating-point number.
2436 This excludes integer and unsigned integer values.
2437
2438 @return `true` if type is a floating-point number, `false` otherwise.
2439
2440 @complexity Constant.
2441
2442 @exceptionsafety No-throw guarantee: this member function never throws
2443 exceptions.
2444
2445 @liveexample{The following code exemplifies `is_number_float()` for all
2446 JSON types.,is_number_float}
2447
2448 @sa @ref is_number() -- check if value is number
2449 @sa @ref is_number_integer() -- check if value is an integer number
2450 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2451 number
2452
2453 @since version 1.0.0
2454 */
is_number_float() const2455 constexpr bool is_number_float() const noexcept
2456 {
2457 return m_type == value_t::number_float;
2458 }
2459
2460 /*!
2461 @brief return whether value is an object
2462
2463 This function returns true iff the JSON value is an object.
2464
2465 @return `true` if type is object, `false` otherwise.
2466
2467 @complexity Constant.
2468
2469 @exceptionsafety No-throw guarantee: this member function never throws
2470 exceptions.
2471
2472 @liveexample{The following code exemplifies `is_object()` for all JSON
2473 types.,is_object}
2474
2475 @since version 1.0.0
2476 */
is_object() const2477 constexpr bool is_object() const noexcept
2478 {
2479 return m_type == value_t::object;
2480 }
2481
2482 /*!
2483 @brief return whether value is an array
2484
2485 This function returns true iff the JSON value is an array.
2486
2487 @return `true` if type is array, `false` otherwise.
2488
2489 @complexity Constant.
2490
2491 @exceptionsafety No-throw guarantee: this member function never throws
2492 exceptions.
2493
2494 @liveexample{The following code exemplifies `is_array()` for all JSON
2495 types.,is_array}
2496
2497 @since version 1.0.0
2498 */
is_array() const2499 constexpr bool is_array() const noexcept
2500 {
2501 return m_type == value_t::array;
2502 }
2503
2504 /*!
2505 @brief return whether value is a string
2506
2507 This function returns true iff the JSON value is a string.
2508
2509 @return `true` if type is string, `false` otherwise.
2510
2511 @complexity Constant.
2512
2513 @exceptionsafety No-throw guarantee: this member function never throws
2514 exceptions.
2515
2516 @liveexample{The following code exemplifies `is_string()` for all JSON
2517 types.,is_string}
2518
2519 @since version 1.0.0
2520 */
is_string() const2521 constexpr bool is_string() const noexcept
2522 {
2523 return m_type == value_t::string;
2524 }
2525
2526 /*!
2527 @brief return whether value is discarded
2528
2529 This function returns true iff the JSON value was discarded during parsing
2530 with a callback function (see @ref parser_callback_t).
2531
2532 @note This function will always be `false` for JSON values after parsing.
2533 That is, discarded values can only occur during parsing, but will be
2534 removed when inside a structured value or replaced by null in other cases.
2535
2536 @return `true` if type is discarded, `false` otherwise.
2537
2538 @complexity Constant.
2539
2540 @exceptionsafety No-throw guarantee: this member function never throws
2541 exceptions.
2542
2543 @liveexample{The following code exemplifies `is_discarded()` for all JSON
2544 types.,is_discarded}
2545
2546 @since version 1.0.0
2547 */
is_discarded() const2548 constexpr bool is_discarded() const noexcept
2549 {
2550 return m_type == value_t::discarded;
2551 }
2552
2553 /*!
2554 @brief return the type of the JSON value (implicit)
2555
2556 Implicitly return the type of the JSON value as a value from the @ref
2557 value_t enumeration.
2558
2559 @return the type of the JSON value
2560
2561 @complexity Constant.
2562
2563 @exceptionsafety No-throw guarantee: this member function never throws
2564 exceptions.
2565
2566 @liveexample{The following code exemplifies the @ref value_t operator for
2567 all JSON types.,operator__value_t}
2568
2569 @since version 1.0.0
2570 */
operator value_t() const2571 constexpr operator value_t() const noexcept
2572 {
2573 return m_type;
2574 }
2575
2576 /// @}
2577
2578 private:
2579 //////////////////
2580 // value access //
2581 //////////////////
2582
2583 /// get an object (explicit)
2584 template<class T, typename std::enable_if<
2585 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2586 std::is_convertible<basic_json_t, typename T::mapped_type>::value, int>::type = 0>
2587 T get_impl(T*) const
2588 {
2589 if (is_object())
2590 {
2591 return T(m_value.object->begin(), m_value.object->end());
2592 }
2593 else
2594 {
2595 throw std::domain_error("type must be object, but is " + type_name());
2596 }
2597 }
2598
2599 /// get an object (explicit)
get_impl(object_t *) const2600 object_t get_impl(object_t*) const
2601 {
2602 if (is_object())
2603 {
2604 return *(m_value.object);
2605 }
2606 else
2607 {
2608 throw std::domain_error("type must be object, but is " + type_name());
2609 }
2610 }
2611
2612 /// get an array (explicit)
2613 template<class T, typename std::enable_if<
2614 std::is_convertible<basic_json_t, typename T::value_type>::value and
2615 not std::is_same<basic_json_t, typename T::value_type>::value and
2616 not std::is_arithmetic<T>::value and
2617 not std::is_convertible<std::string, T>::value and
2618 not has_mapped_type<T>::value, int>::type = 0>
2619 T get_impl(T*) const
2620 {
2621 if (is_array())
2622 {
2623 T to_vector;
2624 std::transform(m_value.array->begin(), m_value.array->end(),
2625 std::inserter(to_vector, to_vector.end()), [](basic_json i)
__anon197e37760502(basic_json i) 2626 {
2627 return i.get<typename T::value_type>();
2628 });
2629 return to_vector;
2630 }
2631 else
2632 {
2633 throw std::domain_error("type must be array, but is " + type_name());
2634 }
2635 }
2636
2637 /// get an array (explicit)
2638 template<class T, typename std::enable_if<
2639 std::is_convertible<basic_json_t, T>::value and
2640 not std::is_same<basic_json_t, T>::value, int>::type = 0>
get_impl(std::vector<T> *) const2641 std::vector<T> get_impl(std::vector<T>*) const
2642 {
2643 if (is_array())
2644 {
2645 std::vector<T> to_vector;
2646 to_vector.reserve(m_value.array->size());
2647 std::transform(m_value.array->begin(), m_value.array->end(),
2648 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2649 {
2650 return i.get<T>();
2651 });
2652 return to_vector;
2653 }
2654 else
2655 {
2656 throw std::domain_error("type must be array, but is " + type_name());
2657 }
2658 }
2659
2660 /// get an array (explicit)
2661 template<class T, typename std::enable_if<
2662 std::is_same<basic_json, typename T::value_type>::value and
2663 not has_mapped_type<T>::value, int>::type = 0>
2664 T get_impl(T*) const
2665 {
2666 if (is_array())
2667 {
2668 return T(m_value.array->begin(), m_value.array->end());
2669 }
2670 else
2671 {
2672 throw std::domain_error("type must be array, but is " + type_name());
2673 }
2674 }
2675
2676 /// get an array (explicit)
get_impl(array_t *) const2677 array_t get_impl(array_t*) const
2678 {
2679 if (is_array())
2680 {
2681 return *(m_value.array);
2682 }
2683 else
2684 {
2685 throw std::domain_error("type must be array, but is " + type_name());
2686 }
2687 }
2688
2689 /// get a string (explicit)
2690 template<typename T, typename std::enable_if<
2691 std::is_convertible<string_t, T>::value, int>::type = 0>
2692 T get_impl(T*) const
2693 {
2694 if (is_string())
2695 {
2696 return *m_value.string;
2697 }
2698 else
2699 {
2700 throw std::domain_error("type must be string, but is " + type_name());
2701 }
2702 }
2703
2704 /// get a number (explicit)
2705 template<typename T, typename std::enable_if<
2706 std::is_arithmetic<T>::value, int>::type = 0>
2707 T get_impl(T*) const
2708 {
2709 switch (m_type)
2710 {
2711 case value_t::number_integer:
2712 {
2713 return static_cast<T>(m_value.number_integer);
2714 }
2715
2716 case value_t::number_unsigned:
2717 {
2718 return static_cast<T>(m_value.number_unsigned);
2719 }
2720
2721 case value_t::number_float:
2722 {
2723 return static_cast<T>(m_value.number_float);
2724 }
2725
2726 default:
2727 {
2728 throw std::domain_error("type must be number, but is " + type_name());
2729 }
2730 }
2731 }
2732
2733 /// get a boolean (explicit)
get_impl(boolean_t *) const2734 constexpr boolean_t get_impl(boolean_t*) const
2735 {
2736 return is_boolean()
2737 ? m_value.boolean
2738 : throw std::domain_error("type must be boolean, but is " + type_name());
2739 }
2740
2741 /// get a pointer to the value (object)
get_impl_ptr(object_t *)2742 object_t* get_impl_ptr(object_t*) noexcept
2743 {
2744 return is_object() ? m_value.object : nullptr;
2745 }
2746
2747 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const2748 constexpr const object_t* get_impl_ptr(const object_t*) const noexcept
2749 {
2750 return is_object() ? m_value.object : nullptr;
2751 }
2752
2753 /// get a pointer to the value (array)
get_impl_ptr(array_t *)2754 array_t* get_impl_ptr(array_t*) noexcept
2755 {
2756 return is_array() ? m_value.array : nullptr;
2757 }
2758
2759 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const2760 constexpr const array_t* get_impl_ptr(const array_t*) const noexcept
2761 {
2762 return is_array() ? m_value.array : nullptr;
2763 }
2764
2765 /// get a pointer to the value (string)
get_impl_ptr(string_t *)2766 string_t* get_impl_ptr(string_t*) noexcept
2767 {
2768 return is_string() ? m_value.string : nullptr;
2769 }
2770
2771 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const2772 constexpr const string_t* get_impl_ptr(const string_t*) const noexcept
2773 {
2774 return is_string() ? m_value.string : nullptr;
2775 }
2776
2777 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)2778 boolean_t* get_impl_ptr(boolean_t*) noexcept
2779 {
2780 return is_boolean() ? &m_value.boolean : nullptr;
2781 }
2782
2783 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const2784 constexpr const boolean_t* get_impl_ptr(const boolean_t*) const noexcept
2785 {
2786 return is_boolean() ? &m_value.boolean : nullptr;
2787 }
2788
2789 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)2790 number_integer_t* get_impl_ptr(number_integer_t*) noexcept
2791 {
2792 return is_number_integer() ? &m_value.number_integer : nullptr;
2793 }
2794
2795 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const2796 constexpr const number_integer_t* get_impl_ptr(const number_integer_t*) const noexcept
2797 {
2798 return is_number_integer() ? &m_value.number_integer : nullptr;
2799 }
2800
2801 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)2802 number_unsigned_t* get_impl_ptr(number_unsigned_t*) noexcept
2803 {
2804 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2805 }
2806
2807 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const2808 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t*) const noexcept
2809 {
2810 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2811 }
2812
2813 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)2814 number_float_t* get_impl_ptr(number_float_t*) noexcept
2815 {
2816 return is_number_float() ? &m_value.number_float : nullptr;
2817 }
2818
2819 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const2820 constexpr const number_float_t* get_impl_ptr(const number_float_t*) const noexcept
2821 {
2822 return is_number_float() ? &m_value.number_float : nullptr;
2823 }
2824
2825 /*!
2826 @brief helper function to implement get_ref()
2827
2828 This funcion helps to implement get_ref() without code duplication for
2829 const and non-const overloads
2830
2831 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
2832
2833 @throw std::domain_error if ReferenceType does not match underlying value
2834 type of the current JSON
2835 */
2836 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)2837 static ReferenceType get_ref_impl(ThisType& obj)
2838 {
2839 // helper type
2840 using PointerType = typename std::add_pointer<ReferenceType>::type;
2841
2842 // delegate the call to get_ptr<>()
2843 auto ptr = obj.template get_ptr<PointerType>();
2844
2845 if (ptr != nullptr)
2846 {
2847 return *ptr;
2848 }
2849 else
2850 {
2851 throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
2852 obj.type_name());
2853 }
2854 }
2855
2856 public:
2857
2858 /// @name value access
2859 /// Direct access to the stored value of a JSON value.
2860 /// @{
2861
2862 /*!
2863 @brief get a value (explicit)
2864
2865 Explicit type conversion between the JSON value and a compatible value.
2866
2867 @tparam ValueType non-pointer type compatible to the JSON value, for
2868 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
2869 `std::vector` types for JSON arrays
2870
2871 @return copy of the JSON value, converted to type @a ValueType
2872
2873 @throw std::domain_error in case passed type @a ValueType is incompatible
2874 to JSON; example: `"type must be object, but is null"`
2875
2876 @complexity Linear in the size of the JSON value.
2877
2878 @liveexample{The example below shows several conversions from JSON values
2879 to other types. There a few things to note: (1) Floating-point numbers can
2880 be converted to integers\, (2) A JSON array can be converted to a standard
2881 `std::vector<short>`\, (3) A JSON object can be converted to C++
2882 associative containers such as `std::unordered_map<std::string\,
2883 json>`.,get__ValueType_const}
2884
2885 @internal
2886 The idea of using a casted null pointer to choose the correct
2887 implementation is from <http://stackoverflow.com/a/8315197/266378>.
2888 @endinternal
2889
2890 @sa @ref operator ValueType() const for implicit conversion
2891 @sa @ref get() for pointer-member access
2892
2893 @since version 1.0.0
2894 */
2895 template<typename ValueType, typename std::enable_if<
2896 not std::is_pointer<ValueType>::value, int>::type = 0>
2897 ValueType get() const
2898 {
2899 return get_impl(static_cast<ValueType*>(nullptr));
2900 }
2901
2902 /*!
2903 @brief get a pointer value (explicit)
2904
2905 Explicit pointer access to the internally stored JSON value. No copies are
2906 made.
2907
2908 @warning The pointer becomes invalid if the underlying JSON object
2909 changes.
2910
2911 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
2912 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
2913 @ref number_unsigned_t, or @ref number_float_t.
2914
2915 @return pointer to the internally stored JSON value if the requested
2916 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
2917
2918 @complexity Constant.
2919
2920 @liveexample{The example below shows how pointers to internal values of a
2921 JSON value can be requested. Note that no type conversions are made and a
2922 `nullptr` is returned if the value and the requested pointer type does not
2923 match.,get__PointerType}
2924
2925 @sa @ref get_ptr() for explicit pointer-member access
2926
2927 @since version 1.0.0
2928 */
2929 template<typename PointerType, typename std::enable_if<
2930 std::is_pointer<PointerType>::value, int>::type = 0>
2931 PointerType get() noexcept
2932 {
2933 // delegate the call to get_ptr
2934 return get_ptr<PointerType>();
2935 }
2936
2937 /*!
2938 @brief get a pointer value (explicit)
2939 @copydoc get()
2940 */
2941 template<typename PointerType, typename std::enable_if<
2942 std::is_pointer<PointerType>::value, int>::type = 0>
get() const2943 constexpr const PointerType get() const noexcept
2944 {
2945 // delegate the call to get_ptr
2946 return get_ptr<PointerType>();
2947 }
2948
2949 /*!
2950 @brief get a pointer value (implicit)
2951
2952 Implicit pointer access to the internally stored JSON value. No copies are
2953 made.
2954
2955 @warning Writing data to the pointee of the result yields an undefined
2956 state.
2957
2958 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
2959 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
2960 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
2961 assertion.
2962
2963 @return pointer to the internally stored JSON value if the requested
2964 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
2965
2966 @complexity Constant.
2967
2968 @liveexample{The example below shows how pointers to internal values of a
2969 JSON value can be requested. Note that no type conversions are made and a
2970 `nullptr` is returned if the value and the requested pointer type does not
2971 match.,get_ptr}
2972
2973 @since version 1.0.0
2974 */
2975 template<typename PointerType, typename std::enable_if<
2976 std::is_pointer<PointerType>::value, int>::type = 0>
2977 PointerType get_ptr() noexcept
2978 {
2979 // get the type of the PointerType (remove pointer and const)
2980 using pointee_t = typename std::remove_const<typename
2981 std::remove_pointer<typename
2982 std::remove_const<PointerType>::type>::type>::type;
2983 // make sure the type matches the allowed types
2984 static_assert(
2985 std::is_same<object_t, pointee_t>::value
2986 or std::is_same<array_t, pointee_t>::value
2987 or std::is_same<string_t, pointee_t>::value
2988 or std::is_same<boolean_t, pointee_t>::value
2989 or std::is_same<number_integer_t, pointee_t>::value
2990 or std::is_same<number_unsigned_t, pointee_t>::value
2991 or std::is_same<number_float_t, pointee_t>::value
2992 , "incompatible pointer type");
2993
2994 // delegate the call to get_impl_ptr<>()
2995 return get_impl_ptr(static_cast<PointerType>(nullptr));
2996 }
2997
2998 /*!
2999 @brief get a pointer value (implicit)
3000 @copydoc get_ptr()
3001 */
3002 template<typename PointerType, typename std::enable_if<
3003 std::is_pointer<PointerType>::value and
3004 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const3005 constexpr const PointerType get_ptr() const noexcept
3006 {
3007 // get the type of the PointerType (remove pointer and const)
3008 using pointee_t = typename std::remove_const<typename
3009 std::remove_pointer<typename
3010 std::remove_const<PointerType>::type>::type>::type;
3011 // make sure the type matches the allowed types
3012 static_assert(
3013 std::is_same<object_t, pointee_t>::value
3014 or std::is_same<array_t, pointee_t>::value
3015 or std::is_same<string_t, pointee_t>::value
3016 or std::is_same<boolean_t, pointee_t>::value
3017 or std::is_same<number_integer_t, pointee_t>::value
3018 or std::is_same<number_unsigned_t, pointee_t>::value
3019 or std::is_same<number_float_t, pointee_t>::value
3020 , "incompatible pointer type");
3021
3022 // delegate the call to get_impl_ptr<>() const
3023 return get_impl_ptr(static_cast<const PointerType>(nullptr));
3024 }
3025
3026 /*!
3027 @brief get a reference value (implicit)
3028
3029 Implict reference access to the internally stored JSON value. No copies
3030 are made.
3031
3032 @warning Writing data to the referee of the result yields an undefined
3033 state.
3034
3035 @tparam ReferenceType reference type; must be a reference to @ref array_t,
3036 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
3037 @ref number_float_t. Enforced by static assertion.
3038
3039 @return reference to the internally stored JSON value if the requested
3040 reference type @a ReferenceType fits to the JSON value; throws
3041 std::domain_error otherwise
3042
3043 @throw std::domain_error in case passed type @a ReferenceType is
3044 incompatible with the stored JSON value
3045
3046 @complexity Constant.
3047
3048 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
3049
3050 @since version 1.1.0
3051 */
3052 template<typename ReferenceType, typename std::enable_if<
3053 std::is_reference<ReferenceType>::value, int>::type = 0>
3054 ReferenceType get_ref()
3055 {
3056 // delegate call to get_ref_impl
3057 return get_ref_impl<ReferenceType>(*this);
3058 }
3059
3060 /*!
3061 @brief get a reference value (implicit)
3062 @copydoc get_ref()
3063 */
3064 template<typename ReferenceType, typename std::enable_if<
3065 std::is_reference<ReferenceType>::value and
3066 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
3067 ReferenceType get_ref() const
3068 {
3069 // delegate call to get_ref_impl
3070 return get_ref_impl<ReferenceType>(*this);
3071 }
3072
3073 /*!
3074 @brief get a value (implicit)
3075
3076 Implicit type conversion between the JSON value and a compatible value.
3077 The call is realized by calling @ref get() const.
3078
3079 @tparam ValueType non-pointer type compatible to the JSON value, for
3080 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
3081 `std::vector` types for JSON arrays. The character type of @ref string_t
3082 as well as an initializer list of this type is excluded to avoid
3083 ambiguities as these types implicitly convert to `std::string`.
3084
3085 @return copy of the JSON value, converted to type @a ValueType
3086
3087 @throw std::domain_error in case passed type @a ValueType is incompatible
3088 to JSON, thrown by @ref get() const
3089
3090 @complexity Linear in the size of the JSON value.
3091
3092 @liveexample{The example below shows several conversions from JSON values
3093 to other types. There a few things to note: (1) Floating-point numbers can
3094 be converted to integers\, (2) A JSON array can be converted to a standard
3095 `std::vector<short>`\, (3) A JSON object can be converted to C++
3096 associative containers such as `std::unordered_map<std::string\,
3097 json>`.,operator__ValueType}
3098
3099 @since version 1.0.0
3100 */
3101 template < typename ValueType, typename std::enable_if <
3102 not std::is_pointer<ValueType>::value and
3103 not std::is_same<ValueType, typename string_t::value_type>::value
3104 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015
3105 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3106 #endif
3107 , int >::type = 0 >
operator ValueType() const3108 operator ValueType() const
3109 {
3110 // delegate the call to get<>() const
3111 return get<ValueType>();
3112 }
3113
3114 /// @}
3115
3116
3117 ////////////////////
3118 // element access //
3119 ////////////////////
3120
3121 /// @name element access
3122 /// Access to the JSON value.
3123 /// @{
3124
3125 /*!
3126 @brief access specified array element with bounds checking
3127
3128 Returns a reference to the element at specified location @a idx, with
3129 bounds checking.
3130
3131 @param[in] idx index of the element to access
3132
3133 @return reference to the element at index @a idx
3134
3135 @throw std::domain_error if the JSON value is not an array; example:
3136 `"cannot use at() with string"`
3137 @throw std::out_of_range if the index @a idx is out of range of the array;
3138 that is, `idx >= size()`; example: `"array index 7 is out of range"`
3139
3140 @complexity Constant.
3141
3142 @liveexample{The example below shows how array elements can be read and
3143 written using `at()`.,at__size_type}
3144
3145 @since version 1.0.0
3146 */
at(size_type idx)3147 reference at(size_type idx)
3148 {
3149 // at only works for arrays
3150 if (is_array())
3151 {
3152 try
3153 {
3154 return m_value.array->at(idx);
3155 }
3156 catch (std::out_of_range&)
3157 {
3158 // create better exception explanation
3159 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
3160 }
3161 }
3162 else
3163 {
3164 throw std::domain_error("cannot use at() with " + type_name());
3165 }
3166 }
3167
3168 /*!
3169 @brief access specified array element with bounds checking
3170
3171 Returns a const reference to the element at specified location @a idx,
3172 with bounds checking.
3173
3174 @param[in] idx index of the element to access
3175
3176 @return const reference to the element at index @a idx
3177
3178 @throw std::domain_error if the JSON value is not an array; example:
3179 `"cannot use at() with string"`
3180 @throw std::out_of_range if the index @a idx is out of range of the array;
3181 that is, `idx >= size()`; example: `"array index 7 is out of range"`
3182
3183 @complexity Constant.
3184
3185 @liveexample{The example below shows how array elements can be read using
3186 `at()`.,at__size_type_const}
3187
3188 @since version 1.0.0
3189 */
at(size_type idx) const3190 const_reference at(size_type idx) const
3191 {
3192 // at only works for arrays
3193 if (is_array())
3194 {
3195 try
3196 {
3197 return m_value.array->at(idx);
3198 }
3199 catch (std::out_of_range&)
3200 {
3201 // create better exception explanation
3202 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
3203 }
3204 }
3205 else
3206 {
3207 throw std::domain_error("cannot use at() with " + type_name());
3208 }
3209 }
3210
3211 /*!
3212 @brief access specified object element with bounds checking
3213
3214 Returns a reference to the element at with specified key @a key, with
3215 bounds checking.
3216
3217 @param[in] key key of the element to access
3218
3219 @return reference to the element at key @a key
3220
3221 @throw std::domain_error if the JSON value is not an object; example:
3222 `"cannot use at() with boolean"`
3223 @throw std::out_of_range if the key @a key is is not stored in the object;
3224 that is, `find(key) == end()`; example: `"key "the fast" not found"`
3225
3226 @complexity Logarithmic in the size of the container.
3227
3228 @liveexample{The example below shows how object elements can be read and
3229 written using `at()`.,at__object_t_key_type}
3230
3231 @sa @ref operator[](const typename object_t::key_type&) for unchecked
3232 access by reference
3233 @sa @ref value() for access by value with a default value
3234
3235 @since version 1.0.0
3236 */
at(const typename object_t::key_type & key)3237 reference at(const typename object_t::key_type& key)
3238 {
3239 // at only works for objects
3240 if (is_object())
3241 {
3242 try
3243 {
3244 return m_value.object->at(key);
3245 }
3246 catch (std::out_of_range&)
3247 {
3248 // create better exception explanation
3249 throw std::out_of_range("key '" + key + "' not found");
3250 }
3251 }
3252 else
3253 {
3254 throw std::domain_error("cannot use at() with " + type_name());
3255 }
3256 }
3257
3258 /*!
3259 @brief access specified object element with bounds checking
3260
3261 Returns a const reference to the element at with specified key @a key,
3262 with bounds checking.
3263
3264 @param[in] key key of the element to access
3265
3266 @return const reference to the element at key @a key
3267
3268 @throw std::domain_error if the JSON value is not an object; example:
3269 `"cannot use at() with boolean"`
3270 @throw std::out_of_range if the key @a key is is not stored in the object;
3271 that is, `find(key) == end()`; example: `"key "the fast" not found"`
3272
3273 @complexity Logarithmic in the size of the container.
3274
3275 @liveexample{The example below shows how object elements can be read using
3276 `at()`.,at__object_t_key_type_const}
3277
3278 @sa @ref operator[](const typename object_t::key_type&) for unchecked
3279 access by reference
3280 @sa @ref value() for access by value with a default value
3281
3282 @since version 1.0.0
3283 */
at(const typename object_t::key_type & key) const3284 const_reference at(const typename object_t::key_type& key) const
3285 {
3286 // at only works for objects
3287 if (is_object())
3288 {
3289 try
3290 {
3291 return m_value.object->at(key);
3292 }
3293 catch (std::out_of_range&)
3294 {
3295 // create better exception explanation
3296 throw std::out_of_range("key '" + key + "' not found");
3297 }
3298 }
3299 else
3300 {
3301 throw std::domain_error("cannot use at() with " + type_name());
3302 }
3303 }
3304
3305 /*!
3306 @brief access specified array element
3307
3308 Returns a reference to the element at specified location @a idx.
3309
3310 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
3311 then the array is silently filled up with `null` values to make `idx` a
3312 valid reference to the last stored element.
3313
3314 @param[in] idx index of the element to access
3315
3316 @return reference to the element at index @a idx
3317
3318 @throw std::domain_error if JSON is not an array or null; example:
3319 `"cannot use operator[] with string"`
3320
3321 @complexity Constant if @a idx is in the range of the array. Otherwise
3322 linear in `idx - size()`.
3323
3324 @liveexample{The example below shows how array elements can be read and
3325 written using `[]` operator. Note the addition of `null`
3326 values.,operatorarray__size_type}
3327
3328 @since version 1.0.0
3329 */
operator [](size_type idx)3330 reference operator[](size_type idx)
3331 {
3332 // implicitly convert null value to an empty array
3333 if (is_null())
3334 {
3335 m_type = value_t::array;
3336 m_value.array = create<array_t>();
3337 assert_invariant();
3338 }
3339
3340 // operator[] only works for arrays
3341 if (is_array())
3342 {
3343 // fill up array with null values if given idx is outside range
3344 if (idx >= m_value.array->size())
3345 {
3346 m_value.array->insert(m_value.array->end(),
3347 idx - m_value.array->size() + 1,
3348 basic_json());
3349 }
3350
3351 return m_value.array->operator[](idx);
3352 }
3353 else
3354 {
3355 throw std::domain_error("cannot use operator[] with " + type_name());
3356 }
3357 }
3358
3359 /*!
3360 @brief access specified array element
3361
3362 Returns a const reference to the element at specified location @a idx.
3363
3364 @param[in] idx index of the element to access
3365
3366 @return const reference to the element at index @a idx
3367
3368 @throw std::domain_error if JSON is not an array; example: `"cannot use
3369 operator[] with null"`
3370
3371 @complexity Constant.
3372
3373 @liveexample{The example below shows how array elements can be read using
3374 the `[]` operator.,operatorarray__size_type_const}
3375
3376 @since version 1.0.0
3377 */
operator [](size_type idx) const3378 const_reference operator[](size_type idx) const
3379 {
3380 // const operator[] only works for arrays
3381 if (is_array())
3382 {
3383 return m_value.array->operator[](idx);
3384 }
3385 else
3386 {
3387 throw std::domain_error("cannot use operator[] with " + type_name());
3388 }
3389 }
3390
3391 /*!
3392 @brief access specified object element
3393
3394 Returns a reference to the element at with specified key @a key.
3395
3396 @note If @a key is not found in the object, then it is silently added to
3397 the object and filled with a `null` value to make `key` a valid reference.
3398 In case the value was `null` before, it is converted to an object.
3399
3400 @param[in] key key of the element to access
3401
3402 @return reference to the element at key @a key
3403
3404 @throw std::domain_error if JSON is not an object or null; example:
3405 `"cannot use operator[] with string"`
3406
3407 @complexity Logarithmic in the size of the container.
3408
3409 @liveexample{The example below shows how object elements can be read and
3410 written using the `[]` operator.,operatorarray__key_type}
3411
3412 @sa @ref at(const typename object_t::key_type&) for access by reference
3413 with range checking
3414 @sa @ref value() for access by value with a default value
3415
3416 @since version 1.0.0
3417 */
operator [](const typename object_t::key_type & key)3418 reference operator[](const typename object_t::key_type& key)
3419 {
3420 // implicitly convert null value to an empty object
3421 if (is_null())
3422 {
3423 m_type = value_t::object;
3424 m_value.object = create<object_t>();
3425 assert_invariant();
3426 }
3427
3428 // operator[] only works for objects
3429 if (is_object())
3430 {
3431 return m_value.object->operator[](key);
3432 }
3433 else
3434 {
3435 throw std::domain_error("cannot use operator[] with " + type_name());
3436 }
3437 }
3438
3439 /*!
3440 @brief read-only access specified object element
3441
3442 Returns a const reference to the element at with specified key @a key. No
3443 bounds checking is performed.
3444
3445 @warning If the element with key @a key does not exist, the behavior is
3446 undefined.
3447
3448 @param[in] key key of the element to access
3449
3450 @return const reference to the element at key @a key
3451
3452 @pre The element with key @a key must exist. **This precondition is
3453 enforced with an assertion.**
3454
3455 @throw std::domain_error if JSON is not an object; example: `"cannot use
3456 operator[] with null"`
3457
3458 @complexity Logarithmic in the size of the container.
3459
3460 @liveexample{The example below shows how object elements can be read using
3461 the `[]` operator.,operatorarray__key_type_const}
3462
3463 @sa @ref at(const typename object_t::key_type&) for access by reference
3464 with range checking
3465 @sa @ref value() for access by value with a default value
3466
3467 @since version 1.0.0
3468 */
operator [](const typename object_t::key_type & key) const3469 const_reference operator[](const typename object_t::key_type& key) const
3470 {
3471 // const operator[] only works for objects
3472 if (is_object())
3473 {
3474 assert(m_value.object->find(key) != m_value.object->end());
3475 return m_value.object->find(key)->second;
3476 }
3477 else
3478 {
3479 throw std::domain_error("cannot use operator[] with " + type_name());
3480 }
3481 }
3482
3483 /*!
3484 @brief access specified object element
3485
3486 Returns a reference to the element at with specified key @a key.
3487
3488 @note If @a key is not found in the object, then it is silently added to
3489 the object and filled with a `null` value to make `key` a valid reference.
3490 In case the value was `null` before, it is converted to an object.
3491
3492 @param[in] key key of the element to access
3493
3494 @return reference to the element at key @a key
3495
3496 @throw std::domain_error if JSON is not an object or null; example:
3497 `"cannot use operator[] with string"`
3498
3499 @complexity Logarithmic in the size of the container.
3500
3501 @liveexample{The example below shows how object elements can be read and
3502 written using the `[]` operator.,operatorarray__key_type}
3503
3504 @sa @ref at(const typename object_t::key_type&) for access by reference
3505 with range checking
3506 @sa @ref value() for access by value with a default value
3507
3508 @since version 1.0.0
3509 */
3510 template<typename T, std::size_t n>
operator [](T * (& key)[n])3511 reference operator[](T * (&key)[n])
3512 {
3513 return operator[](static_cast<const T>(key));
3514 }
3515
3516 /*!
3517 @brief read-only access specified object element
3518
3519 Returns a const reference to the element at with specified key @a key. No
3520 bounds checking is performed.
3521
3522 @warning If the element with key @a key does not exist, the behavior is
3523 undefined.
3524
3525 @note This function is required for compatibility reasons with Clang.
3526
3527 @param[in] key key of the element to access
3528
3529 @return const reference to the element at key @a key
3530
3531 @throw std::domain_error if JSON is not an object; example: `"cannot use
3532 operator[] with null"`
3533
3534 @complexity Logarithmic in the size of the container.
3535
3536 @liveexample{The example below shows how object elements can be read using
3537 the `[]` operator.,operatorarray__key_type_const}
3538
3539 @sa @ref at(const typename object_t::key_type&) for access by reference
3540 with range checking
3541 @sa @ref value() for access by value with a default value
3542
3543 @since version 1.0.0
3544 */
3545 template<typename T, std::size_t n>
operator [](T * (& key)[n]) const3546 const_reference operator[](T * (&key)[n]) const
3547 {
3548 return operator[](static_cast<const T>(key));
3549 }
3550
3551 /*!
3552 @brief access specified object element
3553
3554 Returns a reference to the element at with specified key @a key.
3555
3556 @note If @a key is not found in the object, then it is silently added to
3557 the object and filled with a `null` value to make `key` a valid reference.
3558 In case the value was `null` before, it is converted to an object.
3559
3560 @param[in] key key of the element to access
3561
3562 @return reference to the element at key @a key
3563
3564 @throw std::domain_error if JSON is not an object or null; example:
3565 `"cannot use operator[] with string"`
3566
3567 @complexity Logarithmic in the size of the container.
3568
3569 @liveexample{The example below shows how object elements can be read and
3570 written using the `[]` operator.,operatorarray__key_type}
3571
3572 @sa @ref at(const typename object_t::key_type&) for access by reference
3573 with range checking
3574 @sa @ref value() for access by value with a default value
3575
3576 @since version 1.1.0
3577 */
3578 template<typename T>
operator [](T * key)3579 reference operator[](T* key)
3580 {
3581 // implicitly convert null to object
3582 if (is_null())
3583 {
3584 m_type = value_t::object;
3585 m_value = value_t::object;
3586 assert_invariant();
3587 }
3588
3589 // at only works for objects
3590 if (is_object())
3591 {
3592 return m_value.object->operator[](key);
3593 }
3594 else
3595 {
3596 throw std::domain_error("cannot use operator[] with " + type_name());
3597 }
3598 }
3599
3600 /*!
3601 @brief read-only access specified object element
3602
3603 Returns a const reference to the element at with specified key @a key. No
3604 bounds checking is performed.
3605
3606 @warning If the element with key @a key does not exist, the behavior is
3607 undefined.
3608
3609 @param[in] key key of the element to access
3610
3611 @return const reference to the element at key @a key
3612
3613 @pre The element with key @a key must exist. **This precondition is
3614 enforced with an assertion.**
3615
3616 @throw std::domain_error if JSON is not an object; example: `"cannot use
3617 operator[] with null"`
3618
3619 @complexity Logarithmic in the size of the container.
3620
3621 @liveexample{The example below shows how object elements can be read using
3622 the `[]` operator.,operatorarray__key_type_const}
3623
3624 @sa @ref at(const typename object_t::key_type&) for access by reference
3625 with range checking
3626 @sa @ref value() for access by value with a default value
3627
3628 @since version 1.1.0
3629 */
3630 template<typename T>
operator [](T * key) const3631 const_reference operator[](T* key) const
3632 {
3633 // at only works for objects
3634 if (is_object())
3635 {
3636 assert(m_value.object->find(key) != m_value.object->end());
3637 return m_value.object->find(key)->second;
3638 }
3639 else
3640 {
3641 throw std::domain_error("cannot use operator[] with " + type_name());
3642 }
3643 }
3644
3645 /*!
3646 @brief access specified object element with default value
3647
3648 Returns either a copy of an object's element at the specified key @a key
3649 or a given default value if no element with key @a key exists.
3650
3651 The function is basically equivalent to executing
3652 @code {.cpp}
3653 try {
3654 return at(key);
3655 } catch(std::out_of_range) {
3656 return default_value;
3657 }
3658 @endcode
3659
3660 @note Unlike @ref at(const typename object_t::key_type&), this function
3661 does not throw if the given key @a key was not found.
3662
3663 @note Unlike @ref operator[](const typename object_t::key_type& key), this
3664 function does not implicitly add an element to the position defined by @a
3665 key. This function is furthermore also applicable to const objects.
3666
3667 @param[in] key key of the element to access
3668 @param[in] default_value the value to return if @a key is not found
3669
3670 @tparam ValueType type compatible to JSON values, for instance `int` for
3671 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
3672 JSON arrays. Note the type of the expected value at @a key and the default
3673 value @a default_value must be compatible.
3674
3675 @return copy of the element at key @a key or @a default_value if @a key
3676 is not found
3677
3678 @throw std::domain_error if JSON is not an object; example: `"cannot use
3679 value() with null"`
3680
3681 @complexity Logarithmic in the size of the container.
3682
3683 @liveexample{The example below shows how object elements can be queried
3684 with a default value.,basic_json__value}
3685
3686 @sa @ref at(const typename object_t::key_type&) for access by reference
3687 with range checking
3688 @sa @ref operator[](const typename object_t::key_type&) for unchecked
3689 access by reference
3690
3691 @since version 1.0.0
3692 */
3693 template<class ValueType, typename std::enable_if<
3694 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
3695 ValueType value(const typename object_t::key_type& key, ValueType default_value) const
3696 {
3697 // at only works for objects
3698 if (is_object())
3699 {
3700 // if key is found, return value and given default value otherwise
3701 const auto it = find(key);
3702 if (it != end())
3703 {
3704 return *it;
3705 }
3706 else
3707 {
3708 return default_value;
3709 }
3710 }
3711 else
3712 {
3713 throw std::domain_error("cannot use value() with " + type_name());
3714 }
3715 }
3716
3717 /*!
3718 @brief overload for a default value of type const char*
3719 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
3720 */
value(const typename object_t::key_type & key,const char * default_value) const3721 string_t value(const typename object_t::key_type& key, const char* default_value) const
3722 {
3723 return value(key, string_t(default_value));
3724 }
3725
3726 /*!
3727 @brief access specified object element via JSON Pointer with default value
3728
3729 Returns either a copy of an object's element at the specified key @a key
3730 or a given default value if no element with key @a key exists.
3731
3732 The function is basically equivalent to executing
3733 @code {.cpp}
3734 try {
3735 return at(ptr);
3736 } catch(std::out_of_range) {
3737 return default_value;
3738 }
3739 @endcode
3740
3741 @note Unlike @ref at(const json_pointer&), this function does not throw
3742 if the given key @a key was not found.
3743
3744 @param[in] ptr a JSON pointer to the element to access
3745 @param[in] default_value the value to return if @a ptr found no value
3746
3747 @tparam ValueType type compatible to JSON values, for instance `int` for
3748 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
3749 JSON arrays. Note the type of the expected value at @a key and the default
3750 value @a default_value must be compatible.
3751
3752 @return copy of the element at key @a key or @a default_value if @a key
3753 is not found
3754
3755 @throw std::domain_error if JSON is not an object; example: `"cannot use
3756 value() with null"`
3757
3758 @complexity Logarithmic in the size of the container.
3759
3760 @liveexample{The example below shows how object elements can be queried
3761 with a default value.,basic_json__value_ptr}
3762
3763 @sa @ref operator[](const json_pointer&) for unchecked access by reference
3764
3765 @since version 2.0.2
3766 */
3767 template<class ValueType, typename std::enable_if<
3768 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
3769 ValueType value(const json_pointer& ptr, ValueType default_value) const
3770 {
3771 // at only works for objects
3772 if (is_object())
3773 {
3774 // if pointer resolves a value, return it or use default value
3775 try
3776 {
3777 return ptr.get_checked(this);
3778 }
3779 catch (std::out_of_range&)
3780 {
3781 return default_value;
3782 }
3783 }
3784 else
3785 {
3786 throw std::domain_error("cannot use value() with " + type_name());
3787 }
3788 }
3789
3790 /*!
3791 @brief overload for a default value of type const char*
3792 @copydoc basic_json::value(const json_pointer&, ValueType) const
3793 */
value(const json_pointer & ptr,const char * default_value) const3794 string_t value(const json_pointer& ptr, const char* default_value) const
3795 {
3796 return value(ptr, string_t(default_value));
3797 }
3798
3799 /*!
3800 @brief access the first element
3801
3802 Returns a reference to the first element in the container. For a JSON
3803 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
3804
3805 @return In case of a structured type (array or object), a reference to the
3806 first element is returned. In cast of number, string, or boolean values, a
3807 reference to the value is returned.
3808
3809 @complexity Constant.
3810
3811 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
3812 or an empty array or object (undefined behavior, **guarded by
3813 assertions**).
3814 @post The JSON value remains unchanged.
3815
3816 @throw std::out_of_range when called on `null` value
3817
3818 @liveexample{The following code shows an example for `front()`.,front}
3819
3820 @sa @ref back() -- access the last element
3821
3822 @since version 1.0.0
3823 */
front()3824 reference front()
3825 {
3826 return *begin();
3827 }
3828
3829 /*!
3830 @copydoc basic_json::front()
3831 */
front() const3832 const_reference front() const
3833 {
3834 return *cbegin();
3835 }
3836
3837 /*!
3838 @brief access the last element
3839
3840 Returns a reference to the last element in the container. For a JSON
3841 container `c`, the expression `c.back()` is equivalent to
3842 @code {.cpp}
3843 auto tmp = c.end();
3844 --tmp;
3845 return *tmp;
3846 @endcode
3847
3848 @return In case of a structured type (array or object), a reference to the
3849 last element is returned. In cast of number, string, or boolean values, a
3850 reference to the value is returned.
3851
3852 @complexity Constant.
3853
3854 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
3855 or an empty array or object (undefined behavior, **guarded by
3856 assertions**).
3857 @post The JSON value remains unchanged.
3858
3859 @throw std::out_of_range when called on `null` value.
3860
3861 @liveexample{The following code shows an example for `back()`.,back}
3862
3863 @sa @ref front() -- access the first element
3864
3865 @since version 1.0.0
3866 */
back()3867 reference back()
3868 {
3869 auto tmp = end();
3870 --tmp;
3871 return *tmp;
3872 }
3873
3874 /*!
3875 @copydoc basic_json::back()
3876 */
back() const3877 const_reference back() const
3878 {
3879 auto tmp = cend();
3880 --tmp;
3881 return *tmp;
3882 }
3883
3884 /*!
3885 @brief remove element given an iterator
3886
3887 Removes the element specified by iterator @a pos. The iterator @a pos must
3888 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
3889 but is not dereferenceable) cannot be used as a value for @a pos.
3890
3891 If called on a primitive type other than `null`, the resulting JSON value
3892 will be `null`.
3893
3894 @param[in] pos iterator to the element to remove
3895 @return Iterator following the last removed element. If the iterator @a
3896 pos refers to the last element, the `end()` iterator is returned.
3897
3898 @tparam IteratorType an @ref iterator or @ref const_iterator
3899
3900 @post Invalidates iterators and references at or after the point of the
3901 erase, including the `end()` iterator.
3902
3903 @throw std::domain_error if called on a `null` value; example: `"cannot
3904 use erase() with null"`
3905 @throw std::domain_error if called on an iterator which does not belong to
3906 the current JSON value; example: `"iterator does not fit current value"`
3907 @throw std::out_of_range if called on a primitive type with invalid
3908 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
3909 out of range"`
3910
3911 @complexity The complexity depends on the type:
3912 - objects: amortized constant
3913 - arrays: linear in distance between pos and the end of the container
3914 - strings: linear in the length of the string
3915 - other types: constant
3916
3917 @liveexample{The example shows the result of `erase()` for different JSON
3918 types.,erase__IteratorType}
3919
3920 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
3921 the given range
3922 @sa @ref erase(const typename object_t::key_type&) -- removes the element
3923 from an object at the given key
3924 @sa @ref erase(const size_type) -- removes the element from an array at
3925 the given index
3926
3927 @since version 1.0.0
3928 */
3929 template<class IteratorType, typename std::enable_if<
3930 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
3931 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
3932 = 0>
3933 IteratorType erase(IteratorType pos)
3934 {
3935 // make sure iterator fits the current value
3936 if (this != pos.m_object)
3937 {
3938 throw std::domain_error("iterator does not fit current value");
3939 }
3940
3941 IteratorType result = end();
3942
3943 switch (m_type)
3944 {
3945 case value_t::boolean:
3946 case value_t::number_float:
3947 case value_t::number_integer:
3948 case value_t::number_unsigned:
3949 case value_t::string:
3950 {
3951 if (not pos.m_it.primitive_iterator.is_begin())
3952 {
3953 throw std::out_of_range("iterator out of range");
3954 }
3955
3956 if (is_string())
3957 {
3958 AllocatorType<string_t> alloc;
3959 alloc.destroy(m_value.string);
3960 alloc.deallocate(m_value.string, 1);
3961 m_value.string = nullptr;
3962 }
3963
3964 m_type = value_t::null;
3965 assert_invariant();
3966 break;
3967 }
3968
3969 case value_t::object:
3970 {
3971 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3972 break;
3973 }
3974
3975 case value_t::array:
3976 {
3977 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3978 break;
3979 }
3980
3981 default:
3982 {
3983 throw std::domain_error("cannot use erase() with " + type_name());
3984 }
3985 }
3986
3987 return result;
3988 }
3989
3990 /*!
3991 @brief remove elements given an iterator range
3992
3993 Removes the element specified by the range `[first; last)`. The iterator
3994 @a first does not need to be dereferenceable if `first == last`: erasing
3995 an empty range is a no-op.
3996
3997 If called on a primitive type other than `null`, the resulting JSON value
3998 will be `null`.
3999
4000 @param[in] first iterator to the beginning of the range to remove
4001 @param[in] last iterator past the end of the range to remove
4002 @return Iterator following the last removed element. If the iterator @a
4003 second refers to the last element, the `end()` iterator is returned.
4004
4005 @tparam IteratorType an @ref iterator or @ref const_iterator
4006
4007 @post Invalidates iterators and references at or after the point of the
4008 erase, including the `end()` iterator.
4009
4010 @throw std::domain_error if called on a `null` value; example: `"cannot
4011 use erase() with null"`
4012 @throw std::domain_error if called on iterators which does not belong to
4013 the current JSON value; example: `"iterators do not fit current value"`
4014 @throw std::out_of_range if called on a primitive type with invalid
4015 iterators (i.e., if `first != begin()` and `last != end()`); example:
4016 `"iterators out of range"`
4017
4018 @complexity The complexity depends on the type:
4019 - objects: `log(size()) + std::distance(first, last)`
4020 - arrays: linear in the distance between @a first and @a last, plus linear
4021 in the distance between @a last and end of the container
4022 - strings: linear in the length of the string
4023 - other types: constant
4024
4025 @liveexample{The example shows the result of `erase()` for different JSON
4026 types.,erase__IteratorType_IteratorType}
4027
4028 @sa @ref erase(IteratorType) -- removes the element at a given position
4029 @sa @ref erase(const typename object_t::key_type&) -- removes the element
4030 from an object at the given key
4031 @sa @ref erase(const size_type) -- removes the element from an array at
4032 the given index
4033
4034 @since version 1.0.0
4035 */
4036 template<class IteratorType, typename std::enable_if<
4037 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4038 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4039 = 0>
4040 IteratorType erase(IteratorType first, IteratorType last)
4041 {
4042 // make sure iterator fits the current value
4043 if (this != first.m_object or this != last.m_object)
4044 {
4045 throw std::domain_error("iterators do not fit current value");
4046 }
4047
4048 IteratorType result = end();
4049
4050 switch (m_type)
4051 {
4052 case value_t::boolean:
4053 case value_t::number_float:
4054 case value_t::number_integer:
4055 case value_t::number_unsigned:
4056 case value_t::string:
4057 {
4058 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4059 {
4060 throw std::out_of_range("iterators out of range");
4061 }
4062
4063 if (is_string())
4064 {
4065 AllocatorType<string_t> alloc;
4066 alloc.destroy(m_value.string);
4067 alloc.deallocate(m_value.string, 1);
4068 m_value.string = nullptr;
4069 }
4070
4071 m_type = value_t::null;
4072 assert_invariant();
4073 break;
4074 }
4075
4076 case value_t::object:
4077 {
4078 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4079 last.m_it.object_iterator);
4080 break;
4081 }
4082
4083 case value_t::array:
4084 {
4085 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4086 last.m_it.array_iterator);
4087 break;
4088 }
4089
4090 default:
4091 {
4092 throw std::domain_error("cannot use erase() with " + type_name());
4093 }
4094 }
4095
4096 return result;
4097 }
4098
4099 /*!
4100 @brief remove element from a JSON object given a key
4101
4102 Removes elements from a JSON object with the key value @a key.
4103
4104 @param[in] key value of the elements to remove
4105
4106 @return Number of elements removed. If @a ObjectType is the default
4107 `std::map` type, the return value will always be `0` (@a key was not
4108 found) or `1` (@a key was found).
4109
4110 @post References and iterators to the erased elements are invalidated.
4111 Other references and iterators are not affected.
4112
4113 @throw std::domain_error when called on a type other than JSON object;
4114 example: `"cannot use erase() with null"`
4115
4116 @complexity `log(size()) + count(key)`
4117
4118 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
4119
4120 @sa @ref erase(IteratorType) -- removes the element at a given position
4121 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
4122 the given range
4123 @sa @ref erase(const size_type) -- removes the element from an array at
4124 the given index
4125
4126 @since version 1.0.0
4127 */
erase(const typename object_t::key_type & key)4128 size_type erase(const typename object_t::key_type& key)
4129 {
4130 // this erase only works for objects
4131 if (is_object())
4132 {
4133 return m_value.object->erase(key);
4134 }
4135 else
4136 {
4137 throw std::domain_error("cannot use erase() with " + type_name());
4138 }
4139 }
4140
4141 /*!
4142 @brief remove element from a JSON array given an index
4143
4144 Removes element from a JSON array at the index @a idx.
4145
4146 @param[in] idx index of the element to remove
4147
4148 @throw std::domain_error when called on a type other than JSON array;
4149 example: `"cannot use erase() with null"`
4150 @throw std::out_of_range when `idx >= size()`; example: `"array index 17
4151 is out of range"`
4152
4153 @complexity Linear in distance between @a idx and the end of the container.
4154
4155 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
4156
4157 @sa @ref erase(IteratorType) -- removes the element at a given position
4158 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
4159 the given range
4160 @sa @ref erase(const typename object_t::key_type&) -- removes the element
4161 from an object at the given key
4162
4163 @since version 1.0.0
4164 */
erase(const size_type idx)4165 void erase(const size_type idx)
4166 {
4167 // this erase only works for arrays
4168 if (is_array())
4169 {
4170 if (idx >= size())
4171 {
4172 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
4173 }
4174
4175 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4176 }
4177 else
4178 {
4179 throw std::domain_error("cannot use erase() with " + type_name());
4180 }
4181 }
4182
4183 /// @}
4184
4185
4186 ////////////
4187 // lookup //
4188 ////////////
4189
4190 /// @name lookup
4191 /// @{
4192
4193 /*!
4194 @brief find an element in a JSON object
4195
4196 Finds an element in a JSON object with key equivalent to @a key. If the
4197 element is not found or the JSON value is not an object, end() is
4198 returned.
4199
4200 @param[in] key key value of the element to search for
4201
4202 @return Iterator to an element with key equivalent to @a key. If no such
4203 element is found, past-the-end (see end()) iterator is returned.
4204
4205 @complexity Logarithmic in the size of the JSON object.
4206
4207 @liveexample{The example shows how `find()` is used.,find__key_type}
4208
4209 @since version 1.0.0
4210 */
find(typename object_t::key_type key)4211 iterator find(typename object_t::key_type key)
4212 {
4213 auto result = end();
4214
4215 if (is_object())
4216 {
4217 result.m_it.object_iterator = m_value.object->find(key);
4218 }
4219
4220 return result;
4221 }
4222
4223 /*!
4224 @brief find an element in a JSON object
4225 @copydoc find(typename object_t::key_type)
4226 */
find(typename object_t::key_type key) const4227 const_iterator find(typename object_t::key_type key) const
4228 {
4229 auto result = cend();
4230
4231 if (is_object())
4232 {
4233 result.m_it.object_iterator = m_value.object->find(key);
4234 }
4235
4236 return result;
4237 }
4238
4239 /*!
4240 @brief returns the number of occurrences of a key in a JSON object
4241
4242 Returns the number of elements with key @a key. If ObjectType is the
4243 default `std::map` type, the return value will always be `0` (@a key was
4244 not found) or `1` (@a key was found).
4245
4246 @param[in] key key value of the element to count
4247
4248 @return Number of elements with key @a key. If the JSON value is not an
4249 object, the return value will be `0`.
4250
4251 @complexity Logarithmic in the size of the JSON object.
4252
4253 @liveexample{The example shows how `count()` is used.,count}
4254
4255 @since version 1.0.0
4256 */
count(typename object_t::key_type key) const4257 size_type count(typename object_t::key_type key) const
4258 {
4259 // return 0 for all nonobject types
4260 return is_object() ? m_value.object->count(key) : 0;
4261 }
4262
4263 /// @}
4264
4265
4266 ///////////////
4267 // iterators //
4268 ///////////////
4269
4270 /// @name iterators
4271 /// @{
4272
4273 /*!
4274 @brief returns an iterator to the first element
4275
4276 Returns an iterator to the first element.
4277
4278 @image html range-begin-end.svg "Illustration from cppreference.com"
4279
4280 @return iterator to the first element
4281
4282 @complexity Constant.
4283
4284 @requirement This function helps `basic_json` satisfying the
4285 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4286 requirements:
4287 - The complexity is constant.
4288
4289 @liveexample{The following code shows an example for `begin()`.,begin}
4290
4291 @sa @ref cbegin() -- returns a const iterator to the beginning
4292 @sa @ref end() -- returns an iterator to the end
4293 @sa @ref cend() -- returns a const iterator to the end
4294
4295 @since version 1.0.0
4296 */
begin()4297 iterator begin() noexcept
4298 {
4299 iterator result(this);
4300 result.set_begin();
4301 return result;
4302 }
4303
4304 /*!
4305 @copydoc basic_json::cbegin()
4306 */
begin() const4307 const_iterator begin() const noexcept
4308 {
4309 return cbegin();
4310 }
4311
4312 /*!
4313 @brief returns a const iterator to the first element
4314
4315 Returns a const iterator to the first element.
4316
4317 @image html range-begin-end.svg "Illustration from cppreference.com"
4318
4319 @return const iterator to the first element
4320
4321 @complexity Constant.
4322
4323 @requirement This function helps `basic_json` satisfying the
4324 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4325 requirements:
4326 - The complexity is constant.
4327 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
4328
4329 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
4330
4331 @sa @ref begin() -- returns an iterator to the beginning
4332 @sa @ref end() -- returns an iterator to the end
4333 @sa @ref cend() -- returns a const iterator to the end
4334
4335 @since version 1.0.0
4336 */
cbegin() const4337 const_iterator cbegin() const noexcept
4338 {
4339 const_iterator result(this);
4340 result.set_begin();
4341 return result;
4342 }
4343
4344 /*!
4345 @brief returns an iterator to one past the last element
4346
4347 Returns an iterator to one past the last element.
4348
4349 @image html range-begin-end.svg "Illustration from cppreference.com"
4350
4351 @return iterator one past the last element
4352
4353 @complexity Constant.
4354
4355 @requirement This function helps `basic_json` satisfying the
4356 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4357 requirements:
4358 - The complexity is constant.
4359
4360 @liveexample{The following code shows an example for `end()`.,end}
4361
4362 @sa @ref cend() -- returns a const iterator to the end
4363 @sa @ref begin() -- returns an iterator to the beginning
4364 @sa @ref cbegin() -- returns a const iterator to the beginning
4365
4366 @since version 1.0.0
4367 */
end()4368 iterator end() noexcept
4369 {
4370 iterator result(this);
4371 result.set_end();
4372 return result;
4373 }
4374
4375 /*!
4376 @copydoc basic_json::cend()
4377 */
end() const4378 const_iterator end() const noexcept
4379 {
4380 return cend();
4381 }
4382
4383 /*!
4384 @brief returns a const iterator to one past the last element
4385
4386 Returns a const iterator to one past the last element.
4387
4388 @image html range-begin-end.svg "Illustration from cppreference.com"
4389
4390 @return const iterator one past the last element
4391
4392 @complexity Constant.
4393
4394 @requirement This function helps `basic_json` satisfying the
4395 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4396 requirements:
4397 - The complexity is constant.
4398 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
4399
4400 @liveexample{The following code shows an example for `cend()`.,cend}
4401
4402 @sa @ref end() -- returns an iterator to the end
4403 @sa @ref begin() -- returns an iterator to the beginning
4404 @sa @ref cbegin() -- returns a const iterator to the beginning
4405
4406 @since version 1.0.0
4407 */
cend() const4408 const_iterator cend() const noexcept
4409 {
4410 const_iterator result(this);
4411 result.set_end();
4412 return result;
4413 }
4414
4415 /*!
4416 @brief returns an iterator to the reverse-beginning
4417
4418 Returns an iterator to the reverse-beginning; that is, the last element.
4419
4420 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4421
4422 @complexity Constant.
4423
4424 @requirement This function helps `basic_json` satisfying the
4425 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4426 requirements:
4427 - The complexity is constant.
4428 - Has the semantics of `reverse_iterator(end())`.
4429
4430 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
4431
4432 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4433 @sa @ref rend() -- returns a reverse iterator to the end
4434 @sa @ref crend() -- returns a const reverse iterator to the end
4435
4436 @since version 1.0.0
4437 */
rbegin()4438 reverse_iterator rbegin() noexcept
4439 {
4440 return reverse_iterator(end());
4441 }
4442
4443 /*!
4444 @copydoc basic_json::crbegin()
4445 */
rbegin() const4446 const_reverse_iterator rbegin() const noexcept
4447 {
4448 return crbegin();
4449 }
4450
4451 /*!
4452 @brief returns an iterator to the reverse-end
4453
4454 Returns an iterator to the reverse-end; that is, one before the first
4455 element.
4456
4457 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4458
4459 @complexity Constant.
4460
4461 @requirement This function helps `basic_json` satisfying the
4462 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4463 requirements:
4464 - The complexity is constant.
4465 - Has the semantics of `reverse_iterator(begin())`.
4466
4467 @liveexample{The following code shows an example for `rend()`.,rend}
4468
4469 @sa @ref crend() -- returns a const reverse iterator to the end
4470 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4471 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4472
4473 @since version 1.0.0
4474 */
rend()4475 reverse_iterator rend() noexcept
4476 {
4477 return reverse_iterator(begin());
4478 }
4479
4480 /*!
4481 @copydoc basic_json::crend()
4482 */
rend() const4483 const_reverse_iterator rend() const noexcept
4484 {
4485 return crend();
4486 }
4487
4488 /*!
4489 @brief returns a const reverse iterator to the last element
4490
4491 Returns a const iterator to the reverse-beginning; that is, the last
4492 element.
4493
4494 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4495
4496 @complexity Constant.
4497
4498 @requirement This function helps `basic_json` satisfying the
4499 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4500 requirements:
4501 - The complexity is constant.
4502 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
4503
4504 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
4505
4506 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4507 @sa @ref rend() -- returns a reverse iterator to the end
4508 @sa @ref crend() -- returns a const reverse iterator to the end
4509
4510 @since version 1.0.0
4511 */
crbegin() const4512 const_reverse_iterator crbegin() const noexcept
4513 {
4514 return const_reverse_iterator(cend());
4515 }
4516
4517 /*!
4518 @brief returns a const reverse iterator to one before the first
4519
4520 Returns a const reverse iterator to the reverse-end; that is, one before
4521 the first element.
4522
4523 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4524
4525 @complexity Constant.
4526
4527 @requirement This function helps `basic_json` satisfying the
4528 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4529 requirements:
4530 - The complexity is constant.
4531 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
4532
4533 @liveexample{The following code shows an example for `crend()`.,crend}
4534
4535 @sa @ref rend() -- returns a reverse iterator to the end
4536 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4537 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4538
4539 @since version 1.0.0
4540 */
crend() const4541 const_reverse_iterator crend() const noexcept
4542 {
4543 return const_reverse_iterator(cbegin());
4544 }
4545
4546 private:
4547 // forward declaration
4548 template<typename IteratorType> class iteration_proxy;
4549
4550 public:
4551 /*!
4552 @brief wrapper to access iterator member functions in range-based for
4553
4554 This function allows to access @ref iterator::key() and @ref
4555 iterator::value() during range-based for loops. In these loops, a
4556 reference to the JSON values is returned, so there is no access to the
4557 underlying iterator.
4558
4559 @note The name of this function is not yet final and may change in the
4560 future.
4561 */
iterator_wrapper(reference cont)4562 static iteration_proxy<iterator> iterator_wrapper(reference cont)
4563 {
4564 return iteration_proxy<iterator>(cont);
4565 }
4566
4567 /*!
4568 @copydoc iterator_wrapper(reference)
4569 */
iterator_wrapper(const_reference cont)4570 static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
4571 {
4572 return iteration_proxy<const_iterator>(cont);
4573 }
4574
4575 /// @}
4576
4577
4578 //////////////
4579 // capacity //
4580 //////////////
4581
4582 /// @name capacity
4583 /// @{
4584
4585 /*!
4586 @brief checks whether the container is empty
4587
4588 Checks if a JSON value has no elements.
4589
4590 @return The return value depends on the different types and is
4591 defined as follows:
4592 Value type | return value
4593 ----------- | -------------
4594 null | `true`
4595 boolean | `false`
4596 string | `false`
4597 number | `false`
4598 object | result of function `object_t::empty()`
4599 array | result of function `array_t::empty()`
4600
4601 @note This function does not return whether a string stored as JSON value
4602 is empty - it returns whether the JSON container itself is empty which is
4603 false in the case of a string.
4604
4605 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
4606 the Container concept; that is, their `empty()` functions have constant
4607 complexity.
4608
4609 @requirement This function helps `basic_json` satisfying the
4610 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4611 requirements:
4612 - The complexity is constant.
4613 - Has the semantics of `begin() == end()`.
4614
4615 @liveexample{The following code uses `empty()` to check if a JSON
4616 object contains any elements.,empty}
4617
4618 @sa @ref size() -- returns the number of elements
4619
4620 @since version 1.0.0
4621 */
empty() const4622 bool empty() const noexcept
4623 {
4624 switch (m_type)
4625 {
4626 case value_t::null:
4627 {
4628 // null values are empty
4629 return true;
4630 }
4631
4632 case value_t::array:
4633 {
4634 // delegate call to array_t::empty()
4635 return m_value.array->empty();
4636 }
4637
4638 case value_t::object:
4639 {
4640 // delegate call to object_t::empty()
4641 return m_value.object->empty();
4642 }
4643
4644 default:
4645 {
4646 // all other types are nonempty
4647 return false;
4648 }
4649 }
4650 }
4651
4652 /*!
4653 @brief returns the number of elements
4654
4655 Returns the number of elements in a JSON value.
4656
4657 @return The return value depends on the different types and is
4658 defined as follows:
4659 Value type | return value
4660 ----------- | -------------
4661 null | `0`
4662 boolean | `1`
4663 string | `1`
4664 number | `1`
4665 object | result of function object_t::size()
4666 array | result of function array_t::size()
4667
4668 @note This function does not return the length of a string stored as JSON
4669 value - it returns the number of elements in the JSON value which is 1 in
4670 the case of a string.
4671
4672 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
4673 the Container concept; that is, their size() functions have constant
4674 complexity.
4675
4676 @requirement This function helps `basic_json` satisfying the
4677 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4678 requirements:
4679 - The complexity is constant.
4680 - Has the semantics of `std::distance(begin(), end())`.
4681
4682 @liveexample{The following code calls `size()` on the different value
4683 types.,size}
4684
4685 @sa @ref empty() -- checks whether the container is empty
4686 @sa @ref max_size() -- returns the maximal number of elements
4687
4688 @since version 1.0.0
4689 */
size() const4690 size_type size() const noexcept
4691 {
4692 switch (m_type)
4693 {
4694 case value_t::null:
4695 {
4696 // null values are empty
4697 return 0;
4698 }
4699
4700 case value_t::array:
4701 {
4702 // delegate call to array_t::size()
4703 return m_value.array->size();
4704 }
4705
4706 case value_t::object:
4707 {
4708 // delegate call to object_t::size()
4709 return m_value.object->size();
4710 }
4711
4712 default:
4713 {
4714 // all other types have size 1
4715 return 1;
4716 }
4717 }
4718 }
4719
4720 /*!
4721 @brief returns the maximum possible number of elements
4722
4723 Returns the maximum number of elements a JSON value is able to hold due to
4724 system or library implementation limitations, i.e. `std::distance(begin(),
4725 end())` for the JSON value.
4726
4727 @return The return value depends on the different types and is
4728 defined as follows:
4729 Value type | return value
4730 ----------- | -------------
4731 null | `0` (same as `size()`)
4732 boolean | `1` (same as `size()`)
4733 string | `1` (same as `size()`)
4734 number | `1` (same as `size()`)
4735 object | result of function `object_t::max_size()`
4736 array | result of function `array_t::max_size()`
4737
4738 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
4739 the Container concept; that is, their `max_size()` functions have constant
4740 complexity.
4741
4742 @requirement This function helps `basic_json` satisfying the
4743 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4744 requirements:
4745 - The complexity is constant.
4746 - Has the semantics of returning `b.size()` where `b` is the largest
4747 possible JSON value.
4748
4749 @liveexample{The following code calls `max_size()` on the different value
4750 types. Note the output is implementation specific.,max_size}
4751
4752 @sa @ref size() -- returns the number of elements
4753
4754 @since version 1.0.0
4755 */
max_size() const4756 size_type max_size() const noexcept
4757 {
4758 switch (m_type)
4759 {
4760 case value_t::array:
4761 {
4762 // delegate call to array_t::max_size()
4763 return m_value.array->max_size();
4764 }
4765
4766 case value_t::object:
4767 {
4768 // delegate call to object_t::max_size()
4769 return m_value.object->max_size();
4770 }
4771
4772 default:
4773 {
4774 // all other types have max_size() == size()
4775 return size();
4776 }
4777 }
4778 }
4779
4780 /// @}
4781
4782
4783 ///////////////
4784 // modifiers //
4785 ///////////////
4786
4787 /// @name modifiers
4788 /// @{
4789
4790 /*!
4791 @brief clears the contents
4792
4793 Clears the content of a JSON value and resets it to the default value as
4794 if @ref basic_json(value_t) would have been called:
4795
4796 Value type | initial value
4797 ----------- | -------------
4798 null | `null`
4799 boolean | `false`
4800 string | `""`
4801 number | `0`
4802 object | `{}`
4803 array | `[]`
4804
4805 @note Floating-point numbers are set to `0.0` which will be serialized to
4806 `0`. The vale type remains @ref number_float_t.
4807
4808 @complexity Linear in the size of the JSON value.
4809
4810 @liveexample{The example below shows the effect of `clear()` to different
4811 JSON types.,clear}
4812
4813 @since version 1.0.0
4814 */
clear()4815 void clear() noexcept
4816 {
4817 switch (m_type)
4818 {
4819 case value_t::number_integer:
4820 {
4821 m_value.number_integer = 0;
4822 break;
4823 }
4824
4825 case value_t::number_unsigned:
4826 {
4827 m_value.number_unsigned = 0;
4828 break;
4829 }
4830
4831 case value_t::number_float:
4832 {
4833 m_value.number_float = 0.0;
4834 break;
4835 }
4836
4837 case value_t::boolean:
4838 {
4839 m_value.boolean = false;
4840 break;
4841 }
4842
4843 case value_t::string:
4844 {
4845 m_value.string->clear();
4846 break;
4847 }
4848
4849 case value_t::array:
4850 {
4851 m_value.array->clear();
4852 break;
4853 }
4854
4855 case value_t::object:
4856 {
4857 m_value.object->clear();
4858 break;
4859 }
4860
4861 default:
4862 {
4863 break;
4864 }
4865 }
4866 }
4867
4868 /*!
4869 @brief add an object to an array
4870
4871 Appends the given element @a val to the end of the JSON value. If the
4872 function is called on a JSON null value, an empty array is created before
4873 appending @a val.
4874
4875 @param[in] val the value to add to the JSON array
4876
4877 @throw std::domain_error when called on a type other than JSON array or
4878 null; example: `"cannot use push_back() with number"`
4879
4880 @complexity Amortized constant.
4881
4882 @liveexample{The example shows how `push_back()` and `+=` can be used to
4883 add elements to a JSON array. Note how the `null` value was silently
4884 converted to a JSON array.,push_back}
4885
4886 @since version 1.0.0
4887 */
push_back(basic_json && val)4888 void push_back(basic_json&& val)
4889 {
4890 // push_back only works for null objects or arrays
4891 if (not(is_null() or is_array()))
4892 {
4893 throw std::domain_error("cannot use push_back() with " + type_name());
4894 }
4895
4896 // transform null object into an array
4897 if (is_null())
4898 {
4899 m_type = value_t::array;
4900 m_value = value_t::array;
4901 assert_invariant();
4902 }
4903
4904 // add element to array (move semantics)
4905 m_value.array->push_back(std::move(val));
4906 // invalidate object
4907 val.m_type = value_t::null;
4908 }
4909
4910 /*!
4911 @brief add an object to an array
4912 @copydoc push_back(basic_json&&)
4913 */
operator +=(basic_json && val)4914 reference operator+=(basic_json&& val)
4915 {
4916 push_back(std::move(val));
4917 return *this;
4918 }
4919
4920 /*!
4921 @brief add an object to an array
4922 @copydoc push_back(basic_json&&)
4923 */
push_back(const basic_json & val)4924 void push_back(const basic_json& val)
4925 {
4926 // push_back only works for null objects or arrays
4927 if (not(is_null() or is_array()))
4928 {
4929 throw std::domain_error("cannot use push_back() with " + type_name());
4930 }
4931
4932 // transform null object into an array
4933 if (is_null())
4934 {
4935 m_type = value_t::array;
4936 m_value = value_t::array;
4937 assert_invariant();
4938 }
4939
4940 // add element to array
4941 m_value.array->push_back(val);
4942 }
4943
4944 /*!
4945 @brief add an object to an array
4946 @copydoc push_back(basic_json&&)
4947 */
operator +=(const basic_json & val)4948 reference operator+=(const basic_json& val)
4949 {
4950 push_back(val);
4951 return *this;
4952 }
4953
4954 /*!
4955 @brief add an object to an object
4956
4957 Inserts the given element @a val to the JSON object. If the function is
4958 called on a JSON null value, an empty object is created before inserting
4959 @a val.
4960
4961 @param[in] val the value to add to the JSON object
4962
4963 @throw std::domain_error when called on a type other than JSON object or
4964 null; example: `"cannot use push_back() with number"`
4965
4966 @complexity Logarithmic in the size of the container, O(log(`size()`)).
4967
4968 @liveexample{The example shows how `push_back()` and `+=` can be used to
4969 add elements to a JSON object. Note how the `null` value was silently
4970 converted to a JSON object.,push_back__object_t__value}
4971
4972 @since version 1.0.0
4973 */
push_back(const typename object_t::value_type & val)4974 void push_back(const typename object_t::value_type& val)
4975 {
4976 // push_back only works for null objects or objects
4977 if (not(is_null() or is_object()))
4978 {
4979 throw std::domain_error("cannot use push_back() with " + type_name());
4980 }
4981
4982 // transform null object into an object
4983 if (is_null())
4984 {
4985 m_type = value_t::object;
4986 m_value = value_t::object;
4987 assert_invariant();
4988 }
4989
4990 // add element to array
4991 m_value.object->insert(val);
4992 }
4993
4994 /*!
4995 @brief add an object to an object
4996 @copydoc push_back(const typename object_t::value_type&)
4997 */
operator +=(const typename object_t::value_type & val)4998 reference operator+=(const typename object_t::value_type& val)
4999 {
5000 push_back(val);
5001 return *this;
5002 }
5003
5004 /*!
5005 @brief add an object to an object
5006
5007 This function allows to use `push_back` with an initializer list. In case
5008
5009 1. the current value is an object,
5010 2. the initializer list @a init contains only two elements, and
5011 3. the first element of @a init is a string,
5012
5013 @a init is converted into an object element and added using
5014 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
5015 is converted to a JSON value and added using @ref push_back(basic_json&&).
5016
5017 @param init an initializer list
5018
5019 @complexity Linear in the size of the initializer list @a init.
5020
5021 @note This function is required to resolve an ambiguous overload error,
5022 because pairs like `{"key", "value"}` can be both interpreted as
5023 `object_t::value_type` or `std::initializer_list<basic_json>`, see
5024 https://github.com/nlohmann/json/issues/235 for more information.
5025
5026 @liveexample{The example shows how initializer lists are treated as
5027 objects when possible.,push_back__initializer_list}
5028 */
push_back(std::initializer_list<basic_json> init)5029 void push_back(std::initializer_list<basic_json> init)
5030 {
5031 if (is_object() and init.size() == 2 and init.begin()->is_string())
5032 {
5033 const string_t key = *init.begin();
5034 push_back(typename object_t::value_type(key, *(init.begin() + 1)));
5035 }
5036 else
5037 {
5038 push_back(basic_json(init));
5039 }
5040 }
5041
5042 /*!
5043 @brief add an object to an object
5044 @copydoc push_back(std::initializer_list<basic_json>)
5045 */
operator +=(std::initializer_list<basic_json> init)5046 reference operator+=(std::initializer_list<basic_json> init)
5047 {
5048 push_back(init);
5049 return *this;
5050 }
5051
5052 /*!
5053 @brief inserts element
5054
5055 Inserts element @a val before iterator @a pos.
5056
5057 @param[in] pos iterator before which the content will be inserted; may be
5058 the end() iterator
5059 @param[in] val element to insert
5060 @return iterator pointing to the inserted @a val.
5061
5062 @throw std::domain_error if called on JSON values other than arrays;
5063 example: `"cannot use insert() with string"`
5064 @throw std::domain_error if @a pos is not an iterator of *this; example:
5065 `"iterator does not fit current value"`
5066
5067 @complexity Constant plus linear in the distance between pos and end of the
5068 container.
5069
5070 @liveexample{The example shows how `insert()` is used.,insert}
5071
5072 @since version 1.0.0
5073 */
insert(const_iterator pos,const basic_json & val)5074 iterator insert(const_iterator pos, const basic_json& val)
5075 {
5076 // insert only works for arrays
5077 if (is_array())
5078 {
5079 // check if iterator pos fits to this JSON value
5080 if (pos.m_object != this)
5081 {
5082 throw std::domain_error("iterator does not fit current value");
5083 }
5084
5085 // insert to array and return iterator
5086 iterator result(this);
5087 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5088 return result;
5089 }
5090 else
5091 {
5092 throw std::domain_error("cannot use insert() with " + type_name());
5093 }
5094 }
5095
5096 /*!
5097 @brief inserts element
5098 @copydoc insert(const_iterator, const basic_json&)
5099 */
insert(const_iterator pos,basic_json && val)5100 iterator insert(const_iterator pos, basic_json&& val)
5101 {
5102 return insert(pos, val);
5103 }
5104
5105 /*!
5106 @brief inserts elements
5107
5108 Inserts @a cnt copies of @a val before iterator @a pos.
5109
5110 @param[in] pos iterator before which the content will be inserted; may be
5111 the end() iterator
5112 @param[in] cnt number of copies of @a val to insert
5113 @param[in] val element to insert
5114 @return iterator pointing to the first element inserted, or @a pos if
5115 `cnt==0`
5116
5117 @throw std::domain_error if called on JSON values other than arrays;
5118 example: `"cannot use insert() with string"`
5119 @throw std::domain_error if @a pos is not an iterator of *this; example:
5120 `"iterator does not fit current value"`
5121
5122 @complexity Linear in @a cnt plus linear in the distance between @a pos
5123 and end of the container.
5124
5125 @liveexample{The example shows how `insert()` is used.,insert__count}
5126
5127 @since version 1.0.0
5128 */
insert(const_iterator pos,size_type cnt,const basic_json & val)5129 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
5130 {
5131 // insert only works for arrays
5132 if (is_array())
5133 {
5134 // check if iterator pos fits to this JSON value
5135 if (pos.m_object != this)
5136 {
5137 throw std::domain_error("iterator does not fit current value");
5138 }
5139
5140 // insert to array and return iterator
5141 iterator result(this);
5142 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5143 return result;
5144 }
5145 else
5146 {
5147 throw std::domain_error("cannot use insert() with " + type_name());
5148 }
5149 }
5150
5151 /*!
5152 @brief inserts elements
5153
5154 Inserts elements from range `[first, last)` before iterator @a pos.
5155
5156 @param[in] pos iterator before which the content will be inserted; may be
5157 the end() iterator
5158 @param[in] first begin of the range of elements to insert
5159 @param[in] last end of the range of elements to insert
5160
5161 @throw std::domain_error if called on JSON values other than arrays;
5162 example: `"cannot use insert() with string"`
5163 @throw std::domain_error if @a pos is not an iterator of *this; example:
5164 `"iterator does not fit current value"`
5165 @throw std::domain_error if @a first and @a last do not belong to the same
5166 JSON value; example: `"iterators do not fit"`
5167 @throw std::domain_error if @a first or @a last are iterators into
5168 container for which insert is called; example: `"passed iterators may not
5169 belong to container"`
5170
5171 @return iterator pointing to the first element inserted, or @a pos if
5172 `first==last`
5173
5174 @complexity Linear in `std::distance(first, last)` plus linear in the
5175 distance between @a pos and end of the container.
5176
5177 @liveexample{The example shows how `insert()` is used.,insert__range}
5178
5179 @since version 1.0.0
5180 */
insert(const_iterator pos,const_iterator first,const_iterator last)5181 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
5182 {
5183 // insert only works for arrays
5184 if (not is_array())
5185 {
5186 throw std::domain_error("cannot use insert() with " + type_name());
5187 }
5188
5189 // check if iterator pos fits to this JSON value
5190 if (pos.m_object != this)
5191 {
5192 throw std::domain_error("iterator does not fit current value");
5193 }
5194
5195 // check if range iterators belong to the same JSON object
5196 if (first.m_object != last.m_object)
5197 {
5198 throw std::domain_error("iterators do not fit");
5199 }
5200
5201 if (first.m_object == this or last.m_object == this)
5202 {
5203 throw std::domain_error("passed iterators may not belong to container");
5204 }
5205
5206 // insert to array and return iterator
5207 iterator result(this);
5208 result.m_it.array_iterator = m_value.array->insert(
5209 pos.m_it.array_iterator,
5210 first.m_it.array_iterator,
5211 last.m_it.array_iterator);
5212 return result;
5213 }
5214
5215 /*!
5216 @brief inserts elements
5217
5218 Inserts elements from initializer list @a ilist before iterator @a pos.
5219
5220 @param[in] pos iterator before which the content will be inserted; may be
5221 the end() iterator
5222 @param[in] ilist initializer list to insert the values from
5223
5224 @throw std::domain_error if called on JSON values other than arrays;
5225 example: `"cannot use insert() with string"`
5226 @throw std::domain_error if @a pos is not an iterator of *this; example:
5227 `"iterator does not fit current value"`
5228
5229 @return iterator pointing to the first element inserted, or @a pos if
5230 `ilist` is empty
5231
5232 @complexity Linear in `ilist.size()` plus linear in the distance between
5233 @a pos and end of the container.
5234
5235 @liveexample{The example shows how `insert()` is used.,insert__ilist}
5236
5237 @since version 1.0.0
5238 */
insert(const_iterator pos,std::initializer_list<basic_json> ilist)5239 iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
5240 {
5241 // insert only works for arrays
5242 if (not is_array())
5243 {
5244 throw std::domain_error("cannot use insert() with " + type_name());
5245 }
5246
5247 // check if iterator pos fits to this JSON value
5248 if (pos.m_object != this)
5249 {
5250 throw std::domain_error("iterator does not fit current value");
5251 }
5252
5253 // insert to array and return iterator
5254 iterator result(this);
5255 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5256 return result;
5257 }
5258
5259 /*!
5260 @brief exchanges the values
5261
5262 Exchanges the contents of the JSON value with those of @a other. Does not
5263 invoke any move, copy, or swap operations on individual elements. All
5264 iterators and references remain valid. The past-the-end iterator is
5265 invalidated.
5266
5267 @param[in,out] other JSON value to exchange the contents with
5268
5269 @complexity Constant.
5270
5271 @liveexample{The example below shows how JSON values can be swapped with
5272 `swap()`.,swap__reference}
5273
5274 @since version 1.0.0
5275 */
swap(reference other)5276 void swap(reference other) noexcept (
5277 std::is_nothrow_move_constructible<value_t>::value and
5278 std::is_nothrow_move_assignable<value_t>::value and
5279 std::is_nothrow_move_constructible<json_value>::value and
5280 std::is_nothrow_move_assignable<json_value>::value
5281 )
5282 {
5283 std::swap(m_type, other.m_type);
5284 std::swap(m_value, other.m_value);
5285 assert_invariant();
5286 }
5287
5288 /*!
5289 @brief exchanges the values
5290
5291 Exchanges the contents of a JSON array with those of @a other. Does not
5292 invoke any move, copy, or swap operations on individual elements. All
5293 iterators and references remain valid. The past-the-end iterator is
5294 invalidated.
5295
5296 @param[in,out] other array to exchange the contents with
5297
5298 @throw std::domain_error when JSON value is not an array; example: `"cannot
5299 use swap() with string"`
5300
5301 @complexity Constant.
5302
5303 @liveexample{The example below shows how arrays can be swapped with
5304 `swap()`.,swap__array_t}
5305
5306 @since version 1.0.0
5307 */
swap(array_t & other)5308 void swap(array_t& other)
5309 {
5310 // swap only works for arrays
5311 if (is_array())
5312 {
5313 std::swap(*(m_value.array), other);
5314 }
5315 else
5316 {
5317 throw std::domain_error("cannot use swap() with " + type_name());
5318 }
5319 }
5320
5321 /*!
5322 @brief exchanges the values
5323
5324 Exchanges the contents of a JSON object with those of @a other. Does not
5325 invoke any move, copy, or swap operations on individual elements. All
5326 iterators and references remain valid. The past-the-end iterator is
5327 invalidated.
5328
5329 @param[in,out] other object to exchange the contents with
5330
5331 @throw std::domain_error when JSON value is not an object; example:
5332 `"cannot use swap() with string"`
5333
5334 @complexity Constant.
5335
5336 @liveexample{The example below shows how objects can be swapped with
5337 `swap()`.,swap__object_t}
5338
5339 @since version 1.0.0
5340 */
swap(object_t & other)5341 void swap(object_t& other)
5342 {
5343 // swap only works for objects
5344 if (is_object())
5345 {
5346 std::swap(*(m_value.object), other);
5347 }
5348 else
5349 {
5350 throw std::domain_error("cannot use swap() with " + type_name());
5351 }
5352 }
5353
5354 /*!
5355 @brief exchanges the values
5356
5357 Exchanges the contents of a JSON string with those of @a other. Does not
5358 invoke any move, copy, or swap operations on individual elements. All
5359 iterators and references remain valid. The past-the-end iterator is
5360 invalidated.
5361
5362 @param[in,out] other string to exchange the contents with
5363
5364 @throw std::domain_error when JSON value is not a string; example: `"cannot
5365 use swap() with boolean"`
5366
5367 @complexity Constant.
5368
5369 @liveexample{The example below shows how strings can be swapped with
5370 `swap()`.,swap__string_t}
5371
5372 @since version 1.0.0
5373 */
swap(string_t & other)5374 void swap(string_t& other)
5375 {
5376 // swap only works for strings
5377 if (is_string())
5378 {
5379 std::swap(*(m_value.string), other);
5380 }
5381 else
5382 {
5383 throw std::domain_error("cannot use swap() with " + type_name());
5384 }
5385 }
5386
5387 /// @}
5388
5389
5390 //////////////////////////////////////////
5391 // lexicographical comparison operators //
5392 //////////////////////////////////////////
5393
5394 /// @name lexicographical comparison operators
5395 /// @{
5396
5397 private:
5398 /*!
5399 @brief comparison operator for JSON types
5400
5401 Returns an ordering that is similar to Python:
5402 - order: null < boolean < number < object < array < string
5403 - furthermore, each type is not smaller than itself
5404
5405 @since version 1.0.0
5406 */
operator <(const value_t lhs,const value_t rhs)5407 friend bool operator<(const value_t lhs, const value_t rhs) noexcept
5408 {
5409 static constexpr std::array<uint8_t, 8> order = {{
5410 0, // null
5411 3, // object
5412 4, // array
5413 5, // string
5414 1, // boolean
5415 2, // integer
5416 2, // unsigned
5417 2, // float
5418 }
5419 };
5420
5421 // discarded values are not comparable
5422 if (lhs == value_t::discarded or rhs == value_t::discarded)
5423 {
5424 return false;
5425 }
5426
5427 return order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
5428 }
5429
5430 public:
5431 /*!
5432 @brief comparison: equal
5433
5434 Compares two JSON values for equality according to the following rules:
5435 - Two JSON values are equal if (1) they are from the same type and (2)
5436 their stored values are the same.
5437 - Integer and floating-point numbers are automatically converted before
5438 comparison. Floating-point numbers are compared indirectly: two
5439 floating-point numbers `f1` and `f2` are considered equal if neither
5440 `f1 > f2` nor `f2 > f1` holds.
5441 - Two JSON null values are equal.
5442
5443 @param[in] lhs first JSON value to consider
5444 @param[in] rhs second JSON value to consider
5445 @return whether the values @a lhs and @a rhs are equal
5446
5447 @complexity Linear.
5448
5449 @liveexample{The example demonstrates comparing several JSON
5450 types.,operator__equal}
5451
5452 @since version 1.0.0
5453 */
operator ==(const_reference lhs,const_reference rhs)5454 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
5455 {
5456 const auto lhs_type = lhs.type();
5457 const auto rhs_type = rhs.type();
5458
5459 if (lhs_type == rhs_type)
5460 {
5461 switch (lhs_type)
5462 {
5463 case value_t::array:
5464 {
5465 return *lhs.m_value.array == *rhs.m_value.array;
5466 }
5467 case value_t::object:
5468 {
5469 return *lhs.m_value.object == *rhs.m_value.object;
5470 }
5471 case value_t::null:
5472 {
5473 return true;
5474 }
5475 case value_t::string:
5476 {
5477 return *lhs.m_value.string == *rhs.m_value.string;
5478 }
5479 case value_t::boolean:
5480 {
5481 return lhs.m_value.boolean == rhs.m_value.boolean;
5482 }
5483 case value_t::number_integer:
5484 {
5485 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5486 }
5487 case value_t::number_unsigned:
5488 {
5489 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5490 }
5491 case value_t::number_float:
5492 {
5493 return lhs.m_value.number_float == rhs.m_value.number_float;
5494 }
5495 default:
5496 {
5497 return false;
5498 }
5499 }
5500 }
5501 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5502 {
5503 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5504 }
5505 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5506 {
5507 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
5508 }
5509 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5510 {
5511 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5512 }
5513 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5514 {
5515 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
5516 }
5517 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5518 {
5519 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5520 }
5521 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5522 {
5523 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5524 }
5525
5526 return false;
5527 }
5528
5529 /*!
5530 @brief comparison: equal
5531
5532 The functions compares the given JSON value against a null pointer. As the
5533 null pointer can be used to initialize a JSON value to null, a comparison
5534 of JSON value @a v with a null pointer should be equivalent to call
5535 `v.is_null()`.
5536
5537 @param[in] v JSON value to consider
5538 @return whether @a v is null
5539
5540 @complexity Constant.
5541
5542 @liveexample{The example compares several JSON types to the null pointer.
5543 ,operator__equal__nullptr_t}
5544
5545 @since version 1.0.0
5546 */
operator ==(const_reference v,std::nullptr_t)5547 friend bool operator==(const_reference v, std::nullptr_t) noexcept
5548 {
5549 return v.is_null();
5550 }
5551
5552 /*!
5553 @brief comparison: equal
5554 @copydoc operator==(const_reference, std::nullptr_t)
5555 */
operator ==(std::nullptr_t,const_reference v)5556 friend bool operator==(std::nullptr_t, const_reference v) noexcept
5557 {
5558 return v.is_null();
5559 }
5560
5561 /*!
5562 @brief comparison: not equal
5563
5564 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
5565
5566 @param[in] lhs first JSON value to consider
5567 @param[in] rhs second JSON value to consider
5568 @return whether the values @a lhs and @a rhs are not equal
5569
5570 @complexity Linear.
5571
5572 @liveexample{The example demonstrates comparing several JSON
5573 types.,operator__notequal}
5574
5575 @since version 1.0.0
5576 */
operator !=(const_reference lhs,const_reference rhs)5577 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
5578 {
5579 return not (lhs == rhs);
5580 }
5581
5582 /*!
5583 @brief comparison: not equal
5584
5585 The functions compares the given JSON value against a null pointer. As the
5586 null pointer can be used to initialize a JSON value to null, a comparison
5587 of JSON value @a v with a null pointer should be equivalent to call
5588 `not v.is_null()`.
5589
5590 @param[in] v JSON value to consider
5591 @return whether @a v is not null
5592
5593 @complexity Constant.
5594
5595 @liveexample{The example compares several JSON types to the null pointer.
5596 ,operator__notequal__nullptr_t}
5597
5598 @since version 1.0.0
5599 */
operator !=(const_reference v,std::nullptr_t)5600 friend bool operator!=(const_reference v, std::nullptr_t) noexcept
5601 {
5602 return not v.is_null();
5603 }
5604
5605 /*!
5606 @brief comparison: not equal
5607 @copydoc operator!=(const_reference, std::nullptr_t)
5608 */
operator !=(std::nullptr_t,const_reference v)5609 friend bool operator!=(std::nullptr_t, const_reference v) noexcept
5610 {
5611 return not v.is_null();
5612 }
5613
5614 /*!
5615 @brief comparison: less than
5616
5617 Compares whether one JSON value @a lhs is less than another JSON value @a
5618 rhs according to the following rules:
5619 - If @a lhs and @a rhs have the same type, the values are compared using
5620 the default `<` operator.
5621 - Integer and floating-point numbers are automatically converted before
5622 comparison
5623 - In case @a lhs and @a rhs have different types, the values are ignored
5624 and the order of the types is considered, see
5625 @ref operator<(const value_t, const value_t).
5626
5627 @param[in] lhs first JSON value to consider
5628 @param[in] rhs second JSON value to consider
5629 @return whether @a lhs is less than @a rhs
5630
5631 @complexity Linear.
5632
5633 @liveexample{The example demonstrates comparing several JSON
5634 types.,operator__less}
5635
5636 @since version 1.0.0
5637 */
operator <(const_reference lhs,const_reference rhs)5638 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
5639 {
5640 const auto lhs_type = lhs.type();
5641 const auto rhs_type = rhs.type();
5642
5643 if (lhs_type == rhs_type)
5644 {
5645 switch (lhs_type)
5646 {
5647 case value_t::array:
5648 {
5649 return *lhs.m_value.array < *rhs.m_value.array;
5650 }
5651 case value_t::object:
5652 {
5653 return *lhs.m_value.object < *rhs.m_value.object;
5654 }
5655 case value_t::null:
5656 {
5657 return false;
5658 }
5659 case value_t::string:
5660 {
5661 return *lhs.m_value.string < *rhs.m_value.string;
5662 }
5663 case value_t::boolean:
5664 {
5665 return lhs.m_value.boolean < rhs.m_value.boolean;
5666 }
5667 case value_t::number_integer:
5668 {
5669 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5670 }
5671 case value_t::number_unsigned:
5672 {
5673 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5674 }
5675 case value_t::number_float:
5676 {
5677 return lhs.m_value.number_float < rhs.m_value.number_float;
5678 }
5679 default:
5680 {
5681 return false;
5682 }
5683 }
5684 }
5685 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5686 {
5687 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5688 }
5689 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5690 {
5691 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
5692 }
5693 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5694 {
5695 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5696 }
5697 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5698 {
5699 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
5700 }
5701 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5702 {
5703 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5704 }
5705 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5706 {
5707 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5708 }
5709
5710 // We only reach this line if we cannot compare values. In that case,
5711 // we compare types. Note we have to call the operator explicitly,
5712 // because MSVC has problems otherwise.
5713 return operator<(lhs_type, rhs_type);
5714 }
5715
5716 /*!
5717 @brief comparison: less than or equal
5718
5719 Compares whether one JSON value @a lhs is less than or equal to another
5720 JSON value by calculating `not (rhs < lhs)`.
5721
5722 @param[in] lhs first JSON value to consider
5723 @param[in] rhs second JSON value to consider
5724 @return whether @a lhs is less than or equal to @a rhs
5725
5726 @complexity Linear.
5727
5728 @liveexample{The example demonstrates comparing several JSON
5729 types.,operator__greater}
5730
5731 @since version 1.0.0
5732 */
operator <=(const_reference lhs,const_reference rhs)5733 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
5734 {
5735 return not (rhs < lhs);
5736 }
5737
5738 /*!
5739 @brief comparison: greater than
5740
5741 Compares whether one JSON value @a lhs is greater than another
5742 JSON value by calculating `not (lhs <= rhs)`.
5743
5744 @param[in] lhs first JSON value to consider
5745 @param[in] rhs second JSON value to consider
5746 @return whether @a lhs is greater than to @a rhs
5747
5748 @complexity Linear.
5749
5750 @liveexample{The example demonstrates comparing several JSON
5751 types.,operator__lessequal}
5752
5753 @since version 1.0.0
5754 */
operator >(const_reference lhs,const_reference rhs)5755 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
5756 {
5757 return not (lhs <= rhs);
5758 }
5759
5760 /*!
5761 @brief comparison: greater than or equal
5762
5763 Compares whether one JSON value @a lhs is greater than or equal to another
5764 JSON value by calculating `not (lhs < rhs)`.
5765
5766 @param[in] lhs first JSON value to consider
5767 @param[in] rhs second JSON value to consider
5768 @return whether @a lhs is greater than or equal to @a rhs
5769
5770 @complexity Linear.
5771
5772 @liveexample{The example demonstrates comparing several JSON
5773 types.,operator__greaterequal}
5774
5775 @since version 1.0.0
5776 */
operator >=(const_reference lhs,const_reference rhs)5777 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
5778 {
5779 return not (lhs < rhs);
5780 }
5781
5782 /// @}
5783
5784
5785 ///////////////////
5786 // serialization //
5787 ///////////////////
5788
5789 /// @name serialization
5790 /// @{
5791
5792 /*!
5793 @brief serialize to stream
5794
5795 Serialize the given JSON value @a j to the output stream @a o. The JSON
5796 value will be serialized using the @ref dump member function. The
5797 indentation of the output can be controlled with the member variable
5798 `width` of the output stream @a o. For instance, using the manipulator
5799 `std::setw(4)` on @a o sets the indentation level to `4` and the
5800 serialization result is the same as calling `dump(4)`.
5801
5802 @note During serializaion, the locale and the precision of the output
5803 stream @a o are changed. The original values are restored when the
5804 function returns.
5805
5806 @param[in,out] o stream to serialize to
5807 @param[in] j JSON value to serialize
5808
5809 @return the stream @a o
5810
5811 @complexity Linear.
5812
5813 @liveexample{The example below shows the serialization with different
5814 parameters to `width` to adjust the indentation level.,operator_serialize}
5815
5816 @since version 1.0.0
5817 */
operator <<(std::ostream & o,const basic_json & j)5818 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
5819 {
5820 // read width member and use it as indentation parameter if nonzero
5821 const bool pretty_print = (o.width() > 0);
5822 const auto indentation = (pretty_print ? o.width() : 0);
5823
5824 // reset width to 0 for subsequent calls to this stream
5825 o.width(0);
5826
5827 // fix locale problems
5828 const auto old_locale = o.imbue(std::locale(std::locale(), new DecimalSeparator));
5829 // set precision
5830
5831 // 6, 15 or 16 digits of precision allows round-trip IEEE 754
5832 // string->float->string, string->double->string or string->long
5833 // double->string; to be safe, we read this value from
5834 // std::numeric_limits<number_float_t>::digits10
5835 const auto old_precision = o.precision(std::numeric_limits<double>::digits10);
5836
5837 // do the actual serialization
5838 j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
5839
5840 // reset locale and precision
5841 o.imbue(old_locale);
5842 o.precision(old_precision);
5843 return o;
5844 }
5845
5846 /*!
5847 @brief serialize to stream
5848 @copydoc operator<<(std::ostream&, const basic_json&)
5849 */
operator >>(const basic_json & j,std::ostream & o)5850 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
5851 {
5852 return o << j;
5853 }
5854
5855 /// @}
5856
5857
5858 /////////////////////
5859 // deserialization //
5860 /////////////////////
5861
5862 /// @name deserialization
5863 /// @{
5864
5865 /*!
5866 @brief deserialize from an array
5867
5868 This function reads from an array of 1-byte values.
5869
5870 @pre Each element of the container has a size of 1 byte. Violating this
5871 precondition yields undefined behavior. **This precondition is enforced
5872 with a static assertion.**
5873
5874 @param[in] array array to read from
5875 @param[in] cb a parser callback function of type @ref parser_callback_t
5876 which is used to control the deserialization by filtering unwanted values
5877 (optional)
5878
5879 @return result of the deserialization
5880
5881 @complexity Linear in the length of the input. The parser is a predictive
5882 LL(1) parser. The complexity can be higher if the parser callback function
5883 @a cb has a super-linear complexity.
5884
5885 @note A UTF-8 byte order mark is silently ignored.
5886
5887 @liveexample{The example below demonstrates the `parse()` function reading
5888 from an array.,parse__array__parser_callback_t}
5889
5890 @since version 2.0.3
5891 */
5892 template<class T, std::size_t N>
parse(T (& array)[N],const parser_callback_t cb=nullptr)5893 static basic_json parse(T (&array)[N],
5894 const parser_callback_t cb = nullptr)
5895 {
5896 // delegate the call to the iterator-range parse overload
5897 return parse(std::begin(array), std::end(array), cb);
5898 }
5899
5900 /*!
5901 @brief deserialize from string literal
5902
5903 @tparam CharT character/literal type with size of 1 byte
5904 @param[in] s string literal to read a serialized JSON value from
5905 @param[in] cb a parser callback function of type @ref parser_callback_t
5906 which is used to control the deserialization by filtering unwanted values
5907 (optional)
5908
5909 @return result of the deserialization
5910
5911 @complexity Linear in the length of the input. The parser is a predictive
5912 LL(1) parser. The complexity can be higher if the parser callback function
5913 @a cb has a super-linear complexity.
5914
5915 @note A UTF-8 byte order mark is silently ignored.
5916 @note String containers like `std::string` or @ref string_t can be parsed
5917 with @ref parse(const ContiguousContainer&, const parser_callback_t)
5918
5919 @liveexample{The example below demonstrates the `parse()` function with
5920 and without callback function.,parse__string__parser_callback_t}
5921
5922 @sa @ref parse(std::istream&, const parser_callback_t) for a version that
5923 reads from an input stream
5924
5925 @since version 1.0.0 (originally for @ref string_t)
5926 */
5927 template<typename CharPT, typename std::enable_if<
5928 std::is_pointer<CharPT>::value and
5929 std::is_integral<typename std::remove_pointer<CharPT>::type>::value and
5930 sizeof(typename std::remove_pointer<CharPT>::type) == 1, int>::type = 0>
parse(const CharPT s,const parser_callback_t cb=nullptr)5931 static basic_json parse(const CharPT s,
5932 const parser_callback_t cb = nullptr)
5933 {
5934 return parser(reinterpret_cast<const char*>(s), cb).parse();
5935 }
5936
5937 /*!
5938 @brief deserialize from stream
5939
5940 @param[in,out] i stream to read a serialized JSON value from
5941 @param[in] cb a parser callback function of type @ref parser_callback_t
5942 which is used to control the deserialization by filtering unwanted values
5943 (optional)
5944
5945 @return result of the deserialization
5946
5947 @complexity Linear in the length of the input. The parser is a predictive
5948 LL(1) parser. The complexity can be higher if the parser callback function
5949 @a cb has a super-linear complexity.
5950
5951 @note A UTF-8 byte order mark is silently ignored.
5952
5953 @liveexample{The example below demonstrates the `parse()` function with
5954 and without callback function.,parse__istream__parser_callback_t}
5955
5956 @sa @ref parse(const char*, const parser_callback_t) for a version
5957 that reads from a string
5958
5959 @since version 1.0.0
5960 */
parse(std::istream & i,const parser_callback_t cb=nullptr)5961 static basic_json parse(std::istream& i,
5962 const parser_callback_t cb = nullptr)
5963 {
5964 return parser(i, cb).parse();
5965 }
5966
5967 /*!
5968 @copydoc parse(std::istream&, const parser_callback_t)
5969 */
parse(std::istream && i,const parser_callback_t cb=nullptr)5970 static basic_json parse(std::istream&& i,
5971 const parser_callback_t cb = nullptr)
5972 {
5973 return parser(i, cb).parse();
5974 }
5975
5976 /*!
5977 @brief deserialize from an iterator range with contiguous storage
5978
5979 This function reads from an iterator range of a container with contiguous
5980 storage of 1-byte values. Compatible container types include
5981 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
5982 `std::initializer_list`. Furthermore, C-style arrays can be used with
5983 `std::begin()`/`std::end()`. User-defined containers can be used as long
5984 as they implement random-access iterators and a contiguous storage.
5985
5986 @pre The iterator range is contiguous. Violating this precondition yields
5987 undefined behavior. **This precondition is enforced with an assertion.**
5988 @pre Each element in the range has a size of 1 byte. Violating this
5989 precondition yields undefined behavior. **This precondition is enforced
5990 with a static assertion.**
5991
5992 @warning There is no way to enforce all preconditions at compile-time. If
5993 the function is called with noncompliant iterators and with
5994 assertions switched off, the behavior is undefined and will most
5995 likely yield segmentation violation.
5996
5997 @tparam IteratorType iterator of container with contiguous storage
5998 @param[in] first begin of the range to parse (included)
5999 @param[in] last end of the range to parse (excluded)
6000 @param[in] cb a parser callback function of type @ref parser_callback_t
6001 which is used to control the deserialization by filtering unwanted values
6002 (optional)
6003
6004 @return result of the deserialization
6005
6006 @complexity Linear in the length of the input. The parser is a predictive
6007 LL(1) parser. The complexity can be higher if the parser callback function
6008 @a cb has a super-linear complexity.
6009
6010 @note A UTF-8 byte order mark is silently ignored.
6011
6012 @liveexample{The example below demonstrates the `parse()` function reading
6013 from an iterator range.,parse__iteratortype__parser_callback_t}
6014
6015 @since version 2.0.3
6016 */
6017 template<class IteratorType, typename std::enable_if<
6018 std::is_base_of<
6019 std::random_access_iterator_tag,
6020 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr)6021 static basic_json parse(IteratorType first, IteratorType last,
6022 const parser_callback_t cb = nullptr)
6023 {
6024 // assertion to check that the iterator range is indeed contiguous,
6025 // see http://stackoverflow.com/a/35008842/266378 for more discussion
6026 assert(std::accumulate(first, last, std::make_pair<bool, int>(true, 0),
6027 [&first](std::pair<bool, int> res, decltype(*first) val)
6028 {
6029 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
6030 return res;
6031 }).first);
6032
6033 // assertion to check that each element is 1 byte long
6034 static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
6035 "each element in the iterator range must have the size of 1 byte");
6036
6037 // if iterator range is empty, create a parser with an empty string
6038 // to generate "unexpected EOF" error message
6039 if (std::distance(first, last) <= 0)
6040 {
6041 return parser("").parse();
6042 }
6043
6044 return parser(first, last, cb).parse();
6045 }
6046
6047 /*!
6048 @brief deserialize from a container with contiguous storage
6049
6050 This function reads from a container with contiguous storage of 1-byte
6051 values. Compatible container types include `std::vector`, `std::string`,
6052 `std::array`, and `std::initializer_list`. User-defined containers can be
6053 used as long as they implement random-access iterators and a contiguous
6054 storage.
6055
6056 @pre The container storage is contiguous. Violating this precondition
6057 yields undefined behavior. **This precondition is enforced with an
6058 assertion.**
6059 @pre Each element of the container has a size of 1 byte. Violating this
6060 precondition yields undefined behavior. **This precondition is enforced
6061 with a static assertion.**
6062
6063 @warning There is no way to enforce all preconditions at compile-time. If
6064 the function is called with a noncompliant container and with
6065 assertions switched off, the behavior is undefined and will most
6066 likely yield segmentation violation.
6067
6068 @tparam ContiguousContainer container type with contiguous storage
6069 @param[in] c container to read from
6070 @param[in] cb a parser callback function of type @ref parser_callback_t
6071 which is used to control the deserialization by filtering unwanted values
6072 (optional)
6073
6074 @return result of the deserialization
6075
6076 @complexity Linear in the length of the input. The parser is a predictive
6077 LL(1) parser. The complexity can be higher if the parser callback function
6078 @a cb has a super-linear complexity.
6079
6080 @note A UTF-8 byte order mark is silently ignored.
6081
6082 @liveexample{The example below demonstrates the `parse()` function reading
6083 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
6084
6085 @since version 2.0.3
6086 */
6087 template<class ContiguousContainer, typename std::enable_if<
6088 not std::is_pointer<ContiguousContainer>::value and
6089 std::is_base_of<
6090 std::random_access_iterator_tag,
6091 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
6092 , int>::type = 0>
parse(const ContiguousContainer & c,const parser_callback_t cb=nullptr)6093 static basic_json parse(const ContiguousContainer& c,
6094 const parser_callback_t cb = nullptr)
6095 {
6096 // delegate the call to the iterator-range parse overload
6097 return parse(std::begin(c), std::end(c), cb);
6098 }
6099
6100 /*!
6101 @brief deserialize from stream
6102
6103 Deserializes an input stream to a JSON value.
6104
6105 @param[in,out] i input stream to read a serialized JSON value from
6106 @param[in,out] j JSON value to write the deserialized input to
6107
6108 @throw std::invalid_argument in case of parse errors
6109
6110 @complexity Linear in the length of the input. The parser is a predictive
6111 LL(1) parser.
6112
6113 @note A UTF-8 byte order mark is silently ignored.
6114
6115 @liveexample{The example below shows how a JSON value is constructed by
6116 reading a serialization from a stream.,operator_deserialize}
6117
6118 @sa parse(std::istream&, const parser_callback_t) for a variant with a
6119 parser callback function to filter values while parsing
6120
6121 @since version 1.0.0
6122 */
operator <<(basic_json & j,std::istream & i)6123 friend std::istream& operator<<(basic_json& j, std::istream& i)
6124 {
6125 j = parser(i).parse();
6126 return i;
6127 }
6128
6129 /*!
6130 @brief deserialize from stream
6131 @copydoc operator<<(basic_json&, std::istream&)
6132 */
operator >>(std::istream & i,basic_json & j)6133 friend std::istream& operator>>(std::istream& i, basic_json& j)
6134 {
6135 j = parser(i).parse();
6136 return i;
6137 }
6138
6139 /// @}
6140
6141
6142 private:
6143 ///////////////////////////
6144 // convenience functions //
6145 ///////////////////////////
6146
6147 /*!
6148 @brief return the type as string
6149
6150 Returns the type name as string to be used in error messages - usually to
6151 indicate that a function was called on a wrong JSON type.
6152
6153 @return basically a string representation of a the @a m_type member
6154
6155 @complexity Constant.
6156
6157 @since version 1.0.0
6158 */
type_name() const6159 std::string type_name() const
6160 {
6161 switch (m_type)
6162 {
6163 case value_t::null:
6164 return "null";
6165 case value_t::object:
6166 return "object";
6167 case value_t::array:
6168 return "array";
6169 case value_t::string:
6170 return "string";
6171 case value_t::boolean:
6172 return "boolean";
6173 case value_t::discarded:
6174 return "discarded";
6175 default:
6176 return "number";
6177 }
6178 }
6179
6180 /*!
6181 @brief calculates the extra space to escape a JSON string
6182
6183 @param[in] s the string to escape
6184 @return the number of characters required to escape string @a s
6185
6186 @complexity Linear in the length of string @a s.
6187 */
extra_space(const string_t & s)6188 static std::size_t extra_space(const string_t& s) noexcept
6189 {
6190 return std::accumulate(s.begin(), s.end(), size_t{},
6191 [](size_t res, typename string_t::value_type c)
6192 {
6193 switch (c)
6194 {
6195 case '"':
6196 case '\\':
6197 case '\b':
6198 case '\f':
6199 case '\n':
6200 case '\r':
6201 case '\t':
6202 {
6203 // from c (1 byte) to \x (2 bytes)
6204 return res + 1;
6205 }
6206
6207 default:
6208 {
6209 if (c >= 0x00 and c <= 0x1f)
6210 {
6211 // from c (1 byte) to \uxxxx (6 bytes)
6212 return res + 5;
6213 }
6214 else
6215 {
6216 return res;
6217 }
6218 }
6219 }
6220 });
6221 }
6222
6223 /*!
6224 @brief escape a string
6225
6226 Escape a string by replacing certain special characters by a sequence of
6227 an escape character (backslash) and another character and other control
6228 characters by a sequence of "\u" followed by a four-digit hex
6229 representation.
6230
6231 @param[in] s the string to escape
6232 @return the escaped string
6233
6234 @complexity Linear in the length of string @a s.
6235 */
escape_string(const string_t & s)6236 static string_t escape_string(const string_t& s)
6237 {
6238 const auto space = extra_space(s);
6239 if (space == 0)
6240 {
6241 return s;
6242 }
6243
6244 // create a result string of necessary size
6245 string_t result(s.size() + space, '\\');
6246 std::size_t pos = 0;
6247
6248 for (const auto& c : s)
6249 {
6250 switch (c)
6251 {
6252 // quotation mark (0x22)
6253 case '"':
6254 {
6255 result[pos + 1] = '"';
6256 pos += 2;
6257 break;
6258 }
6259
6260 // reverse solidus (0x5c)
6261 case '\\':
6262 {
6263 // nothing to change
6264 pos += 2;
6265 break;
6266 }
6267
6268 // backspace (0x08)
6269 case '\b':
6270 {
6271 result[pos + 1] = 'b';
6272 pos += 2;
6273 break;
6274 }
6275
6276 // formfeed (0x0c)
6277 case '\f':
6278 {
6279 result[pos + 1] = 'f';
6280 pos += 2;
6281 break;
6282 }
6283
6284 // newline (0x0a)
6285 case '\n':
6286 {
6287 result[pos + 1] = 'n';
6288 pos += 2;
6289 break;
6290 }
6291
6292 // carriage return (0x0d)
6293 case '\r':
6294 {
6295 result[pos + 1] = 'r';
6296 pos += 2;
6297 break;
6298 }
6299
6300 // horizontal tab (0x09)
6301 case '\t':
6302 {
6303 result[pos + 1] = 't';
6304 pos += 2;
6305 break;
6306 }
6307
6308 default:
6309 {
6310 if (c >= 0x00 and c <= 0x1f)
6311 {
6312 // convert a number 0..15 to its hex representation
6313 // (0..f)
6314 static const char hexify[16] =
6315 {
6316 '0', '1', '2', '3', '4', '5', '6', '7',
6317 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
6318 };
6319
6320 // print character c as \uxxxx
6321 for (const char m :
6322 { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
6323 })
6324 {
6325 result[++pos] = m;
6326 }
6327
6328 ++pos;
6329 }
6330 else
6331 {
6332 // all other characters are added as-is
6333 result[pos++] = c;
6334 }
6335 break;
6336 }
6337 }
6338 }
6339
6340 return result;
6341 }
6342
6343 /*!
6344 @brief internal implementation of the serialization function
6345
6346 This function is called by the public member function dump and organizes
6347 the serialization internally. The indentation level is propagated as
6348 additional parameter. In case of arrays and objects, the function is
6349 called recursively. Note that
6350
6351 - strings and object keys are escaped using `escape_string()`
6352 - integer numbers are converted implicitly via `operator<<`
6353 - floating-point numbers are converted to a string using `"%g"` format
6354
6355 @param[out] o stream to write to
6356 @param[in] pretty_print whether the output shall be pretty-printed
6357 @param[in] indent_step the indent level
6358 @param[in] current_indent the current indent level (only used internally)
6359 */
dump(std::ostream & o,const bool pretty_print,const unsigned int indent_step,const unsigned int current_indent=0) const6360 void dump(std::ostream& o,
6361 const bool pretty_print,
6362 const unsigned int indent_step,
6363 const unsigned int current_indent = 0) const
6364 {
6365 // variable to hold indentation for recursive calls
6366 unsigned int new_indent = current_indent;
6367
6368 switch (m_type)
6369 {
6370 case value_t::object:
6371 {
6372 if (m_value.object->empty())
6373 {
6374 o << "{}";
6375 return;
6376 }
6377
6378 o << "{";
6379
6380 // increase indentation
6381 if (pretty_print)
6382 {
6383 new_indent += indent_step;
6384 o << "\n";
6385 }
6386
6387 for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
6388 {
6389 if (i != m_value.object->cbegin())
6390 {
6391 o << (pretty_print ? ",\n" : ",");
6392 }
6393 o << string_t(new_indent, ' ') << "\""
6394 << escape_string(i->first) << "\":"
6395 << (pretty_print ? " " : "");
6396 i->second.dump(o, pretty_print, indent_step, new_indent);
6397 }
6398
6399 // decrease indentation
6400 if (pretty_print)
6401 {
6402 new_indent -= indent_step;
6403 o << "\n";
6404 }
6405
6406 o << string_t(new_indent, ' ') + "}";
6407 return;
6408 }
6409
6410 case value_t::array:
6411 {
6412 if (m_value.array->empty())
6413 {
6414 o << "[]";
6415 return;
6416 }
6417
6418 o << "[";
6419
6420 // increase indentation
6421 if (pretty_print)
6422 {
6423 new_indent += indent_step;
6424 o << "\n";
6425 }
6426
6427 for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
6428 {
6429 if (i != m_value.array->cbegin())
6430 {
6431 o << (pretty_print ? ",\n" : ",");
6432 }
6433 o << string_t(new_indent, ' ');
6434 i->dump(o, pretty_print, indent_step, new_indent);
6435 }
6436
6437 // decrease indentation
6438 if (pretty_print)
6439 {
6440 new_indent -= indent_step;
6441 o << "\n";
6442 }
6443
6444 o << string_t(new_indent, ' ') << "]";
6445 return;
6446 }
6447
6448 case value_t::string:
6449 {
6450 o << string_t("\"") << escape_string(*m_value.string) << "\"";
6451 return;
6452 }
6453
6454 case value_t::boolean:
6455 {
6456 o << (m_value.boolean ? "true" : "false");
6457 return;
6458 }
6459
6460 case value_t::number_integer:
6461 {
6462 o << m_value.number_integer;
6463 return;
6464 }
6465
6466 case value_t::number_unsigned:
6467 {
6468 o << m_value.number_unsigned;
6469 return;
6470 }
6471
6472 case value_t::number_float:
6473 {
6474 if (m_value.number_float == 0)
6475 {
6476 // special case for zero to get "0.0"/"-0.0"
6477 o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
6478 }
6479 else
6480 {
6481 o << m_value.number_float;
6482 }
6483 return;
6484 }
6485
6486 case value_t::discarded:
6487 {
6488 o << "<discarded>";
6489 return;
6490 }
6491
6492 case value_t::null:
6493 {
6494 o << "null";
6495 return;
6496 }
6497 }
6498 }
6499
6500 private:
6501 //////////////////////
6502 // member variables //
6503 //////////////////////
6504
6505 /// the type of the current element
6506 value_t m_type = value_t::null;
6507
6508 /// the value of the current element
6509 json_value m_value = {};
6510
6511
6512 private:
6513 ///////////////
6514 // iterators //
6515 ///////////////
6516
6517 /*!
6518 @brief an iterator for primitive JSON types
6519
6520 This class models an iterator for primitive JSON types (boolean, number,
6521 string). It's only purpose is to allow the iterator/const_iterator classes
6522 to "iterate" over primitive values. Internally, the iterator is modeled by
6523 a `difference_type` variable. Value begin_value (`0`) models the begin,
6524 end_value (`1`) models past the end.
6525 */
6526 class primitive_iterator_t
6527 {
6528 public:
6529 /// set iterator to a defined beginning
set_begin()6530 void set_begin() noexcept
6531 {
6532 m_it = begin_value;
6533 }
6534
6535 /// set iterator to a defined past the end
set_end()6536 void set_end() noexcept
6537 {
6538 m_it = end_value;
6539 }
6540
6541 /// return whether the iterator can be dereferenced
is_begin() const6542 constexpr bool is_begin() const noexcept
6543 {
6544 return (m_it == begin_value);
6545 }
6546
6547 /// return whether the iterator is at end
is_end() const6548 constexpr bool is_end() const noexcept
6549 {
6550 return (m_it == end_value);
6551 }
6552
6553 /// return reference to the value to change and compare
operator difference_type&()6554 operator difference_type& () noexcept
6555 {
6556 return m_it;
6557 }
6558
6559 /// return value to compare
operator difference_type() const6560 constexpr operator difference_type () const noexcept
6561 {
6562 return m_it;
6563 }
6564
6565 private:
6566 static constexpr difference_type begin_value = 0;
6567 static constexpr difference_type end_value = begin_value + 1;
6568
6569 /// iterator as signed integer type
6570 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6571 };
6572
6573 /*!
6574 @brief an iterator value
6575
6576 @note This structure could easily be a union, but MSVC currently does not
6577 allow unions members with complex constructors, see
6578 https://github.com/nlohmann/json/pull/105.
6579 */
6580 struct internal_iterator
6581 {
6582 /// iterator for JSON objects
6583 typename object_t::iterator object_iterator;
6584 /// iterator for JSON arrays
6585 typename array_t::iterator array_iterator;
6586 /// generic iterator for all other types
6587 primitive_iterator_t primitive_iterator;
6588
6589 /// create an uninitialized internal_iterator
internal_iteratornlohmann::basic_json::internal_iterator6590 internal_iterator() noexcept
6591 : object_iterator(), array_iterator(), primitive_iterator()
6592 {}
6593 };
6594
6595 /// proxy class for the iterator_wrapper functions
6596 template<typename IteratorType>
6597 class iteration_proxy
6598 {
6599 private:
6600 /// helper class for iteration
6601 class iteration_proxy_internal
6602 {
6603 private:
6604 /// the iterator
6605 IteratorType anchor;
6606 /// an index for arrays (used to create key names)
6607 size_t array_index = 0;
6608
6609 public:
iteration_proxy_internal(IteratorType it)6610 explicit iteration_proxy_internal(IteratorType it) noexcept
6611 : anchor(it)
6612 {}
6613
6614 /// dereference operator (needed for range-based for)
operator *()6615 iteration_proxy_internal& operator*()
6616 {
6617 return *this;
6618 }
6619
6620 /// increment operator (needed for range-based for)
operator ++()6621 iteration_proxy_internal& operator++()
6622 {
6623 ++anchor;
6624 ++array_index;
6625
6626 return *this;
6627 }
6628
6629 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const6630 bool operator!= (const iteration_proxy_internal& o) const
6631 {
6632 return anchor != o.anchor;
6633 }
6634
6635 /// return key of the iterator
key() const6636 typename basic_json::string_t key() const
6637 {
6638 assert(anchor.m_object != nullptr);
6639
6640 switch (anchor.m_object->type())
6641 {
6642 // use integer array index as key
6643 case value_t::array:
6644 {
6645 return std::to_string(array_index);
6646 }
6647
6648 // use key from the object
6649 case value_t::object:
6650 {
6651 return anchor.key();
6652 }
6653
6654 // use an empty key for all primitive types
6655 default:
6656 {
6657 return "";
6658 }
6659 }
6660 }
6661
6662 /// return value of the iterator
value() const6663 typename IteratorType::reference value() const
6664 {
6665 return anchor.value();
6666 }
6667 };
6668
6669 /// the container to iterate
6670 typename IteratorType::reference container;
6671
6672 public:
6673 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)6674 explicit iteration_proxy(typename IteratorType::reference cont)
6675 : container(cont)
6676 {}
6677
6678 /// return iterator begin (needed for range-based for)
begin()6679 iteration_proxy_internal begin() noexcept
6680 {
6681 return iteration_proxy_internal(container.begin());
6682 }
6683
6684 /// return iterator end (needed for range-based for)
end()6685 iteration_proxy_internal end() noexcept
6686 {
6687 return iteration_proxy_internal(container.end());
6688 }
6689 };
6690
6691 public:
6692 /*!
6693 @brief a const random access iterator for the @ref basic_json class
6694
6695 This class implements a const iterator for the @ref basic_json class. From
6696 this class, the @ref iterator class is derived.
6697
6698 @note An iterator is called *initialized* when a pointer to a JSON value
6699 has been set (e.g., by a constructor or a copy assignment). If the
6700 iterator is default-constructed, it is *uninitialized* and most
6701 methods are undefined. **The library uses assertions to detect calls
6702 on uninitialized iterators.**
6703
6704 @requirement The class satisfies the following concept requirements:
6705 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
6706 The iterator that can be moved to point (forward and backward) to any
6707 element in constant time.
6708
6709 @since version 1.0.0
6710 */
6711 class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
6712 {
6713 /// allow basic_json to access private members
6714 friend class basic_json;
6715
6716 public:
6717 /// the type of the values when the iterator is dereferenced
6718 using value_type = typename basic_json::value_type;
6719 /// a type to represent differences between iterators
6720 using difference_type = typename basic_json::difference_type;
6721 /// defines a pointer to the type iterated over (value_type)
6722 using pointer = typename basic_json::const_pointer;
6723 /// defines a reference to the type iterated over (value_type)
6724 using reference = typename basic_json::const_reference;
6725 /// the category of the iterator
6726 using iterator_category = std::bidirectional_iterator_tag;
6727
6728 /// default constructor
6729 const_iterator() = default;
6730
6731 /*!
6732 @brief constructor for a given JSON instance
6733 @param[in] object pointer to a JSON object for this iterator
6734 @pre object != nullptr
6735 @post The iterator is initialized; i.e. `m_object != nullptr`.
6736 */
const_iterator(pointer object)6737 explicit const_iterator(pointer object) noexcept
6738 : m_object(object)
6739 {
6740 assert(m_object != nullptr);
6741
6742 switch (m_object->m_type)
6743 {
6744 case basic_json::value_t::object:
6745 {
6746 m_it.object_iterator = typename object_t::iterator();
6747 break;
6748 }
6749
6750 case basic_json::value_t::array:
6751 {
6752 m_it.array_iterator = typename array_t::iterator();
6753 break;
6754 }
6755
6756 default:
6757 {
6758 m_it.primitive_iterator = primitive_iterator_t();
6759 break;
6760 }
6761 }
6762 }
6763
6764 /*!
6765 @brief copy constructor given a non-const iterator
6766 @param[in] other iterator to copy from
6767 @note It is not checked whether @a other is initialized.
6768 */
const_iterator(const iterator & other)6769 explicit const_iterator(const iterator& other) noexcept
6770 : m_object(other.m_object)
6771 {
6772 if (m_object != nullptr)
6773 {
6774 switch (m_object->m_type)
6775 {
6776 case basic_json::value_t::object:
6777 {
6778 m_it.object_iterator = other.m_it.object_iterator;
6779 break;
6780 }
6781
6782 case basic_json::value_t::array:
6783 {
6784 m_it.array_iterator = other.m_it.array_iterator;
6785 break;
6786 }
6787
6788 default:
6789 {
6790 m_it.primitive_iterator = other.m_it.primitive_iterator;
6791 break;
6792 }
6793 }
6794 }
6795 }
6796
6797 /*!
6798 @brief copy constructor
6799 @param[in] other iterator to copy from
6800 @note It is not checked whether @a other is initialized.
6801 */
const_iterator(const const_iterator & other)6802 const_iterator(const const_iterator& other) noexcept
6803 : m_object(other.m_object), m_it(other.m_it)
6804 {}
6805
6806 /*!
6807 @brief copy assignment
6808 @param[in,out] other iterator to copy from
6809 @note It is not checked whether @a other is initialized.
6810 */
operator =(const_iterator other)6811 const_iterator& operator=(const_iterator other) noexcept(
6812 std::is_nothrow_move_constructible<pointer>::value and
6813 std::is_nothrow_move_assignable<pointer>::value and
6814 std::is_nothrow_move_constructible<internal_iterator>::value and
6815 std::is_nothrow_move_assignable<internal_iterator>::value
6816 )
6817 {
6818 std::swap(m_object, other.m_object);
6819 std::swap(m_it, other.m_it);
6820 return *this;
6821 }
6822
6823 private:
6824 /*!
6825 @brief set the iterator to the first value
6826 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6827 */
set_begin()6828 void set_begin() noexcept
6829 {
6830 assert(m_object != nullptr);
6831
6832 switch (m_object->m_type)
6833 {
6834 case basic_json::value_t::object:
6835 {
6836 m_it.object_iterator = m_object->m_value.object->begin();
6837 break;
6838 }
6839
6840 case basic_json::value_t::array:
6841 {
6842 m_it.array_iterator = m_object->m_value.array->begin();
6843 break;
6844 }
6845
6846 case basic_json::value_t::null:
6847 {
6848 // set to end so begin()==end() is true: null is empty
6849 m_it.primitive_iterator.set_end();
6850 break;
6851 }
6852
6853 default:
6854 {
6855 m_it.primitive_iterator.set_begin();
6856 break;
6857 }
6858 }
6859 }
6860
6861 /*!
6862 @brief set the iterator past the last value
6863 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6864 */
set_end()6865 void set_end() noexcept
6866 {
6867 assert(m_object != nullptr);
6868
6869 switch (m_object->m_type)
6870 {
6871 case basic_json::value_t::object:
6872 {
6873 m_it.object_iterator = m_object->m_value.object->end();
6874 break;
6875 }
6876
6877 case basic_json::value_t::array:
6878 {
6879 m_it.array_iterator = m_object->m_value.array->end();
6880 break;
6881 }
6882
6883 default:
6884 {
6885 m_it.primitive_iterator.set_end();
6886 break;
6887 }
6888 }
6889 }
6890
6891 public:
6892 /*!
6893 @brief return a reference to the value pointed to by the iterator
6894 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6895 */
operator *() const6896 reference operator*() const
6897 {
6898 assert(m_object != nullptr);
6899
6900 switch (m_object->m_type)
6901 {
6902 case basic_json::value_t::object:
6903 {
6904 assert(m_it.object_iterator != m_object->m_value.object->end());
6905 return m_it.object_iterator->second;
6906 }
6907
6908 case basic_json::value_t::array:
6909 {
6910 assert(m_it.array_iterator != m_object->m_value.array->end());
6911 return *m_it.array_iterator;
6912 }
6913
6914 case basic_json::value_t::null:
6915 {
6916 throw std::out_of_range("cannot get value");
6917 }
6918
6919 default:
6920 {
6921 if (m_it.primitive_iterator.is_begin())
6922 {
6923 return *m_object;
6924 }
6925 else
6926 {
6927 throw std::out_of_range("cannot get value");
6928 }
6929 }
6930 }
6931 }
6932
6933 /*!
6934 @brief dereference the iterator
6935 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6936 */
operator ->() const6937 pointer operator->() const
6938 {
6939 assert(m_object != nullptr);
6940
6941 switch (m_object->m_type)
6942 {
6943 case basic_json::value_t::object:
6944 {
6945 assert(m_it.object_iterator != m_object->m_value.object->end());
6946 return &(m_it.object_iterator->second);
6947 }
6948
6949 case basic_json::value_t::array:
6950 {
6951 assert(m_it.array_iterator != m_object->m_value.array->end());
6952 return &*m_it.array_iterator;
6953 }
6954
6955 default:
6956 {
6957 if (m_it.primitive_iterator.is_begin())
6958 {
6959 return m_object;
6960 }
6961 else
6962 {
6963 throw std::out_of_range("cannot get value");
6964 }
6965 }
6966 }
6967 }
6968
6969 /*!
6970 @brief post-increment (it++)
6971 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6972 */
operator ++(int)6973 const_iterator operator++(int)
6974 {
6975 auto result = *this;
6976 ++(*this);
6977 return result;
6978 }
6979
6980 /*!
6981 @brief pre-increment (++it)
6982 @pre The iterator is initialized; i.e. `m_object != nullptr`.
6983 */
operator ++()6984 const_iterator& operator++()
6985 {
6986 assert(m_object != nullptr);
6987
6988 switch (m_object->m_type)
6989 {
6990 case basic_json::value_t::object:
6991 {
6992 std::advance(m_it.object_iterator, 1);
6993 break;
6994 }
6995
6996 case basic_json::value_t::array:
6997 {
6998 std::advance(m_it.array_iterator, 1);
6999 break;
7000 }
7001
7002 default:
7003 {
7004 ++m_it.primitive_iterator;
7005 break;
7006 }
7007 }
7008
7009 return *this;
7010 }
7011
7012 /*!
7013 @brief post-decrement (it--)
7014 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7015 */
operator --(int)7016 const_iterator operator--(int)
7017 {
7018 auto result = *this;
7019 --(*this);
7020 return result;
7021 }
7022
7023 /*!
7024 @brief pre-decrement (--it)
7025 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7026 */
operator --()7027 const_iterator& operator--()
7028 {
7029 assert(m_object != nullptr);
7030
7031 switch (m_object->m_type)
7032 {
7033 case basic_json::value_t::object:
7034 {
7035 std::advance(m_it.object_iterator, -1);
7036 break;
7037 }
7038
7039 case basic_json::value_t::array:
7040 {
7041 std::advance(m_it.array_iterator, -1);
7042 break;
7043 }
7044
7045 default:
7046 {
7047 --m_it.primitive_iterator;
7048 break;
7049 }
7050 }
7051
7052 return *this;
7053 }
7054
7055 /*!
7056 @brief comparison: equal
7057 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7058 */
operator ==(const const_iterator & other) const7059 bool operator==(const const_iterator& other) const
7060 {
7061 // if objects are not the same, the comparison is undefined
7062 if (m_object != other.m_object)
7063 {
7064 throw std::domain_error("cannot compare iterators of different containers");
7065 }
7066
7067 assert(m_object != nullptr);
7068
7069 switch (m_object->m_type)
7070 {
7071 case basic_json::value_t::object:
7072 {
7073 return (m_it.object_iterator == other.m_it.object_iterator);
7074 }
7075
7076 case basic_json::value_t::array:
7077 {
7078 return (m_it.array_iterator == other.m_it.array_iterator);
7079 }
7080
7081 default:
7082 {
7083 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
7084 }
7085 }
7086 }
7087
7088 /*!
7089 @brief comparison: not equal
7090 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7091 */
operator !=(const const_iterator & other) const7092 bool operator!=(const const_iterator& other) const
7093 {
7094 return not operator==(other);
7095 }
7096
7097 /*!
7098 @brief comparison: smaller
7099 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7100 */
operator <(const const_iterator & other) const7101 bool operator<(const const_iterator& other) const
7102 {
7103 // if objects are not the same, the comparison is undefined
7104 if (m_object != other.m_object)
7105 {
7106 throw std::domain_error("cannot compare iterators of different containers");
7107 }
7108
7109 assert(m_object != nullptr);
7110
7111 switch (m_object->m_type)
7112 {
7113 case basic_json::value_t::object:
7114 {
7115 throw std::domain_error("cannot compare order of object iterators");
7116 }
7117
7118 case basic_json::value_t::array:
7119 {
7120 return (m_it.array_iterator < other.m_it.array_iterator);
7121 }
7122
7123 default:
7124 {
7125 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
7126 }
7127 }
7128 }
7129
7130 /*!
7131 @brief comparison: less than or equal
7132 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7133 */
operator <=(const const_iterator & other) const7134 bool operator<=(const const_iterator& other) const
7135 {
7136 return not other.operator < (*this);
7137 }
7138
7139 /*!
7140 @brief comparison: greater than
7141 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7142 */
operator >(const const_iterator & other) const7143 bool operator>(const const_iterator& other) const
7144 {
7145 return not operator<=(other);
7146 }
7147
7148 /*!
7149 @brief comparison: greater than or equal
7150 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7151 */
operator >=(const const_iterator & other) const7152 bool operator>=(const const_iterator& other) const
7153 {
7154 return not operator<(other);
7155 }
7156
7157 /*!
7158 @brief add to iterator
7159 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7160 */
operator +=(difference_type i)7161 const_iterator& operator+=(difference_type i)
7162 {
7163 assert(m_object != nullptr);
7164
7165 switch (m_object->m_type)
7166 {
7167 case basic_json::value_t::object:
7168 {
7169 throw std::domain_error("cannot use offsets with object iterators");
7170 }
7171
7172 case basic_json::value_t::array:
7173 {
7174 std::advance(m_it.array_iterator, i);
7175 break;
7176 }
7177
7178 default:
7179 {
7180 m_it.primitive_iterator += i;
7181 break;
7182 }
7183 }
7184
7185 return *this;
7186 }
7187
7188 /*!
7189 @brief subtract from iterator
7190 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7191 */
operator -=(difference_type i)7192 const_iterator& operator-=(difference_type i)
7193 {
7194 return operator+=(-i);
7195 }
7196
7197 /*!
7198 @brief add to iterator
7199 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7200 */
operator +(difference_type i)7201 const_iterator operator+(difference_type i)
7202 {
7203 auto result = *this;
7204 result += i;
7205 return result;
7206 }
7207
7208 /*!
7209 @brief subtract from iterator
7210 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7211 */
operator -(difference_type i)7212 const_iterator operator-(difference_type i)
7213 {
7214 auto result = *this;
7215 result -= i;
7216 return result;
7217 }
7218
7219 /*!
7220 @brief return difference
7221 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7222 */
operator -(const const_iterator & other) const7223 difference_type operator-(const const_iterator& other) const
7224 {
7225 assert(m_object != nullptr);
7226
7227 switch (m_object->m_type)
7228 {
7229 case basic_json::value_t::object:
7230 {
7231 throw std::domain_error("cannot use offsets with object iterators");
7232 }
7233
7234 case basic_json::value_t::array:
7235 {
7236 return m_it.array_iterator - other.m_it.array_iterator;
7237 }
7238
7239 default:
7240 {
7241 return m_it.primitive_iterator - other.m_it.primitive_iterator;
7242 }
7243 }
7244 }
7245
7246 /*!
7247 @brief access to successor
7248 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7249 */
operator [](difference_type n) const7250 reference operator[](difference_type n) const
7251 {
7252 assert(m_object != nullptr);
7253
7254 switch (m_object->m_type)
7255 {
7256 case basic_json::value_t::object:
7257 {
7258 throw std::domain_error("cannot use operator[] for object iterators");
7259 }
7260
7261 case basic_json::value_t::array:
7262 {
7263 return *std::next(m_it.array_iterator, n);
7264 }
7265
7266 case basic_json::value_t::null:
7267 {
7268 throw std::out_of_range("cannot get value");
7269 }
7270
7271 default:
7272 {
7273 if (m_it.primitive_iterator == -n)
7274 {
7275 return *m_object;
7276 }
7277 else
7278 {
7279 throw std::out_of_range("cannot get value");
7280 }
7281 }
7282 }
7283 }
7284
7285 /*!
7286 @brief return the key of an object iterator
7287 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7288 */
key() const7289 typename object_t::key_type key() const
7290 {
7291 assert(m_object != nullptr);
7292
7293 if (m_object->is_object())
7294 {
7295 return m_it.object_iterator->first;
7296 }
7297 else
7298 {
7299 throw std::domain_error("cannot use key() for non-object iterators");
7300 }
7301 }
7302
7303 /*!
7304 @brief return the value of an iterator
7305 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7306 */
value() const7307 reference value() const
7308 {
7309 return operator*();
7310 }
7311
7312 private:
7313 /// associated JSON instance
7314 pointer m_object = nullptr;
7315 /// the actual iterator of the associated instance
7316 internal_iterator m_it = internal_iterator();
7317 };
7318
7319 /*!
7320 @brief a mutable random access iterator for the @ref basic_json class
7321
7322 @requirement The class satisfies the following concept requirements:
7323 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
7324 The iterator that can be moved to point (forward and backward) to any
7325 element in constant time.
7326 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
7327 It is possible to write to the pointed-to element.
7328
7329 @since version 1.0.0
7330 */
7331 class iterator : public const_iterator
7332 {
7333 public:
7334 using base_iterator = const_iterator;
7335 using pointer = typename basic_json::pointer;
7336 using reference = typename basic_json::reference;
7337
7338 /// default constructor
7339 iterator() = default;
7340
7341 /// constructor for a given JSON instance
iterator(pointer object)7342 explicit iterator(pointer object) noexcept
7343 : base_iterator(object)
7344 {}
7345
7346 /// copy constructor
iterator(const iterator & other)7347 iterator(const iterator& other) noexcept
7348 : base_iterator(other)
7349 {}
7350
7351 /// copy assignment
operator =(iterator other)7352 iterator& operator=(iterator other) noexcept(
7353 std::is_nothrow_move_constructible<pointer>::value and
7354 std::is_nothrow_move_assignable<pointer>::value and
7355 std::is_nothrow_move_constructible<internal_iterator>::value and
7356 std::is_nothrow_move_assignable<internal_iterator>::value
7357 )
7358 {
7359 base_iterator::operator=(other);
7360 return *this;
7361 }
7362
7363 /// return a reference to the value pointed to by the iterator
operator *() const7364 reference operator*() const
7365 {
7366 return const_cast<reference>(base_iterator::operator*());
7367 }
7368
7369 /// dereference the iterator
operator ->() const7370 pointer operator->() const
7371 {
7372 return const_cast<pointer>(base_iterator::operator->());
7373 }
7374
7375 /// post-increment (it++)
operator ++(int)7376 iterator operator++(int)
7377 {
7378 iterator result = *this;
7379 base_iterator::operator++();
7380 return result;
7381 }
7382
7383 /// pre-increment (++it)
operator ++()7384 iterator& operator++()
7385 {
7386 base_iterator::operator++();
7387 return *this;
7388 }
7389
7390 /// post-decrement (it--)
operator --(int)7391 iterator operator--(int)
7392 {
7393 iterator result = *this;
7394 base_iterator::operator--();
7395 return result;
7396 }
7397
7398 /// pre-decrement (--it)
operator --()7399 iterator& operator--()
7400 {
7401 base_iterator::operator--();
7402 return *this;
7403 }
7404
7405 /// add to iterator
operator +=(difference_type i)7406 iterator& operator+=(difference_type i)
7407 {
7408 base_iterator::operator+=(i);
7409 return *this;
7410 }
7411
7412 /// subtract from iterator
operator -=(difference_type i)7413 iterator& operator-=(difference_type i)
7414 {
7415 base_iterator::operator-=(i);
7416 return *this;
7417 }
7418
7419 /// add to iterator
operator +(difference_type i)7420 iterator operator+(difference_type i)
7421 {
7422 auto result = *this;
7423 result += i;
7424 return result;
7425 }
7426
7427 /// subtract from iterator
operator -(difference_type i)7428 iterator operator-(difference_type i)
7429 {
7430 auto result = *this;
7431 result -= i;
7432 return result;
7433 }
7434
7435 /// return difference
operator -(const iterator & other) const7436 difference_type operator-(const iterator& other) const
7437 {
7438 return base_iterator::operator-(other);
7439 }
7440
7441 /// access to successor
operator [](difference_type n) const7442 reference operator[](difference_type n) const
7443 {
7444 return const_cast<reference>(base_iterator::operator[](n));
7445 }
7446
7447 /// return the value of an iterator
value() const7448 reference value() const
7449 {
7450 return const_cast<reference>(base_iterator::value());
7451 }
7452 };
7453
7454 /*!
7455 @brief a template for a reverse iterator class
7456
7457 @tparam Base the base iterator type to reverse. Valid types are @ref
7458 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
7459 create @ref const_reverse_iterator).
7460
7461 @requirement The class satisfies the following concept requirements:
7462 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
7463 The iterator that can be moved to point (forward and backward) to any
7464 element in constant time.
7465 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
7466 It is possible to write to the pointed-to element (only if @a Base is
7467 @ref iterator).
7468
7469 @since version 1.0.0
7470 */
7471 template<typename Base>
7472 class json_reverse_iterator : public std::reverse_iterator<Base>
7473 {
7474 public:
7475 /// shortcut to the reverse iterator adaptor
7476 using base_iterator = std::reverse_iterator<Base>;
7477 /// the reference type for the pointed-to element
7478 using reference = typename Base::reference;
7479
7480 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)7481 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
7482 : base_iterator(it)
7483 {}
7484
7485 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)7486 json_reverse_iterator(const base_iterator& it) noexcept
7487 : base_iterator(it)
7488 {}
7489
7490 /// post-increment (it++)
operator ++(int)7491 json_reverse_iterator operator++(int)
7492 {
7493 return base_iterator::operator++(1);
7494 }
7495
7496 /// pre-increment (++it)
operator ++()7497 json_reverse_iterator& operator++()
7498 {
7499 base_iterator::operator++();
7500 return *this;
7501 }
7502
7503 /// post-decrement (it--)
operator --(int)7504 json_reverse_iterator operator--(int)
7505 {
7506 return base_iterator::operator--(1);
7507 }
7508
7509 /// pre-decrement (--it)
operator --()7510 json_reverse_iterator& operator--()
7511 {
7512 base_iterator::operator--();
7513 return *this;
7514 }
7515
7516 /// add to iterator
operator +=(difference_type i)7517 json_reverse_iterator& operator+=(difference_type i)
7518 {
7519 base_iterator::operator+=(i);
7520 return *this;
7521 }
7522
7523 /// add to iterator
operator +(difference_type i) const7524 json_reverse_iterator operator+(difference_type i) const
7525 {
7526 auto result = *this;
7527 result += i;
7528 return result;
7529 }
7530
7531 /// subtract from iterator
operator -(difference_type i) const7532 json_reverse_iterator operator-(difference_type i) const
7533 {
7534 auto result = *this;
7535 result -= i;
7536 return result;
7537 }
7538
7539 /// return difference
operator -(const json_reverse_iterator & other) const7540 difference_type operator-(const json_reverse_iterator& other) const
7541 {
7542 return this->base() - other.base();
7543 }
7544
7545 /// access to successor
operator [](difference_type n) const7546 reference operator[](difference_type n) const
7547 {
7548 return *(this->operator+(n));
7549 }
7550
7551 /// return the key of an object iterator
key() const7552 typename object_t::key_type key() const
7553 {
7554 auto it = --this->base();
7555 return it.key();
7556 }
7557
7558 /// return the value of an iterator
value() const7559 reference value() const
7560 {
7561 auto it = --this->base();
7562 return it.operator * ();
7563 }
7564 };
7565
7566
7567 private:
7568 //////////////////////
7569 // lexer and parser //
7570 //////////////////////
7571
7572 /*!
7573 @brief lexical analysis
7574
7575 This class organizes the lexical analysis during JSON deserialization. The
7576 core of it is a scanner generated by [re2c](http://re2c.org) that
7577 processes a buffer and recognizes tokens according to RFC 7159.
7578 */
7579 class lexer
7580 {
7581 public:
7582 /// token types for the parser
7583 enum class token_type
7584 {
7585 uninitialized, ///< indicating the scanner is uninitialized
7586 literal_true, ///< the `true` literal
7587 literal_false, ///< the `false` literal
7588 literal_null, ///< the `null` literal
7589 value_string, ///< a string -- use get_string() for actual value
7590 value_number, ///< a number -- use get_number() for actual value
7591 begin_array, ///< the character for array begin `[`
7592 begin_object, ///< the character for object begin `{`
7593 end_array, ///< the character for array end `]`
7594 end_object, ///< the character for object end `}`
7595 name_separator, ///< the name separator `:`
7596 value_separator, ///< the value separator `,`
7597 parse_error, ///< indicating a parse error
7598 end_of_input ///< indicating the end of the input buffer
7599 };
7600
7601 /// the char type to use in the lexer
7602 using lexer_char_t = unsigned char;
7603
7604 /// a lexer from a buffer with given length
lexer(const lexer_char_t * buff,const size_t len)7605 lexer(const lexer_char_t* buff, const size_t len) noexcept
7606 : m_content(buff)
7607 {
7608 assert(m_content != nullptr);
7609 m_start = m_cursor = m_content;
7610 m_limit = m_content + len;
7611 }
7612
7613 /// a lexer from an input stream
lexer(std::istream & s)7614 explicit lexer(std::istream& s)
7615 : m_stream(&s), m_line_buffer()
7616 {
7617 // fill buffer
7618 fill_line_buffer();
7619 }
7620
7621 // switch off unwanted functions (due to pointer members)
7622 lexer() = delete;
7623 lexer(const lexer&) = delete;
7624 lexer operator=(const lexer&) = delete;
7625
7626 /*!
7627 @brief create a string from one or two Unicode code points
7628
7629 There are two cases: (1) @a codepoint1 is in the Basic Multilingual
7630 Plane (U+0000 through U+FFFF) and @a codepoint2 is 0, or (2)
7631 @a codepoint1 and @a codepoint2 are a UTF-16 surrogate pair to
7632 represent a code point above U+FFFF.
7633
7634 @param[in] codepoint1 the code point (can be high surrogate)
7635 @param[in] codepoint2 the code point (can be low surrogate or 0)
7636
7637 @return string representation of the code point; the length of the
7638 result string is between 1 and 4 characters.
7639
7640 @throw std::out_of_range if code point is > 0x10ffff; example: `"code
7641 points above 0x10FFFF are invalid"`
7642 @throw std::invalid_argument if the low surrogate is invalid; example:
7643 `""missing or wrong low surrogate""`
7644
7645 @complexity Constant.
7646
7647 @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
7648 */
to_unicode(const std::size_t codepoint1,const std::size_t codepoint2=0)7649 static string_t to_unicode(const std::size_t codepoint1,
7650 const std::size_t codepoint2 = 0)
7651 {
7652 // calculate the code point from the given code points
7653 std::size_t codepoint = codepoint1;
7654
7655 // check if codepoint1 is a high surrogate
7656 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7657 {
7658 // check if codepoint2 is a low surrogate
7659 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7660 {
7661 codepoint =
7662 // high surrogate occupies the most significant 22 bits
7663 (codepoint1 << 10)
7664 // low surrogate occupies the least significant 15 bits
7665 + codepoint2
7666 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7667 // in the result so we have to subtract with:
7668 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7669 - 0x35FDC00;
7670 }
7671 else
7672 {
7673 throw std::invalid_argument("missing or wrong low surrogate");
7674 }
7675 }
7676
7677 string_t result;
7678
7679 if (codepoint < 0x80)
7680 {
7681 // 1-byte characters: 0xxxxxxx (ASCII)
7682 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7683 }
7684 else if (codepoint <= 0x7ff)
7685 {
7686 // 2-byte characters: 110xxxxx 10xxxxxx
7687 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7688 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7689 }
7690 else if (codepoint <= 0xffff)
7691 {
7692 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7693 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7694 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7695 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7696 }
7697 else if (codepoint <= 0x10ffff)
7698 {
7699 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7700 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7701 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7702 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7703 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7704 }
7705 else
7706 {
7707 throw std::out_of_range("code points above 0x10FFFF are invalid");
7708 }
7709
7710 return result;
7711 }
7712
7713 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)7714 static std::string token_type_name(const token_type t)
7715 {
7716 switch (t)
7717 {
7718 case token_type::uninitialized:
7719 return "<uninitialized>";
7720 case token_type::literal_true:
7721 return "true literal";
7722 case token_type::literal_false:
7723 return "false literal";
7724 case token_type::literal_null:
7725 return "null literal";
7726 case token_type::value_string:
7727 return "string literal";
7728 case token_type::value_number:
7729 return "number literal";
7730 case token_type::begin_array:
7731 return "'['";
7732 case token_type::begin_object:
7733 return "'{'";
7734 case token_type::end_array:
7735 return "']'";
7736 case token_type::end_object:
7737 return "'}'";
7738 case token_type::name_separator:
7739 return "':'";
7740 case token_type::value_separator:
7741 return "','";
7742 case token_type::parse_error:
7743 return "<parse error>";
7744 case token_type::end_of_input:
7745 return "end of input";
7746 default:
7747 {
7748 // catch non-enum values
7749 return "unknown token"; // LCOV_EXCL_LINE
7750 }
7751 }
7752 }
7753
7754 /*!
7755 This function implements a scanner for JSON. It is specified using
7756 regular expressions that try to follow RFC 7159 as close as possible.
7757 These regular expressions are then translated into a minimized
7758 deterministic finite automaton (DFA) by the tool
7759 [re2c](http://re2c.org). As a result, the translated code for this
7760 function consists of a large block of code with `goto` jumps.
7761
7762 @return the class of the next token read from the buffer
7763
7764 @complexity Linear in the length of the input.\n
7765
7766 Proposition: The loop below will always terminate for finite input.\n
7767
7768 Proof (by contradiction): Assume a finite input. To loop forever, the
7769 loop must never hit code with a `break` statement. The only code
7770 snippets without a `break` statement are the continue statements for
7771 whitespace and byte-order-marks. To loop forever, the input must be an
7772 infinite sequence of whitespace or byte-order-marks. This contradicts
7773 the assumption of finite input, q.e.d.
7774 */
scan()7775 token_type scan()
7776 {
7777 while (true)
7778 {
7779 // pointer for backtracking information
7780 m_marker = nullptr;
7781
7782 // remember the begin of the token
7783 m_start = m_cursor;
7784 assert(m_start != nullptr);
7785
7786
7787 {
7788 lexer_char_t yych;
7789 unsigned int yyaccept = 0;
7790 static const unsigned char yybm[] =
7791 {
7792 0, 0, 0, 0, 0, 0, 0, 0,
7793 0, 32, 32, 0, 0, 32, 0, 0,
7794 0, 0, 0, 0, 0, 0, 0, 0,
7795 0, 0, 0, 0, 0, 0, 0, 0,
7796 160, 128, 0, 128, 128, 128, 128, 128,
7797 128, 128, 128, 128, 128, 128, 128, 128,
7798 192, 192, 192, 192, 192, 192, 192, 192,
7799 192, 192, 128, 128, 128, 128, 128, 128,
7800 128, 128, 128, 128, 128, 128, 128, 128,
7801 128, 128, 128, 128, 128, 128, 128, 128,
7802 128, 128, 128, 128, 128, 128, 128, 128,
7803 128, 128, 128, 128, 0, 128, 128, 128,
7804 128, 128, 128, 128, 128, 128, 128, 128,
7805 128, 128, 128, 128, 128, 128, 128, 128,
7806 128, 128, 128, 128, 128, 128, 128, 128,
7807 128, 128, 128, 128, 128, 128, 128, 128,
7808 128, 128, 128, 128, 128, 128, 128, 128,
7809 128, 128, 128, 128, 128, 128, 128, 128,
7810 128, 128, 128, 128, 128, 128, 128, 128,
7811 128, 128, 128, 128, 128, 128, 128, 128,
7812 128, 128, 128, 128, 128, 128, 128, 128,
7813 128, 128, 128, 128, 128, 128, 128, 128,
7814 128, 128, 128, 128, 128, 128, 128, 128,
7815 128, 128, 128, 128, 128, 128, 128, 128,
7816 128, 128, 128, 128, 128, 128, 128, 128,
7817 128, 128, 128, 128, 128, 128, 128, 128,
7818 128, 128, 128, 128, 128, 128, 128, 128,
7819 128, 128, 128, 128, 128, 128, 128, 128,
7820 128, 128, 128, 128, 128, 128, 128, 128,
7821 128, 128, 128, 128, 128, 128, 128, 128,
7822 128, 128, 128, 128, 128, 128, 128, 128,
7823 128, 128, 128, 128, 128, 128, 128, 128,
7824 };
7825 if ((m_limit - m_cursor) < 5)
7826 {
7827 fill_line_buffer();
7828 }
7829 yych = *m_cursor;
7830 if (yybm[0 + yych] & 32)
7831 {
7832 goto basic_json_parser_6;
7833 }
7834 if (yych <= '\\')
7835 {
7836 if (yych <= '-')
7837 {
7838 if (yych <= '"')
7839 {
7840 if (yych <= 0x00)
7841 {
7842 goto basic_json_parser_2;
7843 }
7844 if (yych <= '!')
7845 {
7846 goto basic_json_parser_4;
7847 }
7848 goto basic_json_parser_9;
7849 }
7850 else
7851 {
7852 if (yych <= '+')
7853 {
7854 goto basic_json_parser_4;
7855 }
7856 if (yych <= ',')
7857 {
7858 goto basic_json_parser_10;
7859 }
7860 goto basic_json_parser_12;
7861 }
7862 }
7863 else
7864 {
7865 if (yych <= '9')
7866 {
7867 if (yych <= '/')
7868 {
7869 goto basic_json_parser_4;
7870 }
7871 if (yych <= '0')
7872 {
7873 goto basic_json_parser_13;
7874 }
7875 goto basic_json_parser_15;
7876 }
7877 else
7878 {
7879 if (yych <= ':')
7880 {
7881 goto basic_json_parser_17;
7882 }
7883 if (yych == '[')
7884 {
7885 goto basic_json_parser_19;
7886 }
7887 goto basic_json_parser_4;
7888 }
7889 }
7890 }
7891 else
7892 {
7893 if (yych <= 't')
7894 {
7895 if (yych <= 'f')
7896 {
7897 if (yych <= ']')
7898 {
7899 goto basic_json_parser_21;
7900 }
7901 if (yych <= 'e')
7902 {
7903 goto basic_json_parser_4;
7904 }
7905 goto basic_json_parser_23;
7906 }
7907 else
7908 {
7909 if (yych == 'n')
7910 {
7911 goto basic_json_parser_24;
7912 }
7913 if (yych <= 's')
7914 {
7915 goto basic_json_parser_4;
7916 }
7917 goto basic_json_parser_25;
7918 }
7919 }
7920 else
7921 {
7922 if (yych <= '|')
7923 {
7924 if (yych == '{')
7925 {
7926 goto basic_json_parser_26;
7927 }
7928 goto basic_json_parser_4;
7929 }
7930 else
7931 {
7932 if (yych <= '}')
7933 {
7934 goto basic_json_parser_28;
7935 }
7936 if (yych == 0xEF)
7937 {
7938 goto basic_json_parser_30;
7939 }
7940 goto basic_json_parser_4;
7941 }
7942 }
7943 }
7944 basic_json_parser_2:
7945 ++m_cursor;
7946 {
7947 last_token_type = token_type::end_of_input;
7948 break;
7949 }
7950 basic_json_parser_4:
7951 ++m_cursor;
7952 basic_json_parser_5:
7953 {
7954 last_token_type = token_type::parse_error;
7955 break;
7956 }
7957 basic_json_parser_6:
7958 ++m_cursor;
7959 if (m_limit <= m_cursor)
7960 {
7961 fill_line_buffer();
7962 }
7963 yych = *m_cursor;
7964 if (yybm[0 + yych] & 32)
7965 {
7966 goto basic_json_parser_6;
7967 }
7968 {
7969 continue;
7970 }
7971 basic_json_parser_9:
7972 yyaccept = 0;
7973 yych = *(m_marker = ++m_cursor);
7974 if (yych <= 0x1F)
7975 {
7976 goto basic_json_parser_5;
7977 }
7978 goto basic_json_parser_32;
7979 basic_json_parser_10:
7980 ++m_cursor;
7981 {
7982 last_token_type = token_type::value_separator;
7983 break;
7984 }
7985 basic_json_parser_12:
7986 yych = *++m_cursor;
7987 if (yych <= '/')
7988 {
7989 goto basic_json_parser_5;
7990 }
7991 if (yych <= '0')
7992 {
7993 goto basic_json_parser_13;
7994 }
7995 if (yych <= '9')
7996 {
7997 goto basic_json_parser_15;
7998 }
7999 goto basic_json_parser_5;
8000 basic_json_parser_13:
8001 yyaccept = 1;
8002 yych = *(m_marker = ++m_cursor);
8003 if (yych <= 'D')
8004 {
8005 if (yych == '.')
8006 {
8007 goto basic_json_parser_37;
8008 }
8009 }
8010 else
8011 {
8012 if (yych <= 'E')
8013 {
8014 goto basic_json_parser_38;
8015 }
8016 if (yych == 'e')
8017 {
8018 goto basic_json_parser_38;
8019 }
8020 }
8021 basic_json_parser_14:
8022 {
8023 last_token_type = token_type::value_number;
8024 break;
8025 }
8026 basic_json_parser_15:
8027 yyaccept = 1;
8028 m_marker = ++m_cursor;
8029 if ((m_limit - m_cursor) < 3)
8030 {
8031 fill_line_buffer();
8032 }
8033 yych = *m_cursor;
8034 if (yybm[0 + yych] & 64)
8035 {
8036 goto basic_json_parser_15;
8037 }
8038 if (yych <= 'D')
8039 {
8040 if (yych == '.')
8041 {
8042 goto basic_json_parser_37;
8043 }
8044 goto basic_json_parser_14;
8045 }
8046 else
8047 {
8048 if (yych <= 'E')
8049 {
8050 goto basic_json_parser_38;
8051 }
8052 if (yych == 'e')
8053 {
8054 goto basic_json_parser_38;
8055 }
8056 goto basic_json_parser_14;
8057 }
8058 basic_json_parser_17:
8059 ++m_cursor;
8060 {
8061 last_token_type = token_type::name_separator;
8062 break;
8063 }
8064 basic_json_parser_19:
8065 ++m_cursor;
8066 {
8067 last_token_type = token_type::begin_array;
8068 break;
8069 }
8070 basic_json_parser_21:
8071 ++m_cursor;
8072 {
8073 last_token_type = token_type::end_array;
8074 break;
8075 }
8076 basic_json_parser_23:
8077 yyaccept = 0;
8078 yych = *(m_marker = ++m_cursor);
8079 if (yych == 'a')
8080 {
8081 goto basic_json_parser_39;
8082 }
8083 goto basic_json_parser_5;
8084 basic_json_parser_24:
8085 yyaccept = 0;
8086 yych = *(m_marker = ++m_cursor);
8087 if (yych == 'u')
8088 {
8089 goto basic_json_parser_40;
8090 }
8091 goto basic_json_parser_5;
8092 basic_json_parser_25:
8093 yyaccept = 0;
8094 yych = *(m_marker = ++m_cursor);
8095 if (yych == 'r')
8096 {
8097 goto basic_json_parser_41;
8098 }
8099 goto basic_json_parser_5;
8100 basic_json_parser_26:
8101 ++m_cursor;
8102 {
8103 last_token_type = token_type::begin_object;
8104 break;
8105 }
8106 basic_json_parser_28:
8107 ++m_cursor;
8108 {
8109 last_token_type = token_type::end_object;
8110 break;
8111 }
8112 basic_json_parser_30:
8113 yyaccept = 0;
8114 yych = *(m_marker = ++m_cursor);
8115 if (yych == 0xBB)
8116 {
8117 goto basic_json_parser_42;
8118 }
8119 goto basic_json_parser_5;
8120 basic_json_parser_31:
8121 ++m_cursor;
8122 if (m_limit <= m_cursor)
8123 {
8124 fill_line_buffer();
8125 }
8126 yych = *m_cursor;
8127 basic_json_parser_32:
8128 if (yybm[0 + yych] & 128)
8129 {
8130 goto basic_json_parser_31;
8131 }
8132 if (yych <= 0x1F)
8133 {
8134 goto basic_json_parser_33;
8135 }
8136 if (yych <= '"')
8137 {
8138 goto basic_json_parser_34;
8139 }
8140 goto basic_json_parser_36;
8141 basic_json_parser_33:
8142 m_cursor = m_marker;
8143 if (yyaccept == 0)
8144 {
8145 goto basic_json_parser_5;
8146 }
8147 else
8148 {
8149 goto basic_json_parser_14;
8150 }
8151 basic_json_parser_34:
8152 ++m_cursor;
8153 {
8154 last_token_type = token_type::value_string;
8155 break;
8156 }
8157 basic_json_parser_36:
8158 ++m_cursor;
8159 if (m_limit <= m_cursor)
8160 {
8161 fill_line_buffer();
8162 }
8163 yych = *m_cursor;
8164 if (yych <= 'e')
8165 {
8166 if (yych <= '/')
8167 {
8168 if (yych == '"')
8169 {
8170 goto basic_json_parser_31;
8171 }
8172 if (yych <= '.')
8173 {
8174 goto basic_json_parser_33;
8175 }
8176 goto basic_json_parser_31;
8177 }
8178 else
8179 {
8180 if (yych <= '\\')
8181 {
8182 if (yych <= '[')
8183 {
8184 goto basic_json_parser_33;
8185 }
8186 goto basic_json_parser_31;
8187 }
8188 else
8189 {
8190 if (yych == 'b')
8191 {
8192 goto basic_json_parser_31;
8193 }
8194 goto basic_json_parser_33;
8195 }
8196 }
8197 }
8198 else
8199 {
8200 if (yych <= 'q')
8201 {
8202 if (yych <= 'f')
8203 {
8204 goto basic_json_parser_31;
8205 }
8206 if (yych == 'n')
8207 {
8208 goto basic_json_parser_31;
8209 }
8210 goto basic_json_parser_33;
8211 }
8212 else
8213 {
8214 if (yych <= 's')
8215 {
8216 if (yych <= 'r')
8217 {
8218 goto basic_json_parser_31;
8219 }
8220 goto basic_json_parser_33;
8221 }
8222 else
8223 {
8224 if (yych <= 't')
8225 {
8226 goto basic_json_parser_31;
8227 }
8228 if (yych <= 'u')
8229 {
8230 goto basic_json_parser_43;
8231 }
8232 goto basic_json_parser_33;
8233 }
8234 }
8235 }
8236 basic_json_parser_37:
8237 yych = *++m_cursor;
8238 if (yych <= '/')
8239 {
8240 goto basic_json_parser_33;
8241 }
8242 if (yych <= '9')
8243 {
8244 goto basic_json_parser_44;
8245 }
8246 goto basic_json_parser_33;
8247 basic_json_parser_38:
8248 yych = *++m_cursor;
8249 if (yych <= ',')
8250 {
8251 if (yych == '+')
8252 {
8253 goto basic_json_parser_46;
8254 }
8255 goto basic_json_parser_33;
8256 }
8257 else
8258 {
8259 if (yych <= '-')
8260 {
8261 goto basic_json_parser_46;
8262 }
8263 if (yych <= '/')
8264 {
8265 goto basic_json_parser_33;
8266 }
8267 if (yych <= '9')
8268 {
8269 goto basic_json_parser_47;
8270 }
8271 goto basic_json_parser_33;
8272 }
8273 basic_json_parser_39:
8274 yych = *++m_cursor;
8275 if (yych == 'l')
8276 {
8277 goto basic_json_parser_49;
8278 }
8279 goto basic_json_parser_33;
8280 basic_json_parser_40:
8281 yych = *++m_cursor;
8282 if (yych == 'l')
8283 {
8284 goto basic_json_parser_50;
8285 }
8286 goto basic_json_parser_33;
8287 basic_json_parser_41:
8288 yych = *++m_cursor;
8289 if (yych == 'u')
8290 {
8291 goto basic_json_parser_51;
8292 }
8293 goto basic_json_parser_33;
8294 basic_json_parser_42:
8295 yych = *++m_cursor;
8296 if (yych == 0xBF)
8297 {
8298 goto basic_json_parser_52;
8299 }
8300 goto basic_json_parser_33;
8301 basic_json_parser_43:
8302 ++m_cursor;
8303 if (m_limit <= m_cursor)
8304 {
8305 fill_line_buffer();
8306 }
8307 yych = *m_cursor;
8308 if (yych <= '@')
8309 {
8310 if (yych <= '/')
8311 {
8312 goto basic_json_parser_33;
8313 }
8314 if (yych <= '9')
8315 {
8316 goto basic_json_parser_54;
8317 }
8318 goto basic_json_parser_33;
8319 }
8320 else
8321 {
8322 if (yych <= 'F')
8323 {
8324 goto basic_json_parser_54;
8325 }
8326 if (yych <= '`')
8327 {
8328 goto basic_json_parser_33;
8329 }
8330 if (yych <= 'f')
8331 {
8332 goto basic_json_parser_54;
8333 }
8334 goto basic_json_parser_33;
8335 }
8336 basic_json_parser_44:
8337 yyaccept = 1;
8338 m_marker = ++m_cursor;
8339 if ((m_limit - m_cursor) < 3)
8340 {
8341 fill_line_buffer();
8342 }
8343 yych = *m_cursor;
8344 if (yych <= 'D')
8345 {
8346 if (yych <= '/')
8347 {
8348 goto basic_json_parser_14;
8349 }
8350 if (yych <= '9')
8351 {
8352 goto basic_json_parser_44;
8353 }
8354 goto basic_json_parser_14;
8355 }
8356 else
8357 {
8358 if (yych <= 'E')
8359 {
8360 goto basic_json_parser_38;
8361 }
8362 if (yych == 'e')
8363 {
8364 goto basic_json_parser_38;
8365 }
8366 goto basic_json_parser_14;
8367 }
8368 basic_json_parser_46:
8369 yych = *++m_cursor;
8370 if (yych <= '/')
8371 {
8372 goto basic_json_parser_33;
8373 }
8374 if (yych >= ':')
8375 {
8376 goto basic_json_parser_33;
8377 }
8378 basic_json_parser_47:
8379 ++m_cursor;
8380 if (m_limit <= m_cursor)
8381 {
8382 fill_line_buffer();
8383 }
8384 yych = *m_cursor;
8385 if (yych <= '/')
8386 {
8387 goto basic_json_parser_14;
8388 }
8389 if (yych <= '9')
8390 {
8391 goto basic_json_parser_47;
8392 }
8393 goto basic_json_parser_14;
8394 basic_json_parser_49:
8395 yych = *++m_cursor;
8396 if (yych == 's')
8397 {
8398 goto basic_json_parser_55;
8399 }
8400 goto basic_json_parser_33;
8401 basic_json_parser_50:
8402 yych = *++m_cursor;
8403 if (yych == 'l')
8404 {
8405 goto basic_json_parser_56;
8406 }
8407 goto basic_json_parser_33;
8408 basic_json_parser_51:
8409 yych = *++m_cursor;
8410 if (yych == 'e')
8411 {
8412 goto basic_json_parser_58;
8413 }
8414 goto basic_json_parser_33;
8415 basic_json_parser_52:
8416 ++m_cursor;
8417 {
8418 continue;
8419 }
8420 basic_json_parser_54:
8421 ++m_cursor;
8422 if (m_limit <= m_cursor)
8423 {
8424 fill_line_buffer();
8425 }
8426 yych = *m_cursor;
8427 if (yych <= '@')
8428 {
8429 if (yych <= '/')
8430 {
8431 goto basic_json_parser_33;
8432 }
8433 if (yych <= '9')
8434 {
8435 goto basic_json_parser_60;
8436 }
8437 goto basic_json_parser_33;
8438 }
8439 else
8440 {
8441 if (yych <= 'F')
8442 {
8443 goto basic_json_parser_60;
8444 }
8445 if (yych <= '`')
8446 {
8447 goto basic_json_parser_33;
8448 }
8449 if (yych <= 'f')
8450 {
8451 goto basic_json_parser_60;
8452 }
8453 goto basic_json_parser_33;
8454 }
8455 basic_json_parser_55:
8456 yych = *++m_cursor;
8457 if (yych == 'e')
8458 {
8459 goto basic_json_parser_61;
8460 }
8461 goto basic_json_parser_33;
8462 basic_json_parser_56:
8463 ++m_cursor;
8464 {
8465 last_token_type = token_type::literal_null;
8466 break;
8467 }
8468 basic_json_parser_58:
8469 ++m_cursor;
8470 {
8471 last_token_type = token_type::literal_true;
8472 break;
8473 }
8474 basic_json_parser_60:
8475 ++m_cursor;
8476 if (m_limit <= m_cursor)
8477 {
8478 fill_line_buffer();
8479 }
8480 yych = *m_cursor;
8481 if (yych <= '@')
8482 {
8483 if (yych <= '/')
8484 {
8485 goto basic_json_parser_33;
8486 }
8487 if (yych <= '9')
8488 {
8489 goto basic_json_parser_63;
8490 }
8491 goto basic_json_parser_33;
8492 }
8493 else
8494 {
8495 if (yych <= 'F')
8496 {
8497 goto basic_json_parser_63;
8498 }
8499 if (yych <= '`')
8500 {
8501 goto basic_json_parser_33;
8502 }
8503 if (yych <= 'f')
8504 {
8505 goto basic_json_parser_63;
8506 }
8507 goto basic_json_parser_33;
8508 }
8509 basic_json_parser_61:
8510 ++m_cursor;
8511 {
8512 last_token_type = token_type::literal_false;
8513 break;
8514 }
8515 basic_json_parser_63:
8516 ++m_cursor;
8517 if (m_limit <= m_cursor)
8518 {
8519 fill_line_buffer();
8520 }
8521 yych = *m_cursor;
8522 if (yych <= '@')
8523 {
8524 if (yych <= '/')
8525 {
8526 goto basic_json_parser_33;
8527 }
8528 if (yych <= '9')
8529 {
8530 goto basic_json_parser_31;
8531 }
8532 goto basic_json_parser_33;
8533 }
8534 else
8535 {
8536 if (yych <= 'F')
8537 {
8538 goto basic_json_parser_31;
8539 }
8540 if (yych <= '`')
8541 {
8542 goto basic_json_parser_33;
8543 }
8544 if (yych <= 'f')
8545 {
8546 goto basic_json_parser_31;
8547 }
8548 goto basic_json_parser_33;
8549 }
8550 }
8551
8552 }
8553
8554 return last_token_type;
8555 }
8556
8557 /*!
8558 @brief append data from the stream to the line buffer
8559
8560 This function is called by the scan() function when the end of the
8561 buffer (`m_limit`) is reached and the `m_cursor` pointer cannot be
8562 incremented without leaving the limits of the line buffer. Note re2c
8563 decides when to call this function.
8564
8565 If the lexer reads from contiguous storage, there is no trailing null
8566 byte. Therefore, this function must make sure to add these padding
8567 null bytes.
8568
8569 If the lexer reads from an input stream, this function reads the next
8570 line of the input.
8571
8572 @pre
8573 p p p p p p u u u u u x . . . . . .
8574 ^ ^ ^ ^
8575 m_content m_start | m_limit
8576 m_cursor
8577
8578 @post
8579 u u u u u x x x x x x x . . . . . .
8580 ^ ^ ^
8581 | m_cursor m_limit
8582 m_start
8583 m_content
8584 */
fill_line_buffer()8585 void fill_line_buffer()
8586 {
8587 // number of processed characters (p)
8588 const auto offset_start = m_start - m_content;
8589 // offset for m_marker wrt. to m_start
8590 const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
8591 // number of unprocessed characters (u)
8592 const auto offset_cursor = m_cursor - m_start;
8593
8594 // no stream is used or end of file is reached
8595 if (m_stream == nullptr or m_stream->eof())
8596 {
8597 // copy unprocessed characters to line buffer
8598 m_line_buffer.clear();
8599 for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor)
8600 {
8601 m_line_buffer.append(1, static_cast<const char>(*m_cursor));
8602 }
8603
8604 // append 5 characters (size of longest keyword "false") to
8605 // make sure that there is sufficient space between m_cursor
8606 // and m_limit
8607 m_line_buffer.append(5, '\0');
8608 }
8609 else
8610 {
8611 // delete processed characters from line buffer
8612 m_line_buffer.erase(0, static_cast<size_t>(offset_start));
8613 // read next line from input stream
8614 std::string line;
8615 std::getline(*m_stream, line);
8616 // add line with newline symbol to the line buffer
8617 m_line_buffer += line + "\n";
8618 }
8619
8620 // set pointers
8621 m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.c_str());
8622 assert(m_content != nullptr);
8623 m_start = m_content;
8624 m_marker = m_start + offset_marker;
8625 m_cursor = m_start + offset_cursor;
8626 m_limit = m_start + m_line_buffer.size();
8627 }
8628
8629 /// return string representation of last read token
get_token_string() const8630 string_t get_token_string() const
8631 {
8632 assert(m_start != nullptr);
8633 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
8634 static_cast<size_t>(m_cursor - m_start));
8635 }
8636
8637 /*!
8638 @brief return string value for string tokens
8639
8640 The function iterates the characters between the opening and closing
8641 quotes of the string value. The complete string is the range
8642 [m_start,m_cursor). Consequently, we iterate from m_start+1 to
8643 m_cursor-1.
8644
8645 We differentiate two cases:
8646
8647 1. Escaped characters. In this case, a new character is constructed
8648 according to the nature of the escape. Some escapes create new
8649 characters (e.g., `"\\n"` is replaced by `"\n"`), some are copied
8650 as is (e.g., `"\\\\"`). Furthermore, Unicode escapes of the shape
8651 `"\\uxxxx"` need special care. In this case, to_unicode takes care
8652 of the construction of the values.
8653 2. Unescaped characters are copied as is.
8654
8655 @pre `m_cursor - m_start >= 2`, meaning the length of the last token
8656 is at least 2 bytes which is trivially true for any string (which
8657 consists of at least two quotes).
8658
8659 " c1 c2 c3 ... "
8660 ^ ^
8661 m_start m_cursor
8662
8663 @complexity Linear in the length of the string.\n
8664
8665 Lemma: The loop body will always terminate.\n
8666
8667 Proof (by contradiction): Assume the loop body does not terminate. As
8668 the loop body does not contain another loop, one of the called
8669 functions must never return. The called functions are `std::strtoul`
8670 and to_unicode. Neither function can loop forever, so the loop body
8671 will never loop forever which contradicts the assumption that the loop
8672 body does not terminate, q.e.d.\n
8673
8674 Lemma: The loop condition for the for loop is eventually false.\n
8675
8676 Proof (by contradiction): Assume the loop does not terminate. Due to
8677 the above lemma, this can only be due to a tautological loop
8678 condition; that is, the loop condition i < m_cursor - 1 must always be
8679 true. Let x be the change of i for any loop iteration. Then
8680 m_start + 1 + x < m_cursor - 1 must hold to loop indefinitely. This
8681 can be rephrased to m_cursor - m_start - 2 > x. With the
8682 precondition, we x <= 0, meaning that the loop condition holds
8683 indefinitly if i is always decreased. However, observe that the value
8684 of i is strictly increasing with each iteration, as it is incremented
8685 by 1 in the iteration expression and never decremented inside the loop
8686 body. Hence, the loop condition will eventually be false which
8687 contradicts the assumption that the loop condition is a tautology,
8688 q.e.d.
8689
8690 @return string value of current token without opening and closing
8691 quotes
8692 @throw std::out_of_range if to_unicode fails
8693 */
get_string() const8694 string_t get_string() const
8695 {
8696 assert(m_cursor - m_start >= 2);
8697
8698 string_t result;
8699 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8700
8701 // iterate the result between the quotes
8702 for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8703 {
8704 // process escaped characters
8705 if (*i == '\\')
8706 {
8707 // read next character
8708 ++i;
8709
8710 switch (*i)
8711 {
8712 // the default escapes
8713 case 't':
8714 {
8715 result += "\t";
8716 break;
8717 }
8718 case 'b':
8719 {
8720 result += "\b";
8721 break;
8722 }
8723 case 'f':
8724 {
8725 result += "\f";
8726 break;
8727 }
8728 case 'n':
8729 {
8730 result += "\n";
8731 break;
8732 }
8733 case 'r':
8734 {
8735 result += "\r";
8736 break;
8737 }
8738 case '\\':
8739 {
8740 result += "\\";
8741 break;
8742 }
8743 case '/':
8744 {
8745 result += "/";
8746 break;
8747 }
8748 case '"':
8749 {
8750 result += "\"";
8751 break;
8752 }
8753
8754 // unicode
8755 case 'u':
8756 {
8757 // get code xxxx from uxxxx
8758 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8759 4).c_str(), nullptr, 16);
8760
8761 // check if codepoint is a high surrogate
8762 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8763 {
8764 // make sure there is a subsequent unicode
8765 if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
8766 {
8767 throw std::invalid_argument("missing low surrogate");
8768 }
8769
8770 // get code yyyy from uxxxx\uyyyy
8771 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8772 (i + 7), 4).c_str(), nullptr, 16);
8773 result += to_unicode(codepoint, codepoint2);
8774 // skip the next 10 characters (xxxx\uyyyy)
8775 i += 10;
8776 }
8777 else
8778 {
8779 // add unicode character(s)
8780 result += to_unicode(codepoint);
8781 // skip the next four characters (xxxx)
8782 i += 4;
8783 }
8784 break;
8785 }
8786 }
8787 }
8788 else
8789 {
8790 // all other characters are just copied to the end of the
8791 // string
8792 result.append(1, static_cast<typename string_t::value_type>(*i));
8793 }
8794 }
8795
8796 return result;
8797 }
8798
8799 /*!
8800 @brief parse floating point number
8801
8802 This function (and its overloads) serves to select the most approprate
8803 standard floating point number parsing function based on the type
8804 supplied via the first parameter. Set this to @a
8805 static_cast<number_float_t*>(nullptr).
8806
8807 @param[in] type the @ref number_float_t in use
8808
8809 @param[in,out] endptr recieves a pointer to the first character after
8810 the number
8811
8812 @return the floating point number
8813 */
str_to_float_t(long double *,char ** endptr) const8814 long double str_to_float_t(long double* /* type */, char** endptr) const
8815 {
8816 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8817 }
8818
8819 /*!
8820 @brief parse floating point number
8821
8822 This function (and its overloads) serves to select the most approprate
8823 standard floating point number parsing function based on the type
8824 supplied via the first parameter. Set this to @a
8825 static_cast<number_float_t*>(nullptr).
8826
8827 @param[in] type the @ref number_float_t in use
8828
8829 @param[in,out] endptr recieves a pointer to the first character after
8830 the number
8831
8832 @return the floating point number
8833 */
str_to_float_t(double *,char ** endptr) const8834 double str_to_float_t(double* /* type */, char** endptr) const
8835 {
8836 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8837 }
8838
8839 /*!
8840 @brief parse floating point number
8841
8842 This function (and its overloads) serves to select the most approprate
8843 standard floating point number parsing function based on the type
8844 supplied via the first parameter. Set this to @a
8845 static_cast<number_float_t*>(nullptr).
8846
8847 @param[in] type the @ref number_float_t in use
8848
8849 @param[in,out] endptr recieves a pointer to the first character after
8850 the number
8851
8852 @return the floating point number
8853 */
str_to_float_t(float *,char ** endptr) const8854 float str_to_float_t(float* /* type */, char** endptr) const
8855 {
8856 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8857 }
8858
8859 /*!
8860 @brief return number value for number tokens
8861
8862 This function translates the last token into the most appropriate
8863 number type (either integer, unsigned integer or floating point),
8864 which is passed back to the caller via the result parameter.
8865
8866 This function parses the integer component up to the radix point or
8867 exponent while collecting information about the 'floating point
8868 representation', which it stores in the result parameter. If there is
8869 no radix point or exponent, and the number can fit into a @ref
8870 number_integer_t or @ref number_unsigned_t then it sets the result
8871 parameter accordingly.
8872
8873 If the number is a floating point number the number is then parsed
8874 using @a std:strtod (or @a std:strtof or @a std::strtold).
8875
8876 @param[out] result @ref basic_json object to receive the number, or
8877 NAN if the conversion read past the current token. The latter case
8878 needs to be treated by the caller function.
8879 */
get_number(basic_json & result) const8880 void get_number(basic_json& result) const
8881 {
8882 assert(m_start != nullptr);
8883
8884 const lexer::lexer_char_t* curptr = m_start;
8885
8886 // accumulate the integer conversion result (unsigned for now)
8887 number_unsigned_t value = 0;
8888
8889 // maximum absolute value of the relevant integer type
8890 number_unsigned_t max;
8891
8892 // temporarily store the type to avoid unecessary bitfield access
8893 value_t type;
8894
8895 // look for sign
8896 if (*curptr == '-')
8897 {
8898 type = value_t::number_integer;
8899 max = static_cast<uint64_t>((std::numeric_limits<number_integer_t>::max)()) + 1;
8900 curptr++;
8901 }
8902 else
8903 {
8904 type = value_t::number_unsigned;
8905 max = static_cast<uint64_t>((std::numeric_limits<number_unsigned_t>::max)());
8906 }
8907
8908 // count the significant figures
8909 for (; curptr < m_cursor; curptr++)
8910 {
8911 // quickly skip tests if a digit
8912 if (*curptr < '0' || *curptr > '9')
8913 {
8914 if (*curptr == '.')
8915 {
8916 // don't count '.' but change to float
8917 type = value_t::number_float;
8918 continue;
8919 }
8920 // assume exponent (if not then will fail parse): change to
8921 // float, stop counting and record exponent details
8922 type = value_t::number_float;
8923 break;
8924 }
8925
8926 // skip if definitely not an integer
8927 if (type != value_t::number_float)
8928 {
8929 // multiply last value by ten and add the new digit
8930 auto temp = value * 10 + *curptr - '0';
8931
8932 // test for overflow
8933 if (temp < value || temp > max)
8934 {
8935 // overflow
8936 type = value_t::number_float;
8937 }
8938 else
8939 {
8940 // no overflow - save it
8941 value = temp;
8942 }
8943 }
8944 }
8945
8946 // save the value (if not a float)
8947 if (type == value_t::number_unsigned)
8948 {
8949 result.m_value.number_unsigned = value;
8950 }
8951 else if (type == value_t::number_integer)
8952 {
8953 result.m_value.number_integer = -static_cast<number_integer_t>(value);
8954 }
8955 else
8956 {
8957 // parse with strtod
8958 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(nullptr), NULL);
8959 }
8960
8961 // save the type
8962 result.m_type = type;
8963 }
8964
8965 private:
8966 /// optional input stream
8967 std::istream* m_stream = nullptr;
8968 /// line buffer buffer for m_stream
8969 string_t m_line_buffer {};
8970 /// the buffer pointer
8971 const lexer_char_t* m_content = nullptr;
8972 /// pointer to the beginning of the current symbol
8973 const lexer_char_t* m_start = nullptr;
8974 /// pointer for backtracking information
8975 const lexer_char_t* m_marker = nullptr;
8976 /// pointer to the current symbol
8977 const lexer_char_t* m_cursor = nullptr;
8978 /// pointer to the end of the buffer
8979 const lexer_char_t* m_limit = nullptr;
8980 /// the last token type
8981 token_type last_token_type = token_type::end_of_input;
8982 };
8983
8984 /*!
8985 @brief syntax analysis
8986
8987 This class implements a recursive decent parser.
8988 */
8989 class parser
8990 {
8991 public:
8992 /// a parser reading from a string literal
parser(const char * buff,const parser_callback_t cb=nullptr)8993 parser(const char* buff, const parser_callback_t cb = nullptr)
8994 : callback(cb),
8995 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
8996 {}
8997
8998 /// a parser reading from an input stream
parser(std::istream & is,const parser_callback_t cb=nullptr)8999 parser(std::istream& is, const parser_callback_t cb = nullptr)
9000 : callback(cb), m_lexer(is)
9001 {}
9002
9003 /// a parser reading from an iterator range with contiguous storage
9004 template<class IteratorType, typename std::enable_if<
9005 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
9006 , int>::type
9007 = 0>
parser(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr)9008 parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
9009 : callback(cb),
9010 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
9011 static_cast<size_t>(std::distance(first, last)))
9012 {}
9013
9014 /// public parser interface
parse()9015 basic_json parse()
9016 {
9017 // read first token
9018 get_token();
9019
9020 basic_json result = parse_internal(true);
9021 result.assert_invariant();
9022
9023 expect(lexer::token_type::end_of_input);
9024
9025 // return parser result and replace it with null in case the
9026 // top-level value was discarded by the callback function
9027 return result.is_discarded() ? basic_json() : std::move(result);
9028 }
9029
9030 private:
9031 /// the actual parser
parse_internal(bool keep)9032 basic_json parse_internal(bool keep)
9033 {
9034 auto result = basic_json(value_t::discarded);
9035
9036 switch (last_token)
9037 {
9038 case lexer::token_type::begin_object:
9039 {
9040 if (keep and (not callback
9041 or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
9042 {
9043 // explicitly set result to object to cope with {}
9044 result.m_type = value_t::object;
9045 result.m_value = value_t::object;
9046 }
9047
9048 // read next token
9049 get_token();
9050
9051 // closing } -> we are done
9052 if (last_token == lexer::token_type::end_object)
9053 {
9054 get_token();
9055 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
9056 {
9057 result = basic_json(value_t::discarded);
9058 }
9059 return result;
9060 }
9061
9062 // no comma is expected here
9063 unexpect(lexer::token_type::value_separator);
9064
9065 // otherwise: parse key-value pairs
9066 do
9067 {
9068 // ugly, but could be fixed with loop reorganization
9069 if (last_token == lexer::token_type::value_separator)
9070 {
9071 get_token();
9072 }
9073
9074 // store key
9075 expect(lexer::token_type::value_string);
9076 const auto key = m_lexer.get_string();
9077
9078 bool keep_tag = false;
9079 if (keep)
9080 {
9081 if (callback)
9082 {
9083 basic_json k(key);
9084 keep_tag = callback(depth, parse_event_t::key, k);
9085 }
9086 else
9087 {
9088 keep_tag = true;
9089 }
9090 }
9091
9092 // parse separator (:)
9093 get_token();
9094 expect(lexer::token_type::name_separator);
9095
9096 // parse and add value
9097 get_token();
9098 auto value = parse_internal(keep);
9099 if (keep and keep_tag and not value.is_discarded())
9100 {
9101 result[key] = std::move(value);
9102 }
9103 }
9104 while (last_token == lexer::token_type::value_separator);
9105
9106 // closing }
9107 expect(lexer::token_type::end_object);
9108 get_token();
9109 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
9110 {
9111 result = basic_json(value_t::discarded);
9112 }
9113
9114 return result;
9115 }
9116
9117 case lexer::token_type::begin_array:
9118 {
9119 if (keep and (not callback
9120 or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
9121 {
9122 // explicitly set result to object to cope with []
9123 result.m_type = value_t::array;
9124 result.m_value = value_t::array;
9125 }
9126
9127 // read next token
9128 get_token();
9129
9130 // closing ] -> we are done
9131 if (last_token == lexer::token_type::end_array)
9132 {
9133 get_token();
9134 if (callback and not callback(--depth, parse_event_t::array_end, result))
9135 {
9136 result = basic_json(value_t::discarded);
9137 }
9138 return result;
9139 }
9140
9141 // no comma is expected here
9142 unexpect(lexer::token_type::value_separator);
9143
9144 // otherwise: parse values
9145 do
9146 {
9147 // ugly, but could be fixed with loop reorganization
9148 if (last_token == lexer::token_type::value_separator)
9149 {
9150 get_token();
9151 }
9152
9153 // parse value
9154 auto value = parse_internal(keep);
9155 if (keep and not value.is_discarded())
9156 {
9157 result.push_back(std::move(value));
9158 }
9159 }
9160 while (last_token == lexer::token_type::value_separator);
9161
9162 // closing ]
9163 expect(lexer::token_type::end_array);
9164 get_token();
9165 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
9166 {
9167 result = basic_json(value_t::discarded);
9168 }
9169
9170 return result;
9171 }
9172
9173 case lexer::token_type::literal_null:
9174 {
9175 get_token();
9176 result.m_type = value_t::null;
9177 break;
9178 }
9179
9180 case lexer::token_type::value_string:
9181 {
9182 const auto s = m_lexer.get_string();
9183 get_token();
9184 result = basic_json(s);
9185 break;
9186 }
9187
9188 case lexer::token_type::literal_true:
9189 {
9190 get_token();
9191 result.m_type = value_t::boolean;
9192 result.m_value = true;
9193 break;
9194 }
9195
9196 case lexer::token_type::literal_false:
9197 {
9198 get_token();
9199 result.m_type = value_t::boolean;
9200 result.m_value = false;
9201 break;
9202 }
9203
9204 case lexer::token_type::value_number:
9205 {
9206 m_lexer.get_number(result);
9207 get_token();
9208 break;
9209 }
9210
9211 default:
9212 {
9213 // the last token was unexpected
9214 unexpect(last_token);
9215 }
9216 }
9217
9218 if (keep and callback and not callback(depth, parse_event_t::value, result))
9219 {
9220 result = basic_json(value_t::discarded);
9221 }
9222 return result;
9223 }
9224
9225 /// get next token from lexer
get_token()9226 typename lexer::token_type get_token()
9227 {
9228 last_token = m_lexer.scan();
9229 return last_token;
9230 }
9231
expect(typename lexer::token_type t) const9232 void expect(typename lexer::token_type t) const
9233 {
9234 if (t != last_token)
9235 {
9236 std::string error_msg = "parse error - unexpected ";
9237 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
9238 "'") :
9239 lexer::token_type_name(last_token));
9240 error_msg += "; expected " + lexer::token_type_name(t);
9241 throw std::invalid_argument(error_msg);
9242 }
9243 }
9244
unexpect(typename lexer::token_type t) const9245 void unexpect(typename lexer::token_type t) const
9246 {
9247 if (t == last_token)
9248 {
9249 std::string error_msg = "parse error - unexpected ";
9250 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
9251 "'") :
9252 lexer::token_type_name(last_token));
9253 throw std::invalid_argument(error_msg);
9254 }
9255 }
9256
9257 private:
9258 /// current level of recursion
9259 int depth = 0;
9260 /// callback function
9261 const parser_callback_t callback = nullptr;
9262 /// the type of the last read token
9263 typename lexer::token_type last_token = lexer::token_type::uninitialized;
9264 /// the lexer
9265 lexer m_lexer;
9266 };
9267
9268 public:
9269 /*!
9270 @brief JSON Pointer
9271
9272 A JSON pointer defines a string syntax for identifying a specific value
9273 within a JSON document. It can be used with functions `at` and
9274 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
9275
9276 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
9277
9278 @since version 2.0.0
9279 */
9280 class json_pointer
9281 {
9282 /// allow basic_json to access private members
9283 friend class basic_json;
9284
9285 public:
9286 /*!
9287 @brief create JSON pointer
9288
9289 Create a JSON pointer according to the syntax described in
9290 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
9291
9292 @param[in] s string representing the JSON pointer; if omitted, the
9293 empty string is assumed which references the whole JSON
9294 value
9295
9296 @throw std::domain_error if reference token is nonempty and does not
9297 begin with a slash (`/`); example: `"JSON pointer must be empty or
9298 begin with /"`
9299 @throw std::domain_error if a tilde (`~`) is not followed by `0`
9300 (representing `~`) or `1` (representing `/`); example: `"escape error:
9301 ~ must be followed with 0 or 1"`
9302
9303 @liveexample{The example shows the construction several valid JSON
9304 pointers as well as the exceptional behavior.,json_pointer}
9305
9306 @since version 2.0.0
9307 */
json_pointer(const std::string & s="")9308 explicit json_pointer(const std::string& s = "")
9309 : reference_tokens(split(s))
9310 {}
9311
9312 /*!
9313 @brief return a string representation of the JSON pointer
9314
9315 @invariant For each JSON pointer `ptr`, it holds:
9316 @code {.cpp}
9317 ptr == json_pointer(ptr.to_string());
9318 @endcode
9319
9320 @return a string representation of the JSON pointer
9321
9322 @liveexample{The example shows the result of `to_string`.,
9323 json_pointer__to_string}
9324
9325 @since version 2.0.0
9326 */
to_string() const9327 std::string to_string() const noexcept
9328 {
9329 return std::accumulate(reference_tokens.begin(),
9330 reference_tokens.end(), std::string{},
9331 [](const std::string & a, const std::string & b)
9332 {
9333 return a + "/" + escape(b);
9334 });
9335 }
9336
9337 /// @copydoc to_string()
operator std::string() const9338 operator std::string() const
9339 {
9340 return to_string();
9341 }
9342
9343 private:
9344 /// remove and return last reference pointer
pop_back()9345 std::string pop_back()
9346 {
9347 if (is_root())
9348 {
9349 throw std::domain_error("JSON pointer has no parent");
9350 }
9351
9352 auto last = reference_tokens.back();
9353 reference_tokens.pop_back();
9354 return last;
9355 }
9356
9357 /// return whether pointer points to the root document
is_root() const9358 bool is_root() const
9359 {
9360 return reference_tokens.empty();
9361 }
9362
top() const9363 json_pointer top() const
9364 {
9365 if (is_root())
9366 {
9367 throw std::domain_error("JSON pointer has no parent");
9368 }
9369
9370 json_pointer result = *this;
9371 result.reference_tokens = {reference_tokens[0]};
9372 return result;
9373 }
9374
9375 /*!
9376 @brief create and return a reference to the pointed to value
9377
9378 @complexity Linear in the number of reference tokens.
9379 */
get_and_create(reference j) const9380 reference get_and_create(reference j) const
9381 {
9382 pointer result = &j;
9383
9384 // in case no reference tokens exist, return a reference to the
9385 // JSON value j which will be overwritten by a primitive value
9386 for (const auto& reference_token : reference_tokens)
9387 {
9388 switch (result->m_type)
9389 {
9390 case value_t::null:
9391 {
9392 if (reference_token == "0")
9393 {
9394 // start a new array if reference token is 0
9395 result = &result->operator[](0);
9396 }
9397 else
9398 {
9399 // start a new object otherwise
9400 result = &result->operator[](reference_token);
9401 }
9402 break;
9403 }
9404
9405 case value_t::object:
9406 {
9407 // create an entry in the object
9408 result = &result->operator[](reference_token);
9409 break;
9410 }
9411
9412 case value_t::array:
9413 {
9414 // create an entry in the array
9415 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
9416 break;
9417 }
9418
9419 /*
9420 The following code is only reached if there exists a
9421 reference token _and_ the current value is primitive. In
9422 this case, we have an error situation, because primitive
9423 values may only occur as single value; that is, with an
9424 empty list of reference tokens.
9425 */
9426 default:
9427 {
9428 throw std::domain_error("invalid value to unflatten");
9429 }
9430 }
9431 }
9432
9433 return *result;
9434 }
9435
9436 /*!
9437 @brief return a reference to the pointed to value
9438
9439 @param[in] ptr a JSON value
9440
9441 @return reference to the JSON value pointed to by the JSON pointer
9442
9443 @complexity Linear in the length of the JSON pointer.
9444
9445 @throw std::out_of_range if the JSON pointer can not be resolved
9446 @throw std::domain_error if an array index begins with '0'
9447 @throw std::invalid_argument if an array index was not a number
9448 */
get_unchecked(pointer ptr) const9449 reference get_unchecked(pointer ptr) const
9450 {
9451 for (const auto& reference_token : reference_tokens)
9452 {
9453 switch (ptr->m_type)
9454 {
9455 case value_t::object:
9456 {
9457 // use unchecked object access
9458 ptr = &ptr->operator[](reference_token);
9459 break;
9460 }
9461
9462 case value_t::array:
9463 {
9464 // error condition (cf. RFC 6901, Sect. 4)
9465 if (reference_token.size() > 1 and reference_token[0] == '0')
9466 {
9467 throw std::domain_error("array index must not begin with '0'");
9468 }
9469
9470 if (reference_token == "-")
9471 {
9472 // explicityly treat "-" as index beyond the end
9473 ptr = &ptr->operator[](ptr->m_value.array->size());
9474 }
9475 else
9476 {
9477 // convert array index to number; unchecked access
9478 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
9479 }
9480 break;
9481 }
9482
9483 default:
9484 {
9485 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
9486 }
9487 }
9488 }
9489
9490 return *ptr;
9491 }
9492
get_checked(pointer ptr) const9493 reference get_checked(pointer ptr) const
9494 {
9495 for (const auto& reference_token : reference_tokens)
9496 {
9497 switch (ptr->m_type)
9498 {
9499 case value_t::object:
9500 {
9501 // note: at performs range check
9502 ptr = &ptr->at(reference_token);
9503 break;
9504 }
9505
9506 case value_t::array:
9507 {
9508 if (reference_token == "-")
9509 {
9510 // "-" always fails the range check
9511 throw std::out_of_range("array index '-' (" +
9512 std::to_string(ptr->m_value.array->size()) +
9513 ") is out of range");
9514 }
9515
9516 // error condition (cf. RFC 6901, Sect. 4)
9517 if (reference_token.size() > 1 and reference_token[0] == '0')
9518 {
9519 throw std::domain_error("array index must not begin with '0'");
9520 }
9521
9522 // note: at performs range check
9523 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
9524 break;
9525 }
9526
9527 default:
9528 {
9529 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
9530 }
9531 }
9532 }
9533
9534 return *ptr;
9535 }
9536
9537 /*!
9538 @brief return a const reference to the pointed to value
9539
9540 @param[in] ptr a JSON value
9541
9542 @return const reference to the JSON value pointed to by the JSON
9543 pointer
9544 */
get_unchecked(const_pointer ptr) const9545 const_reference get_unchecked(const_pointer ptr) const
9546 {
9547 for (const auto& reference_token : reference_tokens)
9548 {
9549 switch (ptr->m_type)
9550 {
9551 case value_t::object:
9552 {
9553 // use unchecked object access
9554 ptr = &ptr->operator[](reference_token);
9555 break;
9556 }
9557
9558 case value_t::array:
9559 {
9560 if (reference_token == "-")
9561 {
9562 // "-" cannot be used for const access
9563 throw std::out_of_range("array index '-' (" +
9564 std::to_string(ptr->m_value.array->size()) +
9565 ") is out of range");
9566 }
9567
9568 // error condition (cf. RFC 6901, Sect. 4)
9569 if (reference_token.size() > 1 and reference_token[0] == '0')
9570 {
9571 throw std::domain_error("array index must not begin with '0'");
9572 }
9573
9574 // use unchecked array access
9575 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
9576 break;
9577 }
9578
9579 default:
9580 {
9581 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
9582 }
9583 }
9584 }
9585
9586 return *ptr;
9587 }
9588
get_checked(const_pointer ptr) const9589 const_reference get_checked(const_pointer ptr) const
9590 {
9591 for (const auto& reference_token : reference_tokens)
9592 {
9593 switch (ptr->m_type)
9594 {
9595 case value_t::object:
9596 {
9597 // note: at performs range check
9598 ptr = &ptr->at(reference_token);
9599 break;
9600 }
9601
9602 case value_t::array:
9603 {
9604 if (reference_token == "-")
9605 {
9606 // "-" always fails the range check
9607 throw std::out_of_range("array index '-' (" +
9608 std::to_string(ptr->m_value.array->size()) +
9609 ") is out of range");
9610 }
9611
9612 // error condition (cf. RFC 6901, Sect. 4)
9613 if (reference_token.size() > 1 and reference_token[0] == '0')
9614 {
9615 throw std::domain_error("array index must not begin with '0'");
9616 }
9617
9618 // note: at performs range check
9619 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
9620 break;
9621 }
9622
9623 default:
9624 {
9625 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
9626 }
9627 }
9628 }
9629
9630 return *ptr;
9631 }
9632
9633 /// split the string input to reference tokens
split(const std::string & reference_string)9634 static std::vector<std::string> split(const std::string& reference_string)
9635 {
9636 std::vector<std::string> result;
9637
9638 // special case: empty reference string -> no reference tokens
9639 if (reference_string.empty())
9640 {
9641 return result;
9642 }
9643
9644 // check if nonempty reference string begins with slash
9645 if (reference_string[0] != '/')
9646 {
9647 throw std::domain_error("JSON pointer must be empty or begin with '/'");
9648 }
9649
9650 // extract the reference tokens:
9651 // - slash: position of the last read slash (or end of string)
9652 // - start: position after the previous slash
9653 for (
9654 // search for the first slash after the first character
9655 size_t slash = reference_string.find_first_of("/", 1),
9656 // set the beginning of the first reference token
9657 start = 1;
9658 // we can stop if start == string::npos+1 = 0
9659 start != 0;
9660 // set the beginning of the next reference token
9661 // (will eventually be 0 if slash == std::string::npos)
9662 start = slash + 1,
9663 // find next slash
9664 slash = reference_string.find_first_of("/", start))
9665 {
9666 // use the text between the beginning of the reference token
9667 // (start) and the last slash (slash).
9668 auto reference_token = reference_string.substr(start, slash - start);
9669
9670 // check reference tokens are properly escaped
9671 for (size_t pos = reference_token.find_first_of("~");
9672 pos != std::string::npos;
9673 pos = reference_token.find_first_of("~", pos + 1))
9674 {
9675 assert(reference_token[pos] == '~');
9676
9677 // ~ must be followed by 0 or 1
9678 if (pos == reference_token.size() - 1 or
9679 (reference_token[pos + 1] != '0' and
9680 reference_token[pos + 1] != '1'))
9681 {
9682 throw std::domain_error("escape error: '~' must be followed with '0' or '1'");
9683 }
9684 }
9685
9686 // finally, store the reference token
9687 unescape(reference_token);
9688 result.push_back(reference_token);
9689 }
9690
9691 return result;
9692 }
9693
9694 private:
9695 /*!
9696 @brief replace all occurrences of a substring by another string
9697
9698 @param[in,out] s the string to manipulate
9699 @param[in] f the substring to replace with @a t
9700 @param[in] t the string to replace @a f
9701
9702 @return The string @a s where all occurrences of @a f are replaced
9703 with @a t.
9704
9705 @pre The search string @a f must not be empty.
9706
9707 @since version 2.0.0
9708 */
replace_substring(std::string & s,const std::string & f,const std::string & t)9709 static void replace_substring(std::string& s,
9710 const std::string& f,
9711 const std::string& t)
9712 {
9713 assert(not f.empty());
9714
9715 for (
9716 size_t pos = s.find(f); // find first occurrence of f
9717 pos != std::string::npos; // make sure f was found
9718 s.replace(pos, f.size(), t), // replace with t
9719 pos = s.find(f, pos + t.size()) // find next occurrence of f
9720 );
9721 }
9722
9723 /// escape tilde and slash
escape(std::string s)9724 static std::string escape(std::string s)
9725 {
9726 // escape "~"" to "~0" and "/" to "~1"
9727 replace_substring(s, "~", "~0");
9728 replace_substring(s, "/", "~1");
9729 return s;
9730 }
9731
9732 /// unescape tilde and slash
unescape(std::string & s)9733 static void unescape(std::string& s)
9734 {
9735 // first transform any occurrence of the sequence '~1' to '/'
9736 replace_substring(s, "~1", "/");
9737 // then transform any occurrence of the sequence '~0' to '~'
9738 replace_substring(s, "~0", "~");
9739 }
9740
9741 /*!
9742 @param[in] reference_string the reference string to the current value
9743 @param[in] value the value to consider
9744 @param[in,out] result the result object to insert values to
9745
9746 @note Empty objects or arrays are flattened to `null`.
9747 */
flatten(const std::string & reference_string,const basic_json & value,basic_json & result)9748 static void flatten(const std::string& reference_string,
9749 const basic_json& value,
9750 basic_json& result)
9751 {
9752 switch (value.m_type)
9753 {
9754 case value_t::array:
9755 {
9756 if (value.m_value.array->empty())
9757 {
9758 // flatten empty array as null
9759 result[reference_string] = nullptr;
9760 }
9761 else
9762 {
9763 // iterate array and use index as reference string
9764 for (size_t i = 0; i < value.m_value.array->size(); ++i)
9765 {
9766 flatten(reference_string + "/" + std::to_string(i),
9767 value.m_value.array->operator[](i), result);
9768 }
9769 }
9770 break;
9771 }
9772
9773 case value_t::object:
9774 {
9775 if (value.m_value.object->empty())
9776 {
9777 // flatten empty object as null
9778 result[reference_string] = nullptr;
9779 }
9780 else
9781 {
9782 // iterate object and use keys as reference string
9783 for (const auto& element : *value.m_value.object)
9784 {
9785 flatten(reference_string + "/" + escape(element.first),
9786 element.second, result);
9787 }
9788 }
9789 break;
9790 }
9791
9792 default:
9793 {
9794 // add primitive value with its reference string
9795 result[reference_string] = value;
9796 break;
9797 }
9798 }
9799 }
9800
9801 /*!
9802 @param[in] value flattened JSON
9803
9804 @return unflattened JSON
9805 */
unflatten(const basic_json & value)9806 static basic_json unflatten(const basic_json& value)
9807 {
9808 if (not value.is_object())
9809 {
9810 throw std::domain_error("only objects can be unflattened");
9811 }
9812
9813 basic_json result;
9814
9815 // iterate the JSON object values
9816 for (const auto& element : *value.m_value.object)
9817 {
9818 if (not element.second.is_primitive())
9819 {
9820 throw std::domain_error("values in object must be primitive");
9821 }
9822
9823 // assign value to reference pointed to by JSON pointer; Note
9824 // that if the JSON pointer is "" (i.e., points to the whole
9825 // value), function get_and_create returns a reference to
9826 // result itself. An assignment will then create a primitive
9827 // value.
9828 json_pointer(element.first).get_and_create(result) = element.second;
9829 }
9830
9831 return result;
9832 }
9833
9834 private:
9835 /// the reference tokens
9836 std::vector<std::string> reference_tokens {};
9837 };
9838
9839 //////////////////////////
9840 // JSON Pointer support //
9841 //////////////////////////
9842
9843 /// @name JSON Pointer functions
9844 /// @{
9845
9846 /*!
9847 @brief access specified element via JSON Pointer
9848
9849 Uses a JSON pointer to retrieve a reference to the respective JSON value.
9850 No bound checking is performed. Similar to @ref operator[](const typename
9851 object_t::key_type&), `null` values are created in arrays and objects if
9852 necessary.
9853
9854 In particular:
9855 - If the JSON pointer points to an object key that does not exist, it
9856 is created an filled with a `null` value before a reference to it
9857 is returned.
9858 - If the JSON pointer points to an array index that does not exist, it
9859 is created an filled with a `null` value before a reference to it
9860 is returned. All indices between the current maximum and the given
9861 index are also filled with `null`.
9862 - The special value `-` is treated as a synonym for the index past the
9863 end.
9864
9865 @param[in] ptr a JSON pointer
9866
9867 @return reference to the element pointed to by @a ptr
9868
9869 @complexity Constant.
9870
9871 @throw std::out_of_range if the JSON pointer can not be resolved
9872 @throw std::domain_error if an array index begins with '0'
9873 @throw std::invalid_argument if an array index was not a number
9874
9875 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
9876
9877 @since version 2.0.0
9878 */
operator [](const json_pointer & ptr)9879 reference operator[](const json_pointer& ptr)
9880 {
9881 return ptr.get_unchecked(this);
9882 }
9883
9884 /*!
9885 @brief access specified element via JSON Pointer
9886
9887 Uses a JSON pointer to retrieve a reference to the respective JSON value.
9888 No bound checking is performed. The function does not change the JSON
9889 value; no `null` values are created. In particular, the the special value
9890 `-` yields an exception.
9891
9892 @param[in] ptr JSON pointer to the desired element
9893
9894 @return const reference to the element pointed to by @a ptr
9895
9896 @complexity Constant.
9897
9898 @throw std::out_of_range if the JSON pointer can not be resolved
9899 @throw std::domain_error if an array index begins with '0'
9900 @throw std::invalid_argument if an array index was not a number
9901
9902 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
9903
9904 @since version 2.0.0
9905 */
operator [](const json_pointer & ptr) const9906 const_reference operator[](const json_pointer& ptr) const
9907 {
9908 return ptr.get_unchecked(this);
9909 }
9910
9911 /*!
9912 @brief access specified element via JSON Pointer
9913
9914 Returns a reference to the element at with specified JSON pointer @a ptr,
9915 with bounds checking.
9916
9917 @param[in] ptr JSON pointer to the desired element
9918
9919 @return reference to the element pointed to by @a ptr
9920
9921 @complexity Constant.
9922
9923 @throw std::out_of_range if the JSON pointer can not be resolved
9924 @throw std::domain_error if an array index begins with '0'
9925 @throw std::invalid_argument if an array index was not a number
9926
9927 @liveexample{The behavior is shown in the example.,at_json_pointer}
9928
9929 @since version 2.0.0
9930 */
at(const json_pointer & ptr)9931 reference at(const json_pointer& ptr)
9932 {
9933 return ptr.get_checked(this);
9934 }
9935
9936 /*!
9937 @brief access specified element via JSON Pointer
9938
9939 Returns a const reference to the element at with specified JSON pointer @a
9940 ptr, with bounds checking.
9941
9942 @param[in] ptr JSON pointer to the desired element
9943
9944 @return reference to the element pointed to by @a ptr
9945
9946 @complexity Constant.
9947
9948 @throw std::out_of_range if the JSON pointer can not be resolved
9949 @throw std::domain_error if an array index begins with '0'
9950 @throw std::invalid_argument if an array index was not a number
9951
9952 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
9953
9954 @since version 2.0.0
9955 */
at(const json_pointer & ptr) const9956 const_reference at(const json_pointer& ptr) const
9957 {
9958 return ptr.get_checked(this);
9959 }
9960
9961 /*!
9962 @brief return flattened JSON value
9963
9964 The function creates a JSON object whose keys are JSON pointers (see [RFC
9965 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
9966 primitive. The original JSON value can be restored using the @ref
9967 unflatten() function.
9968
9969 @return an object that maps JSON pointers to primitve values
9970
9971 @note Empty objects and arrays are flattened to `null` and will not be
9972 reconstructed correctly by the @ref unflatten() function.
9973
9974 @complexity Linear in the size the JSON value.
9975
9976 @liveexample{The following code shows how a JSON object is flattened to an
9977 object whose keys consist of JSON pointers.,flatten}
9978
9979 @sa @ref unflatten() for the reverse function
9980
9981 @since version 2.0.0
9982 */
flatten() const9983 basic_json flatten() const
9984 {
9985 basic_json result(value_t::object);
9986 json_pointer::flatten("", *this, result);
9987 return result;
9988 }
9989
9990 /*!
9991 @brief unflatten a previously flattened JSON value
9992
9993 The function restores the arbitrary nesting of a JSON value that has been
9994 flattened before using the @ref flatten() function. The JSON value must
9995 meet certain constraints:
9996 1. The value must be an object.
9997 2. The keys must be JSON pointers (see
9998 [RFC 6901](https://tools.ietf.org/html/rfc6901))
9999 3. The mapped values must be primitive JSON types.
10000
10001 @return the original JSON from a flattened version
10002
10003 @note Empty objects and arrays are flattened by @ref flatten() to `null`
10004 values and can not unflattened to their original type. Apart from
10005 this example, for a JSON value `j`, the following is always true:
10006 `j == j.flatten().unflatten()`.
10007
10008 @complexity Linear in the size the JSON value.
10009
10010 @liveexample{The following code shows how a flattened JSON object is
10011 unflattened into the original nested JSON object.,unflatten}
10012
10013 @sa @ref flatten() for the reverse function
10014
10015 @since version 2.0.0
10016 */
unflatten() const10017 basic_json unflatten() const
10018 {
10019 return json_pointer::unflatten(*this);
10020 }
10021
10022 /// @}
10023
10024 //////////////////////////
10025 // JSON Patch functions //
10026 //////////////////////////
10027
10028 /// @name JSON Patch functions
10029 /// @{
10030
10031 /*!
10032 @brief applies a JSON patch
10033
10034 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
10035 expressing a sequence of operations to apply to a JSON) document. With
10036 this funcion, a JSON Patch is applied to the current JSON value by
10037 executing all operations from the patch.
10038
10039 @param[in] json_patch JSON patch document
10040 @return patched document
10041
10042 @note The application of a patch is atomic: Either all operations succeed
10043 and the patched document is returned or an exception is thrown. In
10044 any case, the original value is not changed: the patch is applied
10045 to a copy of the value.
10046
10047 @throw std::out_of_range if a JSON pointer inside the patch could not
10048 be resolved successfully in the current JSON value; example: `"key baz
10049 not found"`
10050 @throw invalid_argument if the JSON patch is malformed (e.g., mandatory
10051 attributes are missing); example: `"operation add must have member path"`
10052
10053 @complexity Linear in the size of the JSON value and the length of the
10054 JSON patch. As usually only a fraction of the JSON value is affected by
10055 the patch, the complexity can usually be neglected.
10056
10057 @liveexample{The following code shows how a JSON patch is applied to a
10058 value.,patch}
10059
10060 @sa @ref diff -- create a JSON patch by comparing two JSON values
10061
10062 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
10063 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
10064
10065 @since version 2.0.0
10066 */
patch(const basic_json & json_patch) const10067 basic_json patch(const basic_json& json_patch) const
10068 {
10069 // make a working copy to apply the patch to
10070 basic_json result = *this;
10071
10072 // the valid JSON Patch operations
10073 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
10074
10075 const auto get_op = [](const std::string op)
10076 {
10077 if (op == "add")
10078 {
10079 return patch_operations::add;
10080 }
10081 if (op == "remove")
10082 {
10083 return patch_operations::remove;
10084 }
10085 if (op == "replace")
10086 {
10087 return patch_operations::replace;
10088 }
10089 if (op == "move")
10090 {
10091 return patch_operations::move;
10092 }
10093 if (op == "copy")
10094 {
10095 return patch_operations::copy;
10096 }
10097 if (op == "test")
10098 {
10099 return patch_operations::test;
10100 }
10101
10102 return patch_operations::invalid;
10103 };
10104
10105 // wrapper for "add" operation; add value at ptr
10106 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
10107 {
10108 // adding to the root of the target document means replacing it
10109 if (ptr.is_root())
10110 {
10111 result = val;
10112 }
10113 else
10114 {
10115 // make sure the top element of the pointer exists
10116 json_pointer top_pointer = ptr.top();
10117 if (top_pointer != ptr)
10118 {
10119 result.at(top_pointer);
10120 }
10121
10122 // get reference to parent of JSON pointer ptr
10123 const auto last_path = ptr.pop_back();
10124 basic_json& parent = result[ptr];
10125
10126 switch (parent.m_type)
10127 {
10128 case value_t::null:
10129 case value_t::object:
10130 {
10131 // use operator[] to add value
10132 parent[last_path] = val;
10133 break;
10134 }
10135
10136 case value_t::array:
10137 {
10138 if (last_path == "-")
10139 {
10140 // special case: append to back
10141 parent.push_back(val);
10142 }
10143 else
10144 {
10145 const auto idx = std::stoi(last_path);
10146 if (static_cast<size_type>(idx) > parent.size())
10147 {
10148 // avoid undefined behavior
10149 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
10150 }
10151 else
10152 {
10153 // default case: insert add offset
10154 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
10155 }
10156 }
10157 break;
10158 }
10159
10160 default:
10161 {
10162 // if there exists a parent it cannot be primitive
10163 assert(false); // LCOV_EXCL_LINE
10164 }
10165 }
10166 }
10167 };
10168
10169 // wrapper for "remove" operation; remove value at ptr
10170 const auto operation_remove = [&result](json_pointer & ptr)
10171 {
10172 // get reference to parent of JSON pointer ptr
10173 const auto last_path = ptr.pop_back();
10174 basic_json& parent = result.at(ptr);
10175
10176 // remove child
10177 if (parent.is_object())
10178 {
10179 // perform range check
10180 auto it = parent.find(last_path);
10181 if (it != parent.end())
10182 {
10183 parent.erase(it);
10184 }
10185 else
10186 {
10187 throw std::out_of_range("key '" + last_path + "' not found");
10188 }
10189 }
10190 else if (parent.is_array())
10191 {
10192 // note erase performs range check
10193 parent.erase(static_cast<size_type>(std::stoi(last_path)));
10194 }
10195 };
10196
10197 // type check
10198 if (not json_patch.is_array())
10199 {
10200 // a JSON patch must be an array of objects
10201 throw std::invalid_argument("JSON patch must be an array of objects");
10202 }
10203
10204 // iterate and apply th eoperations
10205 for (const auto& val : json_patch)
10206 {
10207 // wrapper to get a value for an operation
10208 const auto get_value = [&val](const std::string & op,
10209 const std::string & member,
10210 bool string_type) -> basic_json&
10211 {
10212 // find value
10213 auto it = val.m_value.object->find(member);
10214
10215 // context-sensitive error message
10216 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
10217
10218 // check if desired value is present
10219 if (it == val.m_value.object->end())
10220 {
10221 throw std::invalid_argument(error_msg + " must have member '" + member + "'");
10222 }
10223
10224 // check if result is of type string
10225 if (string_type and not it->second.is_string())
10226 {
10227 throw std::invalid_argument(error_msg + " must have string member '" + member + "'");
10228 }
10229
10230 // no error: return value
10231 return it->second;
10232 };
10233
10234 // type check
10235 if (not val.is_object())
10236 {
10237 throw std::invalid_argument("JSON patch must be an array of objects");
10238 }
10239
10240 // collect mandatory members
10241 const std::string op = get_value("op", "op", true);
10242 const std::string path = get_value(op, "path", true);
10243 json_pointer ptr(path);
10244
10245 switch (get_op(op))
10246 {
10247 case patch_operations::add:
10248 {
10249 operation_add(ptr, get_value("add", "value", false));
10250 break;
10251 }
10252
10253 case patch_operations::remove:
10254 {
10255 operation_remove(ptr);
10256 break;
10257 }
10258
10259 case patch_operations::replace:
10260 {
10261 // the "path" location must exist - use at()
10262 result.at(ptr) = get_value("replace", "value", false);
10263 break;
10264 }
10265
10266 case patch_operations::move:
10267 {
10268 const std::string from_path = get_value("move", "from", true);
10269 json_pointer from_ptr(from_path);
10270
10271 // the "from" location must exist - use at()
10272 basic_json v = result.at(from_ptr);
10273
10274 // The move operation is functionally identical to a
10275 // "remove" operation on the "from" location, followed
10276 // immediately by an "add" operation at the target
10277 // location with the value that was just removed.
10278 operation_remove(from_ptr);
10279 operation_add(ptr, v);
10280 break;
10281 }
10282
10283 case patch_operations::copy:
10284 {
10285 const std::string from_path = get_value("copy", "from", true);;
10286 const json_pointer from_ptr(from_path);
10287
10288 // the "from" location must exist - use at()
10289 result[ptr] = result.at(from_ptr);
10290 break;
10291 }
10292
10293 case patch_operations::test:
10294 {
10295 bool success = false;
10296 try
10297 {
10298 // check if "value" matches the one at "path"
10299 // the "path" location must exist - use at()
10300 success = (result.at(ptr) == get_value("test", "value", false));
10301 }
10302 catch (std::out_of_range&)
10303 {
10304 // ignore out of range errors: success remains false
10305 }
10306
10307 // throw an exception if test fails
10308 if (not success)
10309 {
10310 throw std::domain_error("unsuccessful: " + val.dump());
10311 }
10312
10313 break;
10314 }
10315
10316 case patch_operations::invalid:
10317 {
10318 // op must be "add", "remove", "replace", "move", "copy", or
10319 // "test"
10320 throw std::invalid_argument("operation value '" + op + "' is invalid");
10321 }
10322 }
10323 }
10324
10325 return result;
10326 }
10327
10328 /*!
10329 @brief creates a diff as a JSON patch
10330
10331 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
10332 be changed into the value @a target by calling @ref patch function.
10333
10334 @invariant For two JSON values @a source and @a target, the following code
10335 yields always `true`:
10336 @code {.cpp}
10337 source.patch(diff(source, target)) == target;
10338 @endcode
10339
10340 @note Currently, only `remove`, `add`, and `replace` operations are
10341 generated.
10342
10343 @param[in] source JSON value to copare from
10344 @param[in] target JSON value to copare against
10345 @param[in] path helper value to create JSON pointers
10346
10347 @return a JSON patch to convert the @a source to @a target
10348
10349 @complexity Linear in the lengths of @a source and @a target.
10350
10351 @liveexample{The following code shows how a JSON patch is created as a
10352 diff for two JSON values.,diff}
10353
10354 @sa @ref patch -- apply a JSON patch
10355
10356 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
10357
10358 @since version 2.0.0
10359 */
diff(const basic_json & source,const basic_json & target,const std::string & path="")10360 static basic_json diff(const basic_json& source,
10361 const basic_json& target,
10362 const std::string& path = "")
10363 {
10364 // the patch
10365 basic_json result(value_t::array);
10366
10367 // if the values are the same, return empty patch
10368 if (source == target)
10369 {
10370 return result;
10371 }
10372
10373 if (source.type() != target.type())
10374 {
10375 // different types: replace value
10376 result.push_back(
10377 {
10378 {"op", "replace"},
10379 {"path", path},
10380 {"value", target}
10381 });
10382 }
10383 else
10384 {
10385 switch (source.type())
10386 {
10387 case value_t::array:
10388 {
10389 // first pass: traverse common elements
10390 size_t i = 0;
10391 while (i < source.size() and i < target.size())
10392 {
10393 // recursive call to compare array values at index i
10394 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
10395 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
10396 ++i;
10397 }
10398
10399 // i now reached the end of at least one array
10400 // in a second pass, traverse the remaining elements
10401
10402 // remove my remaining elements
10403 const auto end_index = static_cast<difference_type>(result.size());
10404 while (i < source.size())
10405 {
10406 // add operations in reverse order to avoid invalid
10407 // indices
10408 result.insert(result.begin() + end_index, object(
10409 {
10410 {"op", "remove"},
10411 {"path", path + "/" + std::to_string(i)}
10412 }));
10413 ++i;
10414 }
10415
10416 // add other remaining elements
10417 while (i < target.size())
10418 {
10419 result.push_back(
10420 {
10421 {"op", "add"},
10422 {"path", path + "/" + std::to_string(i)},
10423 {"value", target[i]}
10424 });
10425 ++i;
10426 }
10427
10428 break;
10429 }
10430
10431 case value_t::object:
10432 {
10433 // first pass: traverse this object's elements
10434 for (auto it = source.begin(); it != source.end(); ++it)
10435 {
10436 // escape the key name to be used in a JSON patch
10437 const auto key = json_pointer::escape(it.key());
10438
10439 if (target.find(it.key()) != target.end())
10440 {
10441 // recursive call to compare object values at key it
10442 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
10443 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
10444 }
10445 else
10446 {
10447 // found a key that is not in o -> remove it
10448 result.push_back(object(
10449 {
10450 {"op", "remove"},
10451 {"path", path + "/" + key}
10452 }));
10453 }
10454 }
10455
10456 // second pass: traverse other object's elements
10457 for (auto it = target.begin(); it != target.end(); ++it)
10458 {
10459 if (source.find(it.key()) == source.end())
10460 {
10461 // found a key that is not in this -> add it
10462 const auto key = json_pointer::escape(it.key());
10463 result.push_back(
10464 {
10465 {"op", "add"},
10466 {"path", path + "/" + key},
10467 {"value", it.value()}
10468 });
10469 }
10470 }
10471
10472 break;
10473 }
10474
10475 default:
10476 {
10477 // both primitive type: replace value
10478 result.push_back(
10479 {
10480 {"op", "replace"},
10481 {"path", path},
10482 {"value", target}
10483 });
10484 break;
10485 }
10486 }
10487 }
10488
10489 return result;
10490 }
10491
10492 /// @}
10493 };
10494
10495
10496 /////////////
10497 // presets //
10498 /////////////
10499
10500 /*!
10501 @brief default JSON class
10502
10503 This type is the default specialization of the @ref basic_json class which
10504 uses the standard template types.
10505
10506 @since version 1.0.0
10507 */
10508 using json = basic_json<>;
10509 }
10510
10511
10512 ///////////////////////
10513 // nonmember support //
10514 ///////////////////////
10515
10516 // specialization of std::swap, and std::hash
10517 namespace std
10518 {
10519 /*!
10520 @brief exchanges the values of two JSON objects
10521
10522 @since version 1.0.0
10523 */
10524 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)10525 inline void swap(nlohmann::json& j1,
10526 nlohmann::json& j2) noexcept(
10527 is_nothrow_move_constructible<nlohmann::json>::value and
10528 is_nothrow_move_assignable<nlohmann::json>::value
10529 )
10530 {
10531 j1.swap(j2);
10532 }
10533
10534 /// hash value for JSON objects
10535 template<>
10536 struct hash<nlohmann::json>
10537 {
10538 /*!
10539 @brief return a hash value for a JSON object
10540
10541 @since version 1.0.0
10542 */
operator ()std::hash10543 std::size_t operator()(const nlohmann::json& j) const
10544 {
10545 // a naive hashing via the string representation
10546 const auto& h = hash<nlohmann::json::string_t>();
10547 return h(j.dump());
10548 }
10549 };
10550 }
10551
10552 /*!
10553 @brief user-defined string literal for JSON values
10554
10555 This operator implements a user-defined string literal for JSON objects. It
10556 can be used by adding `"_json"` to a string literal and returns a JSON object
10557 if no parse error occurred.
10558
10559 @param[in] s a string representation of a JSON object
10560 @return a JSON object
10561
10562 @since version 1.0.0
10563 */
operator ""_json(const char * s,std::size_t)10564 inline nlohmann::json operator "" _json(const char* s, std::size_t)
10565 {
10566 return nlohmann::json::parse(s);
10567 }
10568
10569 /*!
10570 @brief user-defined string literal for JSON pointer
10571
10572 This operator implements a user-defined string literal for JSON Pointers. It
10573 can be used by adding `"_json"` to a string literal and returns a JSON pointer
10574 object if no parse error occurred.
10575
10576 @param[in] s a string representation of a JSON Pointer
10577 @return a JSON pointer object
10578
10579 @since version 2.0.0
10580 */
operator ""_json_pointer(const char * s,std::size_t)10581 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t)
10582 {
10583 return nlohmann::json::json_pointer(s);
10584 }
10585
10586 // restore GCC/clang diagnostic settings
10587 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
10588 #pragma GCC diagnostic pop
10589 #endif
10590
10591 #endif
10592