1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48
49 #include <nlohmann/adl_serializer.hpp>
50 #include <nlohmann/byte_container_with_subtype.hpp>
51 #include <nlohmann/detail/conversions/from_json.hpp>
52 #include <nlohmann/detail/conversions/to_json.hpp>
53 #include <nlohmann/detail/exceptions.hpp>
54 #include <nlohmann/detail/hash.hpp>
55 #include <nlohmann/detail/input/binary_reader.hpp>
56 #include <nlohmann/detail/input/input_adapters.hpp>
57 #include <nlohmann/detail/input/lexer.hpp>
58 #include <nlohmann/detail/input/parser.hpp>
59 #include <nlohmann/detail/iterators/internal_iterator.hpp>
60 #include <nlohmann/detail/iterators/iter_impl.hpp>
61 #include <nlohmann/detail/iterators/iteration_proxy.hpp>
62 #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
63 #include <nlohmann/detail/iterators/primitive_iterator.hpp>
64 #include <nlohmann/detail/json_pointer.hpp>
65 #include <nlohmann/detail/json_ref.hpp>
66 #include <nlohmann/detail/macro_scope.hpp>
67 #include <nlohmann/detail/string_escape.hpp>
68 #include <nlohmann/detail/meta/cpp_future.hpp>
69 #include <nlohmann/detail/meta/type_traits.hpp>
70 #include <nlohmann/detail/output/binary_writer.hpp>
71 #include <nlohmann/detail/output/output_adapters.hpp>
72 #include <nlohmann/detail/output/serializer.hpp>
73 #include <nlohmann/detail/value_t.hpp>
74 #include <nlohmann/json_fwd.hpp>
75 #include <nlohmann/ordered_map.hpp>
76
77 #if defined(JSON_HAS_CPP_17)
78 #include <string_view>
79 #endif
80
81 /*!
82 @brief namespace for Niels Lohmann
83 @see https://github.com/nlohmann
84 @since version 1.0.0
85 */
86 namespace nlohmann
87 {
88
89 /*!
90 @brief a class to store JSON values
91
92 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
93 in @ref object_t)
94 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
95 in @ref array_t)
96 @tparam StringType type for JSON strings and object keys (`std::string` by
97 default; will be used in @ref string_t)
98 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
99 in @ref boolean_t)
100 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
101 default; will be used in @ref number_integer_t)
102 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
103 `uint64_t` by default; will be used in @ref number_unsigned_t)
104 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
105 default; will be used in @ref number_float_t)
106 @tparam BinaryType type for packed binary data for compatibility with binary
107 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
108 @ref binary_t)
109 @tparam AllocatorType type of the allocator to use (`std::allocator` by
110 default)
111 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
112 and `from_json()` (@ref adl_serializer by default)
113
114 @requirement The class satisfies the following concept requirements:
115 - Basic
116 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
117 JSON values can be default constructed. The result will be a JSON null
118 value.
119 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
120 A JSON value can be constructed from an rvalue argument.
121 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
122 A JSON value can be copy-constructed from an lvalue expression.
123 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
124 A JSON value van be assigned from an rvalue argument.
125 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
126 A JSON value can be copy-assigned from an lvalue expression.
127 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
128 JSON values can be destructed.
129 - Layout
130 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
131 JSON values have
132 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
133 All non-static data members are private and standard layout types, the
134 class has no virtual functions or (virtual) base classes.
135 - Library-wide
136 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
137 JSON values can be compared with `==`, see @ref
138 operator==(const_reference,const_reference).
139 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
140 JSON values can be compared with `<`, see @ref
141 operator<(const_reference,const_reference).
142 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
143 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
144 other compatible types, using unqualified function call @ref swap().
145 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
146 JSON values can be compared against `std::nullptr_t` objects which are used
147 to model the `null` value.
148 - Container
149 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
150 JSON values can be used like STL containers and provide iterator access.
151 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
152 JSON values can be used like STL containers and provide reverse iterator
153 access.
154
155 @invariant The member variables @a m_value and @a m_type have the following
156 relationship:
157 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
158 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
159 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
160 The invariants are checked by member function assert_invariant().
161
162 @internal
163 @note ObjectType trick from https://stackoverflow.com/a/9860911
164 @endinternal
165
166 @see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
167 Format](https://tools.ietf.org/html/rfc8259)
168
169 @since version 1.0.0
170
171 @nosubgrouping
172 */
173 NLOHMANN_BASIC_JSON_TPL_DECLARATION
174 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
175 {
176 private:
177 template<detail::value_t> friend struct detail::external_constructor;
178 friend ::nlohmann::json_pointer<basic_json>;
179
180 template<typename BasicJsonType, typename InputType>
181 friend class ::nlohmann::detail::parser;
182 friend ::nlohmann::detail::serializer<basic_json>;
183 template<typename BasicJsonType>
184 friend class ::nlohmann::detail::iter_impl;
185 template<typename BasicJsonType, typename CharType>
186 friend class ::nlohmann::detail::binary_writer;
187 template<typename BasicJsonType, typename InputType, typename SAX>
188 friend class ::nlohmann::detail::binary_reader;
189 template<typename BasicJsonType>
190 friend class ::nlohmann::detail::json_sax_dom_parser;
191 template<typename BasicJsonType>
192 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
193 friend class ::nlohmann::detail::exception;
194
195 /// workaround type for MSVC
196 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
197
198 JSON_PRIVATE_UNLESS_TESTED:
199 // convenience aliases for types residing in namespace detail;
200 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
201
202 template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)203 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
204 InputAdapterType adapter,
205 detail::parser_callback_t<basic_json>cb = nullptr,
206 const bool allow_exceptions = true,
207 const bool ignore_comments = false
208 )
209 {
210 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
211 std::move(cb), allow_exceptions, ignore_comments);
212 }
213
214 private:
215 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
216 template<typename BasicJsonType>
217 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
218 template<typename BasicJsonType>
219 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
220 template<typename Iterator>
221 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
222 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
223
224 template<typename CharType>
225 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
226
227 template<typename InputType>
228 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
229 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
230
231 JSON_PRIVATE_UNLESS_TESTED:
232 using serializer = ::nlohmann::detail::serializer<basic_json>;
233
234 public:
235 using value_t = detail::value_t;
236 /// JSON Pointer, see @ref nlohmann::json_pointer
237 using json_pointer = ::nlohmann::json_pointer<basic_json>;
238 template<typename T, typename SFINAE>
239 using json_serializer = JSONSerializer<T, SFINAE>;
240 /// how to treat decoding errors
241 using error_handler_t = detail::error_handler_t;
242 /// how to treat CBOR tags
243 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
244 /// helper type for initializer lists of basic_json values
245 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
246
247 using input_format_t = detail::input_format_t;
248 /// SAX interface type, see @ref nlohmann::json_sax
249 using json_sax_t = json_sax<basic_json>;
250
251 ////////////////
252 // exceptions //
253 ////////////////
254
255 /// @name exceptions
256 /// Classes to implement user-defined exceptions.
257 /// @{
258
259 /// @copydoc detail::exception
260 using exception = detail::exception;
261 /// @copydoc detail::parse_error
262 using parse_error = detail::parse_error;
263 /// @copydoc detail::invalid_iterator
264 using invalid_iterator = detail::invalid_iterator;
265 /// @copydoc detail::type_error
266 using type_error = detail::type_error;
267 /// @copydoc detail::out_of_range
268 using out_of_range = detail::out_of_range;
269 /// @copydoc detail::other_error
270 using other_error = detail::other_error;
271
272 /// @}
273
274
275 /////////////////////
276 // container types //
277 /////////////////////
278
279 /// @name container types
280 /// The canonic container types to use @ref basic_json like any other STL
281 /// container.
282 /// @{
283
284 /// the type of elements in a basic_json container
285 using value_type = basic_json;
286
287 /// the type of an element reference
288 using reference = value_type&;
289 /// the type of an element const reference
290 using const_reference = const value_type&;
291
292 /// a type to represent differences between iterators
293 using difference_type = std::ptrdiff_t;
294 /// a type to represent container sizes
295 using size_type = std::size_t;
296
297 /// the allocator type
298 using allocator_type = AllocatorType<basic_json>;
299
300 /// the type of an element pointer
301 using pointer = typename std::allocator_traits<allocator_type>::pointer;
302 /// the type of an element const pointer
303 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
304
305 /// an iterator for a basic_json container
306 using iterator = iter_impl<basic_json>;
307 /// a const iterator for a basic_json container
308 using const_iterator = iter_impl<const basic_json>;
309 /// a reverse iterator for a basic_json container
310 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
311 /// a const reverse iterator for a basic_json container
312 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
313
314 /// @}
315
316
317 /*!
318 @brief returns the allocator associated with the container
319 */
get_allocator()320 static allocator_type get_allocator()
321 {
322 return allocator_type();
323 }
324
325 /*!
326 @brief returns version information on the library
327
328 This function returns a JSON object with information about the library,
329 including the version number and information on the platform and compiler.
330
331 @return JSON object holding version information
332 key | description
333 ----------- | ---------------
334 `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
335 `copyright` | The copyright line for the library as string.
336 `name` | The name of the library as string.
337 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
338 `url` | The URL of the project as string.
339 `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
340
341 @liveexample{The following code shows an example output of the `meta()`
342 function.,meta}
343
344 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
345 changes to any JSON value.
346
347 @complexity Constant.
348
349 @since 2.1.0
350 */
351 JSON_HEDLEY_WARN_UNUSED_RESULT
meta()352 static basic_json meta()
353 {
354 basic_json result;
355
356 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
357 result["name"] = "JSON for Modern C++";
358 result["url"] = "https://github.com/nlohmann/json";
359 result["version"]["string"] =
360 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
361 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
362 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
363 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
364 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
365 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
366
367 #ifdef _WIN32
368 result["platform"] = "win32";
369 #elif defined __linux__
370 result["platform"] = "linux";
371 #elif defined __APPLE__
372 result["platform"] = "apple";
373 #elif defined __unix__
374 result["platform"] = "unix";
375 #else
376 result["platform"] = "unknown";
377 #endif
378
379 #if defined(__ICC) || defined(__INTEL_COMPILER)
380 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
381 #elif defined(__clang__)
382 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
383 #elif defined(__GNUC__) || defined(__GNUG__)
384 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
385 #elif defined(__HP_cc) || defined(__HP_aCC)
386 result["compiler"] = "hp"
387 #elif defined(__IBMCPP__)
388 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
389 #elif defined(_MSC_VER)
390 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
391 #elif defined(__PGI)
392 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
393 #elif defined(__SUNPRO_CC)
394 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
395 #else
396 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
397 #endif
398
399 #ifdef __cplusplus
400 result["compiler"]["c++"] = std::to_string(__cplusplus);
401 #else
402 result["compiler"]["c++"] = "unknown";
403 #endif
404 return result;
405 }
406
407
408 ///////////////////////////
409 // JSON value data types //
410 ///////////////////////////
411
412 /// @name JSON value data types
413 /// The data types to store a JSON value. These types are derived from
414 /// the template arguments passed to class @ref basic_json.
415 /// @{
416
417 #if defined(JSON_HAS_CPP_14)
418 // Use transparent comparator if possible, combined with perfect forwarding
419 // on find() and count() calls prevents unnecessary string construction.
420 using object_comparator_t = std::less<>;
421 #else
422 using object_comparator_t = std::less<StringType>;
423 #endif
424
425 /*!
426 @brief a type for an object
427
428 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
429 > An object is an unordered collection of zero or more name/value pairs,
430 > where a name is a string and a value is a string, number, boolean, null,
431 > object, or array.
432
433 To store objects in C++, a type is defined by the template parameters
434 described below.
435
436 @tparam ObjectType the container to store objects (e.g., `std::map` or
437 `std::unordered_map`)
438 @tparam StringType the type of the keys or names (e.g., `std::string`).
439 The comparison function `std::less<StringType>` is used to order elements
440 inside the container.
441 @tparam AllocatorType the allocator to use for objects (e.g.,
442 `std::allocator`)
443
444 #### Default type
445
446 With the default values for @a ObjectType (`std::map`), @a StringType
447 (`std::string`), and @a AllocatorType (`std::allocator`), the default
448 value for @a object_t is:
449
450 @code {.cpp}
451 std::map<
452 std::string, // key_type
453 basic_json, // value_type
454 std::less<std::string>, // key_compare
455 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
456 >
457 @endcode
458
459 #### Behavior
460
461 The choice of @a object_t influences the behavior of the JSON class. With
462 the default type, objects have the following behavior:
463
464 - When all names are unique, objects will be interoperable in the sense
465 that all software implementations receiving that object will agree on
466 the name-value mappings.
467 - When the names within an object are not unique, it is unspecified which
468 one of the values for a given key will be chosen. For instance,
469 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
470 `{"key": 2}`.
471 - Internally, name/value pairs are stored in lexicographical order of the
472 names. Objects will also be serialized (see @ref dump) in this order.
473 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
474 and serialized as `{"a": 2, "b": 1}`.
475 - When comparing objects, the order of the name/value pairs is irrelevant.
476 This makes objects interoperable in the sense that they will not be
477 affected by these differences. For instance, `{"b": 1, "a": 2}` and
478 `{"a": 2, "b": 1}` will be treated as equal.
479
480 #### Limits
481
482 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
483 > An implementation may set limits on the maximum depth of nesting.
484
485 In this class, the object's limit of nesting is not explicitly constrained.
486 However, a maximum depth of nesting may be introduced by the compiler or
487 runtime environment. A theoretical limit can be queried by calling the
488 @ref max_size function of a JSON object.
489
490 #### Storage
491
492 Objects are stored as pointers in a @ref basic_json type. That is, for any
493 access to object values, a pointer of type `object_t*` must be
494 dereferenced.
495
496 @sa see @ref array_t -- type for an array value
497
498 @since version 1.0.0
499
500 @note The order name/value pairs are added to the object is *not*
501 preserved by the library. Therefore, iterating an object may return
502 name/value pairs in a different order than they were originally stored. In
503 fact, keys will be traversed in alphabetical order as `std::map` with
504 `std::less` is used by default. Please note this behavior conforms to [RFC
505 8259](https://tools.ietf.org/html/rfc8259), because any order implements the
506 specified "unordered" nature of JSON objects.
507 */
508 using object_t = ObjectType<StringType,
509 basic_json,
510 object_comparator_t,
511 AllocatorType<std::pair<const StringType,
512 basic_json>>>;
513
514 /*!
515 @brief a type for an array
516
517 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
518 > An array is an ordered sequence of zero or more values.
519
520 To store objects in C++, a type is defined by the template parameters
521 explained below.
522
523 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
524 `std::list`)
525 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
526
527 #### Default type
528
529 With the default values for @a ArrayType (`std::vector`) and @a
530 AllocatorType (`std::allocator`), the default value for @a array_t is:
531
532 @code {.cpp}
533 std::vector<
534 basic_json, // value_type
535 std::allocator<basic_json> // allocator_type
536 >
537 @endcode
538
539 #### Limits
540
541 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
542 > An implementation may set limits on the maximum depth of nesting.
543
544 In this class, the array's limit of nesting is not explicitly constrained.
545 However, a maximum depth of nesting may be introduced by the compiler or
546 runtime environment. A theoretical limit can be queried by calling the
547 @ref max_size function of a JSON array.
548
549 #### Storage
550
551 Arrays are stored as pointers in a @ref basic_json type. That is, for any
552 access to array values, a pointer of type `array_t*` must be dereferenced.
553
554 @sa see @ref object_t -- type for an object value
555
556 @since version 1.0.0
557 */
558 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
559
560 /*!
561 @brief a type for a string
562
563 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
564 > A string is a sequence of zero or more Unicode characters.
565
566 To store objects in C++, a type is defined by the template parameter
567 described below. Unicode values are split by the JSON class into
568 byte-sized characters during deserialization.
569
570 @tparam StringType the container to store strings (e.g., `std::string`).
571 Note this container is used for keys/names in objects, see @ref object_t.
572
573 #### Default type
574
575 With the default values for @a StringType (`std::string`), the default
576 value for @a string_t is:
577
578 @code {.cpp}
579 std::string
580 @endcode
581
582 #### Encoding
583
584 Strings are stored in UTF-8 encoding. Therefore, functions like
585 `std::string::size()` or `std::string::length()` return the number of
586 bytes in the string rather than the number of characters or glyphs.
587
588 #### String comparison
589
590 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
591 > Software implementations are typically required to test names of object
592 > members for equality. Implementations that transform the textual
593 > representation into sequences of Unicode code units and then perform the
594 > comparison numerically, code unit by code unit, are interoperable in the
595 > sense that implementations will agree in all cases on equality or
596 > inequality of two strings. For example, implementations that compare
597 > strings with escaped characters unconverted may incorrectly find that
598 > `"a\\b"` and `"a\u005Cb"` are not equal.
599
600 This implementation is interoperable as it does compare strings code unit
601 by code unit.
602
603 #### Storage
604
605 String values are stored as pointers in a @ref basic_json type. That is,
606 for any access to string values, a pointer of type `string_t*` must be
607 dereferenced.
608
609 @since version 1.0.0
610 */
611 using string_t = StringType;
612
613 /*!
614 @brief a type for a boolean
615
616 [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
617 type which differentiates the two literals `true` and `false`.
618
619 To store objects in C++, a type is defined by the template parameter @a
620 BooleanType which chooses the type to use.
621
622 #### Default type
623
624 With the default values for @a BooleanType (`bool`), the default value for
625 @a boolean_t is:
626
627 @code {.cpp}
628 bool
629 @endcode
630
631 #### Storage
632
633 Boolean values are stored directly inside a @ref basic_json type.
634
635 @since version 1.0.0
636 */
637 using boolean_t = BooleanType;
638
639 /*!
640 @brief a type for a number (integer)
641
642 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
643 > The representation of numbers is similar to that used in most
644 > programming languages. A number is represented in base 10 using decimal
645 > digits. It contains an integer component that may be prefixed with an
646 > optional minus sign, which may be followed by a fraction part and/or an
647 > exponent part. Leading zeros are not allowed. (...) Numeric values that
648 > cannot be represented in the grammar below (such as Infinity and NaN)
649 > are not permitted.
650
651 This description includes both integer and floating-point numbers.
652 However, C++ allows more precise storage if it is known whether the number
653 is a signed integer, an unsigned integer or a floating-point number.
654 Therefore, three different types, @ref number_integer_t, @ref
655 number_unsigned_t and @ref number_float_t are used.
656
657 To store integer numbers in C++, a type is defined by the template
658 parameter @a NumberIntegerType which chooses the type to use.
659
660 #### Default type
661
662 With the default values for @a NumberIntegerType (`int64_t`), the default
663 value for @a number_integer_t is:
664
665 @code {.cpp}
666 int64_t
667 @endcode
668
669 #### Default behavior
670
671 - The restrictions about leading zeros is not enforced in C++. Instead,
672 leading zeros in integer literals lead to an interpretation as octal
673 number. Internally, the value will be stored as decimal number. For
674 instance, the C++ integer literal `010` will be serialized to `8`.
675 During deserialization, leading zeros yield an error.
676 - Not-a-number (NaN) values will be serialized to `null`.
677
678 #### Limits
679
680 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
681 > An implementation may set limits on the range and precision of numbers.
682
683 When the default type is used, the maximal integer number that can be
684 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
685 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
686 that are out of range will yield over/underflow when used in a
687 constructor. During deserialization, too large or small integer numbers
688 will be automatically be stored as @ref number_unsigned_t or @ref
689 number_float_t.
690
691 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
692 > Note that when such software is used, numbers that are integers and are
693 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
694 > that implementations will agree exactly on their numeric values.
695
696 As this range is a subrange of the exactly supported range [INT64_MIN,
697 INT64_MAX], this class's integer type is interoperable.
698
699 #### Storage
700
701 Integer number values are stored directly inside a @ref basic_json type.
702
703 @sa see @ref number_float_t -- type for number values (floating-point)
704
705 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
706
707 @since version 1.0.0
708 */
709 using number_integer_t = NumberIntegerType;
710
711 /*!
712 @brief a type for a number (unsigned)
713
714 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
715 > The representation of numbers is similar to that used in most
716 > programming languages. A number is represented in base 10 using decimal
717 > digits. It contains an integer component that may be prefixed with an
718 > optional minus sign, which may be followed by a fraction part and/or an
719 > exponent part. Leading zeros are not allowed. (...) Numeric values that
720 > cannot be represented in the grammar below (such as Infinity and NaN)
721 > are not permitted.
722
723 This description includes both integer and floating-point numbers.
724 However, C++ allows more precise storage if it is known whether the number
725 is a signed integer, an unsigned integer or a floating-point number.
726 Therefore, three different types, @ref number_integer_t, @ref
727 number_unsigned_t and @ref number_float_t are used.
728
729 To store unsigned integer numbers in C++, a type is defined by the
730 template parameter @a NumberUnsignedType which chooses the type to use.
731
732 #### Default type
733
734 With the default values for @a NumberUnsignedType (`uint64_t`), the
735 default value for @a number_unsigned_t is:
736
737 @code {.cpp}
738 uint64_t
739 @endcode
740
741 #### Default behavior
742
743 - The restrictions about leading zeros is not enforced in C++. Instead,
744 leading zeros in integer literals lead to an interpretation as octal
745 number. Internally, the value will be stored as decimal number. For
746 instance, the C++ integer literal `010` will be serialized to `8`.
747 During deserialization, leading zeros yield an error.
748 - Not-a-number (NaN) values will be serialized to `null`.
749
750 #### Limits
751
752 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
753 > An implementation may set limits on the range and precision of numbers.
754
755 When the default type is used, the maximal integer number that can be
756 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
757 number that can be stored is `0`. Integer numbers that are out of range
758 will yield over/underflow when used in a constructor. During
759 deserialization, too large or small integer numbers will be automatically
760 be stored as @ref number_integer_t or @ref number_float_t.
761
762 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
763 > Note that when such software is used, numbers that are integers and are
764 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
765 > that implementations will agree exactly on their numeric values.
766
767 As this range is a subrange (when considered in conjunction with the
768 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
769 this class's integer type is interoperable.
770
771 #### Storage
772
773 Integer number values are stored directly inside a @ref basic_json type.
774
775 @sa see @ref number_float_t -- type for number values (floating-point)
776 @sa see @ref number_integer_t -- type for number values (integer)
777
778 @since version 2.0.0
779 */
780 using number_unsigned_t = NumberUnsignedType;
781
782 /*!
783 @brief a type for a number (floating-point)
784
785 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
786 > The representation of numbers is similar to that used in most
787 > programming languages. A number is represented in base 10 using decimal
788 > digits. It contains an integer component that may be prefixed with an
789 > optional minus sign, which may be followed by a fraction part and/or an
790 > exponent part. Leading zeros are not allowed. (...) Numeric values that
791 > cannot be represented in the grammar below (such as Infinity and NaN)
792 > are not permitted.
793
794 This description includes both integer and floating-point numbers.
795 However, C++ allows more precise storage if it is known whether the number
796 is a signed integer, an unsigned integer or a floating-point number.
797 Therefore, three different types, @ref number_integer_t, @ref
798 number_unsigned_t and @ref number_float_t are used.
799
800 To store floating-point numbers in C++, a type is defined by the template
801 parameter @a NumberFloatType which chooses the type to use.
802
803 #### Default type
804
805 With the default values for @a NumberFloatType (`double`), the default
806 value for @a number_float_t is:
807
808 @code {.cpp}
809 double
810 @endcode
811
812 #### Default behavior
813
814 - The restrictions about leading zeros is not enforced in C++. Instead,
815 leading zeros in floating-point literals will be ignored. Internally,
816 the value will be stored as decimal number. For instance, the C++
817 floating-point literal `01.2` will be serialized to `1.2`. During
818 deserialization, leading zeros yield an error.
819 - Not-a-number (NaN) values will be serialized to `null`.
820
821 #### Limits
822
823 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
824 > This specification allows implementations to set limits on the range and
825 > precision of numbers accepted. Since software that implements IEEE
826 > 754-2008 binary64 (double precision) numbers is generally available and
827 > widely used, good interoperability can be achieved by implementations
828 > that expect no more precision or range than these provide, in the sense
829 > that implementations will approximate JSON numbers within the expected
830 > precision.
831
832 This implementation does exactly follow this approach, as it uses double
833 precision floating-point numbers. Note values smaller than
834 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
835 will be stored as NaN internally and be serialized to `null`.
836
837 #### Storage
838
839 Floating-point number values are stored directly inside a @ref basic_json
840 type.
841
842 @sa see @ref number_integer_t -- type for number values (integer)
843
844 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
845
846 @since version 1.0.0
847 */
848 using number_float_t = NumberFloatType;
849
850 /*!
851 @brief a type for a packed binary type
852
853 This type is a type designed to carry binary data that appears in various
854 serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
855 BSON's generic binary subtype. This type is NOT a part of standard JSON and
856 exists solely for compatibility with these binary types. As such, it is
857 simply defined as an ordered sequence of zero or more byte values.
858
859 Additionally, as an implementation detail, the subtype of the binary data is
860 carried around as a `std::uint8_t`, which is compatible with both of the
861 binary data formats that use binary subtyping, (though the specific
862 numbering is incompatible with each other, and it is up to the user to
863 translate between them).
864
865 [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
866 as:
867 > Major type 2: a byte string. The string's length in bytes is represented
868 > following the rules for positive integers (major type 0).
869
870 [MessagePack's documentation on the bin type
871 family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
872 describes this type as:
873 > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
874 > in addition to the size of the byte array.
875
876 [BSON's specifications](http://bsonspec.org/spec.html) describe several
877 binary types; however, this type is intended to represent the generic binary
878 type which has the description:
879 > Generic binary subtype - This is the most commonly used binary subtype and
880 > should be the 'default' for drivers and tools.
881
882 None of these impose any limitations on the internal representation other
883 than the basic unit of storage be some type of array whose parts are
884 decomposable into bytes.
885
886 The default representation of this binary format is a
887 `std::vector<std::uint8_t>`, which is a very common way to represent a byte
888 array in modern C++.
889
890 #### Default type
891
892 The default values for @a BinaryType is `std::vector<std::uint8_t>`
893
894 #### Storage
895
896 Binary Arrays are stored as pointers in a @ref basic_json type. That is,
897 for any access to array values, a pointer of the type `binary_t*` must be
898 dereferenced.
899
900 #### Notes on subtypes
901
902 - CBOR
903 - Binary values are represented as byte strings. No subtypes are
904 supported and will be ignored when CBOR is written.
905 - MessagePack
906 - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
907 or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
908 is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
909 The subtype is then added as singed 8-bit integer.
910 - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
911 - BSON
912 - If a subtype is given, it is used and added as unsigned 8-bit integer.
913 - If no subtype is given, the generic binary subtype 0x00 is used.
914
915 @sa see @ref binary -- create a binary array
916
917 @since version 3.8.0
918 */
919 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
920 /// @}
921
922 private:
923
924 /// helper for exception-safe object creation
925 template<typename T, typename... Args>
926 JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)927 static T* create(Args&& ... args)
928 {
929 AllocatorType<T> alloc;
930 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
931
932 auto deleter = [&](T * obj)
933 {
934 AllocatorTraits::deallocate(alloc, obj, 1);
935 };
936 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
937 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
938 JSON_ASSERT(obj != nullptr);
939 return obj.release();
940 }
941
942 ////////////////////////
943 // JSON value storage //
944 ////////////////////////
945
946 JSON_PRIVATE_UNLESS_TESTED:
947 /*!
948 @brief a JSON value
949
950 The actual storage for a JSON value of the @ref basic_json class. This
951 union combines the different storage types for the JSON value types
952 defined in @ref value_t.
953
954 JSON type | value_t type | used type
955 --------- | --------------- | ------------------------
956 object | object | pointer to @ref object_t
957 array | array | pointer to @ref array_t
958 string | string | pointer to @ref string_t
959 boolean | boolean | @ref boolean_t
960 number | number_integer | @ref number_integer_t
961 number | number_unsigned | @ref number_unsigned_t
962 number | number_float | @ref number_float_t
963 binary | binary | pointer to @ref binary_t
964 null | null | *no value is stored*
965
966 @note Variable-length types (objects, arrays, and strings) are stored as
967 pointers. The size of the union should not exceed 64 bits if the default
968 value types are used.
969
970 @since version 1.0.0
971 */
972 union json_value
973 {
974 /// object (stored with pointer to save storage)
975 object_t* object;
976 /// array (stored with pointer to save storage)
977 array_t* array;
978 /// string (stored with pointer to save storage)
979 string_t* string;
980 /// binary (stored with pointer to save storage)
981 binary_t* binary;
982 /// boolean
983 boolean_t boolean;
984 /// number (integer)
985 number_integer_t number_integer;
986 /// number (unsigned integer)
987 number_unsigned_t number_unsigned;
988 /// number (floating-point)
989 number_float_t number_float;
990
991 /// default constructor (for null values)
992 json_value() = default;
993 /// constructor for booleans
json_value(boolean_t v)994 json_value(boolean_t v) noexcept : boolean(v) {}
995 /// constructor for numbers (integer)
json_value(number_integer_t v)996 json_value(number_integer_t v) noexcept : number_integer(v) {}
997 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)998 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
999 /// constructor for numbers (floating-point)
json_value(number_float_t v)1000 json_value(number_float_t v) noexcept : number_float(v) {}
1001 /// constructor for empty values of a given type
json_value(value_t t)1002 json_value(value_t t)
1003 {
1004 switch (t)
1005 {
1006 case value_t::object:
1007 {
1008 object = create<object_t>();
1009 break;
1010 }
1011
1012 case value_t::array:
1013 {
1014 array = create<array_t>();
1015 break;
1016 }
1017
1018 case value_t::string:
1019 {
1020 string = create<string_t>("");
1021 break;
1022 }
1023
1024 case value_t::binary:
1025 {
1026 binary = create<binary_t>();
1027 break;
1028 }
1029
1030 case value_t::boolean:
1031 {
1032 boolean = boolean_t(false);
1033 break;
1034 }
1035
1036 case value_t::number_integer:
1037 {
1038 number_integer = number_integer_t(0);
1039 break;
1040 }
1041
1042 case value_t::number_unsigned:
1043 {
1044 number_unsigned = number_unsigned_t(0);
1045 break;
1046 }
1047
1048 case value_t::number_float:
1049 {
1050 number_float = number_float_t(0.0);
1051 break;
1052 }
1053
1054 case value_t::null:
1055 {
1056 object = nullptr; // silence warning, see #821
1057 break;
1058 }
1059
1060 default:
1061 {
1062 object = nullptr; // silence warning, see #821
1063 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
1064 {
1065 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1", basic_json())); // LCOV_EXCL_LINE
1066 }
1067 break;
1068 }
1069 }
1070 }
1071
1072 /// constructor for strings
json_value(const string_t & value)1073 json_value(const string_t& value)
1074 {
1075 string = create<string_t>(value);
1076 }
1077
1078 /// constructor for rvalue strings
json_value(string_t && value)1079 json_value(string_t&& value)
1080 {
1081 string = create<string_t>(std::move(value));
1082 }
1083
1084 /// constructor for objects
json_value(const object_t & value)1085 json_value(const object_t& value)
1086 {
1087 object = create<object_t>(value);
1088 }
1089
1090 /// constructor for rvalue objects
json_value(object_t && value)1091 json_value(object_t&& value)
1092 {
1093 object = create<object_t>(std::move(value));
1094 }
1095
1096 /// constructor for arrays
json_value(const array_t & value)1097 json_value(const array_t& value)
1098 {
1099 array = create<array_t>(value);
1100 }
1101
1102 /// constructor for rvalue arrays
json_value(array_t && value)1103 json_value(array_t&& value)
1104 {
1105 array = create<array_t>(std::move(value));
1106 }
1107
1108 /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)1109 json_value(const typename binary_t::container_type& value)
1110 {
1111 binary = create<binary_t>(value);
1112 }
1113
1114 /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)1115 json_value(typename binary_t::container_type&& value)
1116 {
1117 binary = create<binary_t>(std::move(value));
1118 }
1119
1120 /// constructor for binary arrays (internal type)
json_value(const binary_t & value)1121 json_value(const binary_t& value)
1122 {
1123 binary = create<binary_t>(value);
1124 }
1125
1126 /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)1127 json_value(binary_t&& value)
1128 {
1129 binary = create<binary_t>(std::move(value));
1130 }
1131
destroy(value_t t)1132 void destroy(value_t t) noexcept
1133 {
1134 // flatten the current json_value to a heap-allocated stack
1135 std::vector<basic_json> stack;
1136
1137 // move the top-level items to stack
1138 if (t == value_t::array)
1139 {
1140 stack.reserve(array->size());
1141 std::move(array->begin(), array->end(), std::back_inserter(stack));
1142 }
1143 else if (t == value_t::object)
1144 {
1145 stack.reserve(object->size());
1146 for (auto&& it : *object)
1147 {
1148 stack.push_back(std::move(it.second));
1149 }
1150 }
1151
1152 while (!stack.empty())
1153 {
1154 // move the last item to local variable to be processed
1155 basic_json current_item(std::move(stack.back()));
1156 stack.pop_back();
1157
1158 // if current_item is array/object, move
1159 // its children to the stack to be processed later
1160 if (current_item.is_array())
1161 {
1162 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
1163 std::back_inserter(stack));
1164
1165 current_item.m_value.array->clear();
1166 }
1167 else if (current_item.is_object())
1168 {
1169 for (auto&& it : *current_item.m_value.object)
1170 {
1171 stack.push_back(std::move(it.second));
1172 }
1173
1174 current_item.m_value.object->clear();
1175 }
1176
1177 // it's now safe that current_item get destructed
1178 // since it doesn't have any children
1179 }
1180
1181 switch (t)
1182 {
1183 case value_t::object:
1184 {
1185 AllocatorType<object_t> alloc;
1186 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
1187 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
1188 break;
1189 }
1190
1191 case value_t::array:
1192 {
1193 AllocatorType<array_t> alloc;
1194 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
1195 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
1196 break;
1197 }
1198
1199 case value_t::string:
1200 {
1201 AllocatorType<string_t> alloc;
1202 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
1203 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
1204 break;
1205 }
1206
1207 case value_t::binary:
1208 {
1209 AllocatorType<binary_t> alloc;
1210 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
1211 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
1212 break;
1213 }
1214
1215 default:
1216 {
1217 break;
1218 }
1219 }
1220 }
1221 };
1222
1223 private:
1224 /*!
1225 @brief checks the class invariants
1226
1227 This function asserts the class invariants. It needs to be called at the
1228 end of every constructor to make sure that created objects respect the
1229 invariant. Furthermore, it has to be called each time the type of a JSON
1230 value is changed, because the invariant expresses a relationship between
1231 @a m_type and @a m_value.
1232
1233 Furthermore, the parent relation is checked for arrays and objects: If
1234 @a check_parents true and the value is an array or object, then the
1235 container's elements must have the current value as parent.
1236
1237 @param[in] check_parents whether the parent relation should be checked.
1238 The value is true by default and should only be set to false
1239 during destruction of objects when the invariant does not
1240 need to hold.
1241 */
assert_invariant(bool check_parents=true) const1242 void assert_invariant(bool check_parents = true) const noexcept
1243 {
1244 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
1245 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
1246 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
1247 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
1248
1249 #if JSON_DIAGNOSTICS
1250 JSON_TRY
1251 {
1252 // cppcheck-suppress assertWithSideEffect
1253 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
1254 {
1255 return j.m_parent == this;
1256 }));
1257 }
1258 JSON_CATCH(...) {} // LCOV_EXCL_LINE
1259 #endif
1260 static_cast<void>(check_parents);
1261 }
1262
set_parents()1263 void set_parents()
1264 {
1265 #if JSON_DIAGNOSTICS
1266 switch (m_type)
1267 {
1268 case value_t::array:
1269 {
1270 for (auto& element : *m_value.array)
1271 {
1272 element.m_parent = this;
1273 }
1274 break;
1275 }
1276
1277 case value_t::object:
1278 {
1279 for (auto& element : *m_value.object)
1280 {
1281 element.second.m_parent = this;
1282 }
1283 break;
1284 }
1285
1286 default:
1287 break;
1288 }
1289 #endif
1290 }
1291
set_parents(iterator it,typename iterator::difference_type count)1292 iterator set_parents(iterator it, typename iterator::difference_type count)
1293 {
1294 #if JSON_DIAGNOSTICS
1295 for (typename iterator::difference_type i = 0; i < count; ++i)
1296 {
1297 (it + i)->m_parent = this;
1298 }
1299 #else
1300 static_cast<void>(count);
1301 #endif
1302 return it;
1303 }
1304
set_parent(reference j)1305 reference set_parent(reference j)
1306 {
1307 #if JSON_DIAGNOSTICS
1308 j.m_parent = this;
1309 #else
1310 static_cast<void>(j);
1311 #endif
1312 return j;
1313 }
1314
1315 public:
1316 //////////////////////////
1317 // JSON parser callback //
1318 //////////////////////////
1319
1320 /*!
1321 @brief parser event types
1322
1323 The parser callback distinguishes the following events:
1324 - `object_start`: the parser read `{` and started to process a JSON object
1325 - `key`: the parser read a key of a value in an object
1326 - `object_end`: the parser read `}` and finished processing a JSON object
1327 - `array_start`: the parser read `[` and started to process a JSON array
1328 - `array_end`: the parser read `]` and finished processing a JSON array
1329 - `value`: the parser finished reading a JSON value
1330
1331 @image html callback_events.png "Example when certain parse events are triggered"
1332
1333 @sa see @ref parser_callback_t for more information and examples
1334 */
1335 using parse_event_t = detail::parse_event_t;
1336
1337 /*!
1338 @brief per-element parser callback type
1339
1340 With a parser callback function, the result of parsing a JSON text can be
1341 influenced. When passed to @ref parse, it is called on certain events
1342 (passed as @ref parse_event_t via parameter @a event) with a set recursion
1343 depth @a depth and context JSON value @a parsed. The return value of the
1344 callback function is a boolean indicating whether the element that emitted
1345 the callback shall be kept or not.
1346
1347 We distinguish six scenarios (determined by the event type) in which the
1348 callback function can be called. The following table describes the values
1349 of the parameters @a depth, @a event, and @a parsed.
1350
1351 parameter @a event | description | parameter @a depth | parameter @a parsed
1352 ------------------ | ----------- | ------------------ | -------------------
1353 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
1354 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
1355 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
1356 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
1357 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
1358 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
1359
1360 @image html callback_events.png "Example when certain parse events are triggered"
1361
1362 Discarding a value (i.e., returning `false`) has different effects
1363 depending on the context in which function was called:
1364
1365 - Discarded values in structured types are skipped. That is, the parser
1366 will behave as if the discarded value was never read.
1367 - In case a value outside a structured type is skipped, it is replaced
1368 with `null`. This case happens if the top-level element is skipped.
1369
1370 @param[in] depth the depth of the recursion during parsing
1371
1372 @param[in] event an event of type parse_event_t indicating the context in
1373 the callback function has been called
1374
1375 @param[in,out] parsed the current intermediate parse result; note that
1376 writing to this value has no effect for parse_event_t::key events
1377
1378 @return Whether the JSON value which called the function during parsing
1379 should be kept (`true`) or not (`false`). In the latter case, it is either
1380 skipped completely or replaced by an empty discarded object.
1381
1382 @sa see @ref parse for examples
1383
1384 @since version 1.0.0
1385 */
1386 using parser_callback_t = detail::parser_callback_t<basic_json>;
1387
1388 //////////////////
1389 // constructors //
1390 //////////////////
1391
1392 /// @name constructors and destructors
1393 /// Constructors of class @ref basic_json, copy/move constructor, copy
1394 /// assignment, static functions creating objects, and the destructor.
1395 /// @{
1396
1397 /*!
1398 @brief create an empty value with a given type
1399
1400 Create an empty JSON value with a given type. The value will be default
1401 initialized with an empty value which depends on the type:
1402
1403 Value type | initial value
1404 ----------- | -------------
1405 null | `null`
1406 boolean | `false`
1407 string | `""`
1408 number | `0`
1409 object | `{}`
1410 array | `[]`
1411 binary | empty array
1412
1413 @param[in] v the type of the value to create
1414
1415 @complexity Constant.
1416
1417 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1418 changes to any JSON value.
1419
1420 @liveexample{The following code shows the constructor for different @ref
1421 value_t values,basic_json__value_t}
1422
1423 @sa see @ref clear() -- restores the postcondition of this constructor
1424
1425 @since version 1.0.0
1426 */
basic_json(const value_t v)1427 basic_json(const value_t v)
1428 : m_type(v), m_value(v)
1429 {
1430 assert_invariant();
1431 }
1432
1433 /*!
1434 @brief create a null object
1435
1436 Create a `null` JSON value. It either takes a null pointer as parameter
1437 (explicitly creating `null`) or no parameter (implicitly creating `null`).
1438 The passed null pointer itself is not read -- it is only used to choose
1439 the right constructor.
1440
1441 @complexity Constant.
1442
1443 @exceptionsafety No-throw guarantee: this constructor never throws
1444 exceptions.
1445
1446 @liveexample{The following code shows the constructor with and without a
1447 null pointer parameter.,basic_json__nullptr_t}
1448
1449 @since version 1.0.0
1450 */
basic_json(std::nullptr_t=nullptr)1451 basic_json(std::nullptr_t = nullptr) noexcept
1452 : basic_json(value_t::null)
1453 {
1454 assert_invariant();
1455 }
1456
1457 /*!
1458 @brief create a JSON value
1459
1460 This is a "catch all" constructor for all compatible JSON types; that is,
1461 types for which a `to_json()` method exists. The constructor forwards the
1462 parameter @a val to that method (to `json_serializer<U>::to_json` method
1463 with `U = uncvref_t<CompatibleType>`, to be exact).
1464
1465 Template type @a CompatibleType includes, but is not limited to, the
1466 following types:
1467 - **arrays**: @ref array_t and all kinds of compatible containers such as
1468 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
1469 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
1470 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
1471 which a @ref basic_json value can be constructed.
1472 - **objects**: @ref object_t and all kinds of compatible associative
1473 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
1474 and `std::unordered_multimap` with a `key_type` compatible to
1475 @ref string_t and a `value_type` from which a @ref basic_json value can
1476 be constructed.
1477 - **strings**: @ref string_t, string literals, and all compatible string
1478 containers can be used.
1479 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
1480 @ref number_float_t, and all convertible number types such as `int`,
1481 `size_t`, `int64_t`, `float` or `double` can be used.
1482 - **boolean**: @ref boolean_t / `bool` can be used.
1483 - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
1484 unfortunately because string literals cannot be distinguished from binary
1485 character arrays by the C++ type system, all types compatible with `const
1486 char*` will be directed to the string constructor instead. This is both
1487 for backwards compatibility, and due to the fact that a binary type is not
1488 a standard JSON type.
1489
1490 See the examples below.
1491
1492 @tparam CompatibleType a type such that:
1493 - @a CompatibleType is not derived from `std::istream`,
1494 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
1495 constructors),
1496 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
1497 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
1498 @ref json_pointer, @ref iterator, etc ...)
1499 - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
1500
1501 @tparam U = `uncvref_t<CompatibleType>`
1502
1503 @param[in] val the value to be forwarded to the respective constructor
1504
1505 @complexity Usually linear in the size of the passed @a val, also
1506 depending on the implementation of the called `to_json()`
1507 method.
1508
1509 @exceptionsafety Depends on the called constructor. For types directly
1510 supported by the library (i.e., all types for which no `to_json()` function
1511 was provided), strong guarantee holds: if an exception is thrown, there are
1512 no changes to any JSON value.
1513
1514 @liveexample{The following code shows the constructor with several
1515 compatible types.,basic_json__CompatibleType}
1516
1517 @since version 2.1.0
1518 */
1519 template < typename CompatibleType,
1520 typename U = detail::uncvref_t<CompatibleType>,
1521 detail::enable_if_t <
1522 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)1523 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
1524 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
1525 std::forward<CompatibleType>(val))))
1526 {
1527 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
1528 set_parents();
1529 assert_invariant();
1530 }
1531
1532 /*!
1533 @brief create a JSON value from an existing one
1534
1535 This is a constructor for existing @ref basic_json types.
1536 It does not hijack copy/move constructors, since the parameter has different
1537 template arguments than the current ones.
1538
1539 The constructor tries to convert the internal @ref m_value of the parameter.
1540
1541 @tparam BasicJsonType a type such that:
1542 - @a BasicJsonType is a @ref basic_json type.
1543 - @a BasicJsonType has different template arguments than @ref basic_json_t.
1544
1545 @param[in] val the @ref basic_json value to be converted.
1546
1547 @complexity Usually linear in the size of the passed @a val, also
1548 depending on the implementation of the called `to_json()`
1549 method.
1550
1551 @exceptionsafety Depends on the called constructor. For types directly
1552 supported by the library (i.e., all types for which no `to_json()` function
1553 was provided), strong guarantee holds: if an exception is thrown, there are
1554 no changes to any JSON value.
1555
1556 @since version 3.2.0
1557 */
1558 template < typename BasicJsonType,
1559 detail::enable_if_t <
1560 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)1561 basic_json(const BasicJsonType& val)
1562 {
1563 using other_boolean_t = typename BasicJsonType::boolean_t;
1564 using other_number_float_t = typename BasicJsonType::number_float_t;
1565 using other_number_integer_t = typename BasicJsonType::number_integer_t;
1566 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1567 using other_string_t = typename BasicJsonType::string_t;
1568 using other_object_t = typename BasicJsonType::object_t;
1569 using other_array_t = typename BasicJsonType::array_t;
1570 using other_binary_t = typename BasicJsonType::binary_t;
1571
1572 switch (val.type())
1573 {
1574 case value_t::boolean:
1575 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
1576 break;
1577 case value_t::number_float:
1578 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
1579 break;
1580 case value_t::number_integer:
1581 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
1582 break;
1583 case value_t::number_unsigned:
1584 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
1585 break;
1586 case value_t::string:
1587 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
1588 break;
1589 case value_t::object:
1590 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
1591 break;
1592 case value_t::array:
1593 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
1594 break;
1595 case value_t::binary:
1596 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
1597 break;
1598 case value_t::null:
1599 *this = nullptr;
1600 break;
1601 case value_t::discarded:
1602 m_type = value_t::discarded;
1603 break;
1604 default: // LCOV_EXCL_LINE
1605 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
1606 }
1607 set_parents();
1608 assert_invariant();
1609 }
1610
1611 /*!
1612 @brief create a container (array or object) from an initializer list
1613
1614 Creates a JSON value of type array or object from the passed initializer
1615 list @a init. In case @a type_deduction is `true` (default), the type of
1616 the JSON value to be created is deducted from the initializer list @a init
1617 according to the following rules:
1618
1619 1. If the list is empty, an empty JSON object value `{}` is created.
1620 2. If the list consists of pairs whose first element is a string, a JSON
1621 object value is created where the first elements of the pairs are
1622 treated as keys and the second elements are as values.
1623 3. In all other cases, an array is created.
1624
1625 The rules aim to create the best fit between a C++ initializer list and
1626 JSON values. The rationale is as follows:
1627
1628 1. The empty initializer list is written as `{}` which is exactly an empty
1629 JSON object.
1630 2. C++ has no way of describing mapped types other than to list a list of
1631 pairs. As JSON requires that keys must be of type string, rule 2 is the
1632 weakest constraint one can pose on initializer lists to interpret them
1633 as an object.
1634 3. In all other cases, the initializer list could not be interpreted as
1635 JSON object type, so interpreting it as JSON array type is safe.
1636
1637 With the rules described above, the following JSON values cannot be
1638 expressed by an initializer list:
1639
1640 - the empty array (`[]`): use @ref array(initializer_list_t)
1641 with an empty initializer list in this case
1642 - arrays whose elements satisfy rule 2: use @ref
1643 array(initializer_list_t) with the same initializer list
1644 in this case
1645
1646 @note When used without parentheses around an empty initializer list, @ref
1647 basic_json() is called instead of this function, yielding the JSON null
1648 value.
1649
1650 @param[in] init initializer list with JSON values
1651
1652 @param[in] type_deduction internal parameter; when set to `true`, the type
1653 of the JSON value is deducted from the initializer list @a init; when set
1654 to `false`, the type provided via @a manual_type is forced. This mode is
1655 used by the functions @ref array(initializer_list_t) and
1656 @ref object(initializer_list_t).
1657
1658 @param[in] manual_type internal parameter; when @a type_deduction is set
1659 to `false`, the created JSON value will use the provided type (only @ref
1660 value_t::array and @ref value_t::object are valid); when @a type_deduction
1661 is set to `true`, this parameter has no effect
1662
1663 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
1664 `value_t::object`, but @a init contains an element which is not a pair
1665 whose first element is a string. In this case, the constructor could not
1666 create an object. If @a type_deduction would have be `true`, an array
1667 would have been created. See @ref object(initializer_list_t)
1668 for an example.
1669
1670 @complexity Linear in the size of the initializer list @a init.
1671
1672 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1673 changes to any JSON value.
1674
1675 @liveexample{The example below shows how JSON values are created from
1676 initializer lists.,basic_json__list_init_t}
1677
1678 @sa see @ref array(initializer_list_t) -- create a JSON array
1679 value from an initializer list
1680 @sa see @ref object(initializer_list_t) -- create a JSON object
1681 value from an initializer list
1682
1683 @since version 1.0.0
1684 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)1685 basic_json(initializer_list_t init,
1686 bool type_deduction = true,
1687 value_t manual_type = value_t::array)
1688 {
1689 // check if each element is an array with two elements whose first
1690 // element is a string
1691 bool is_an_object = std::all_of(init.begin(), init.end(),
1692 [](const detail::json_ref<basic_json>& element_ref)
1693 {
1694 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
1695 });
1696
1697 // adjust type if type deduction is not wanted
1698 if (!type_deduction)
1699 {
1700 // if array is wanted, do not create an object though possible
1701 if (manual_type == value_t::array)
1702 {
1703 is_an_object = false;
1704 }
1705
1706 // if object is wanted but impossible, throw an exception
1707 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
1708 {
1709 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
1710 }
1711 }
1712
1713 if (is_an_object)
1714 {
1715 // the initializer list is a list of pairs -> create object
1716 m_type = value_t::object;
1717 m_value = value_t::object;
1718
1719 for (auto& element_ref : init)
1720 {
1721 auto element = element_ref.moved_or_copied();
1722 m_value.object->emplace(
1723 std::move(*((*element.m_value.array)[0].m_value.string)),
1724 std::move((*element.m_value.array)[1]));
1725 }
1726 }
1727 else
1728 {
1729 // the initializer list describes an array -> create array
1730 m_type = value_t::array;
1731 m_value.array = create<array_t>(init.begin(), init.end());
1732 }
1733
1734 set_parents();
1735 assert_invariant();
1736 }
1737
1738 /*!
1739 @brief explicitly create a binary array (without subtype)
1740
1741 Creates a JSON binary array value from a given binary container. Binary
1742 values are part of various binary formats, such as CBOR, MessagePack, and
1743 BSON. This constructor is used to create a value for serialization to those
1744 formats.
1745
1746 @note Note, this function exists because of the difficulty in correctly
1747 specifying the correct template overload in the standard value ctor, as both
1748 JSON arrays and JSON binary arrays are backed with some form of a
1749 `std::vector`. Because JSON binary arrays are a non-standard extension it
1750 was decided that it would be best to prevent automatic initialization of a
1751 binary array type, for backwards compatibility and so it does not happen on
1752 accident.
1753
1754 @param[in] init container containing bytes to use as binary type
1755
1756 @return JSON binary array value
1757
1758 @complexity Linear in the size of @a init.
1759
1760 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1761 changes to any JSON value.
1762
1763 @since version 3.8.0
1764 */
1765 JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)1766 static basic_json binary(const typename binary_t::container_type& init)
1767 {
1768 auto res = basic_json();
1769 res.m_type = value_t::binary;
1770 res.m_value = init;
1771 return res;
1772 }
1773
1774 /*!
1775 @brief explicitly create a binary array (with subtype)
1776
1777 Creates a JSON binary array value from a given binary container. Binary
1778 values are part of various binary formats, such as CBOR, MessagePack, and
1779 BSON. This constructor is used to create a value for serialization to those
1780 formats.
1781
1782 @note Note, this function exists because of the difficulty in correctly
1783 specifying the correct template overload in the standard value ctor, as both
1784 JSON arrays and JSON binary arrays are backed with some form of a
1785 `std::vector`. Because JSON binary arrays are a non-standard extension it
1786 was decided that it would be best to prevent automatic initialization of a
1787 binary array type, for backwards compatibility and so it does not happen on
1788 accident.
1789
1790 @param[in] init container containing bytes to use as binary type
1791 @param[in] subtype subtype to use in MessagePack and BSON
1792
1793 @return JSON binary array value
1794
1795 @complexity Linear in the size of @a init.
1796
1797 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1798 changes to any JSON value.
1799
1800 @since version 3.8.0
1801 */
1802 JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,std::uint8_t subtype)1803 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
1804 {
1805 auto res = basic_json();
1806 res.m_type = value_t::binary;
1807 res.m_value = binary_t(init, subtype);
1808 return res;
1809 }
1810
1811 /// @copydoc binary(const typename binary_t::container_type&)
1812 JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)1813 static basic_json binary(typename binary_t::container_type&& init)
1814 {
1815 auto res = basic_json();
1816 res.m_type = value_t::binary;
1817 res.m_value = std::move(init);
1818 return res;
1819 }
1820
1821 /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
1822 JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,std::uint8_t subtype)1823 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
1824 {
1825 auto res = basic_json();
1826 res.m_type = value_t::binary;
1827 res.m_value = binary_t(std::move(init), subtype);
1828 return res;
1829 }
1830
1831 /*!
1832 @brief explicitly create an array from an initializer list
1833
1834 Creates a JSON array value from a given initializer list. That is, given a
1835 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
1836 initializer list is empty, the empty array `[]` is created.
1837
1838 @note This function is only needed to express two edge cases that cannot
1839 be realized with the initializer list constructor (@ref
1840 basic_json(initializer_list_t, bool, value_t)). These cases
1841 are:
1842 1. creating an array whose elements are all pairs whose first element is a
1843 string -- in this case, the initializer list constructor would create an
1844 object, taking the first elements as keys
1845 2. creating an empty array -- passing the empty initializer list to the
1846 initializer list constructor yields an empty object
1847
1848 @param[in] init initializer list with JSON values to create an array from
1849 (optional)
1850
1851 @return JSON array value
1852
1853 @complexity Linear in the size of @a init.
1854
1855 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1856 changes to any JSON value.
1857
1858 @liveexample{The following code shows an example for the `array`
1859 function.,array}
1860
1861 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
1862 create a JSON value from an initializer list
1863 @sa see @ref object(initializer_list_t) -- create a JSON object
1864 value from an initializer list
1865
1866 @since version 1.0.0
1867 */
1868 JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})1869 static basic_json array(initializer_list_t init = {})
1870 {
1871 return basic_json(init, false, value_t::array);
1872 }
1873
1874 /*!
1875 @brief explicitly create an object from an initializer list
1876
1877 Creates a JSON object value from a given initializer list. The initializer
1878 lists elements must be pairs, and their first elements must be strings. If
1879 the initializer list is empty, the empty object `{}` is created.
1880
1881 @note This function is only added for symmetry reasons. In contrast to the
1882 related function @ref array(initializer_list_t), there are
1883 no cases which can only be expressed by this function. That is, any
1884 initializer list @a init can also be passed to the initializer list
1885 constructor @ref basic_json(initializer_list_t, bool, value_t).
1886
1887 @param[in] init initializer list to create an object from (optional)
1888
1889 @return JSON object value
1890
1891 @throw type_error.301 if @a init is not a list of pairs whose first
1892 elements are strings. In this case, no object can be created. When such a
1893 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
1894 an array would have been created from the passed initializer list @a init.
1895 See example below.
1896
1897 @complexity Linear in the size of @a init.
1898
1899 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1900 changes to any JSON value.
1901
1902 @liveexample{The following code shows an example for the `object`
1903 function.,object}
1904
1905 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
1906 create a JSON value from an initializer list
1907 @sa see @ref array(initializer_list_t) -- create a JSON array
1908 value from an initializer list
1909
1910 @since version 1.0.0
1911 */
1912 JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})1913 static basic_json object(initializer_list_t init = {})
1914 {
1915 return basic_json(init, false, value_t::object);
1916 }
1917
1918 /*!
1919 @brief construct an array with count copies of given value
1920
1921 Constructs a JSON array value by creating @a cnt copies of a passed value.
1922 In case @a cnt is `0`, an empty array is created.
1923
1924 @param[in] cnt the number of JSON copies of @a val to create
1925 @param[in] val the JSON value to copy
1926
1927 @post `std::distance(begin(),end()) == cnt` holds.
1928
1929 @complexity Linear in @a cnt.
1930
1931 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1932 changes to any JSON value.
1933
1934 @liveexample{The following code shows examples for the @ref
1935 basic_json(size_type\, const basic_json&)
1936 constructor.,basic_json__size_type_basic_json}
1937
1938 @since version 1.0.0
1939 */
basic_json(size_type cnt,const basic_json & val)1940 basic_json(size_type cnt, const basic_json& val)
1941 : m_type(value_t::array)
1942 {
1943 m_value.array = create<array_t>(cnt, val);
1944 set_parents();
1945 assert_invariant();
1946 }
1947
1948 /*!
1949 @brief construct a JSON container given an iterator range
1950
1951 Constructs the JSON value with the contents of the range `[first, last)`.
1952 The semantics depends on the different types a JSON value can have:
1953 - In case of a null type, invalid_iterator.206 is thrown.
1954 - In case of other primitive types (number, boolean, or string), @a first
1955 must be `begin()` and @a last must be `end()`. In this case, the value is
1956 copied. Otherwise, invalid_iterator.204 is thrown.
1957 - In case of structured types (array, object), the constructor behaves as
1958 similar versions for `std::vector` or `std::map`; that is, a JSON array
1959 or object is constructed from the values in the range.
1960
1961 @tparam InputIT an input iterator type (@ref iterator or @ref
1962 const_iterator)
1963
1964 @param[in] first begin of the range to copy from (included)
1965 @param[in] last end of the range to copy from (excluded)
1966
1967 @pre Iterators @a first and @a last must be initialized. **This
1968 precondition is enforced with an assertion (see warning).** If
1969 assertions are switched off, a violation of this precondition yields
1970 undefined behavior.
1971
1972 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
1973 checked efficiently. Only certain edge cases are detected; see the
1974 description of the exceptions below. A violation of this precondition
1975 yields undefined behavior.
1976
1977 @warning A precondition is enforced with a runtime assertion that will
1978 result in calling `std::abort` if this precondition is not met.
1979 Assertions can be disabled by defining `NDEBUG` at compile time.
1980 See https://en.cppreference.com/w/cpp/error/assert for more
1981 information.
1982
1983 @throw invalid_iterator.201 if iterators @a first and @a last are not
1984 compatible (i.e., do not belong to the same JSON value). In this case,
1985 the range `[first, last)` is undefined.
1986 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
1987 primitive type (number, boolean, or string), but @a first does not point
1988 to the first element any more. In this case, the range `[first, last)` is
1989 undefined. See example code below.
1990 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
1991 null value. In this case, the range `[first, last)` is undefined.
1992
1993 @complexity Linear in distance between @a first and @a last.
1994
1995 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
1996 changes to any JSON value.
1997
1998 @liveexample{The example below shows several ways to create JSON values by
1999 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
2000
2001 @since version 1.0.0
2002 */
2003 template < class InputIT, typename std::enable_if <
2004 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
2005 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)2006 basic_json(InputIT first, InputIT last)
2007 {
2008 JSON_ASSERT(first.m_object != nullptr);
2009 JSON_ASSERT(last.m_object != nullptr);
2010
2011 // make sure iterator fits the current value
2012 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
2013 {
2014 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
2015 }
2016
2017 // copy type from first iterator
2018 m_type = first.m_object->m_type;
2019
2020 // check if iterator range is complete for primitive values
2021 switch (m_type)
2022 {
2023 case value_t::boolean:
2024 case value_t::number_float:
2025 case value_t::number_integer:
2026 case value_t::number_unsigned:
2027 case value_t::string:
2028 {
2029 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
2030 || !last.m_it.primitive_iterator.is_end()))
2031 {
2032 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
2033 }
2034 break;
2035 }
2036
2037 default:
2038 break;
2039 }
2040
2041 switch (m_type)
2042 {
2043 case value_t::number_integer:
2044 {
2045 m_value.number_integer = first.m_object->m_value.number_integer;
2046 break;
2047 }
2048
2049 case value_t::number_unsigned:
2050 {
2051 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2052 break;
2053 }
2054
2055 case value_t::number_float:
2056 {
2057 m_value.number_float = first.m_object->m_value.number_float;
2058 break;
2059 }
2060
2061 case value_t::boolean:
2062 {
2063 m_value.boolean = first.m_object->m_value.boolean;
2064 break;
2065 }
2066
2067 case value_t::string:
2068 {
2069 m_value = *first.m_object->m_value.string;
2070 break;
2071 }
2072
2073 case value_t::object:
2074 {
2075 m_value.object = create<object_t>(first.m_it.object_iterator,
2076 last.m_it.object_iterator);
2077 break;
2078 }
2079
2080 case value_t::array:
2081 {
2082 m_value.array = create<array_t>(first.m_it.array_iterator,
2083 last.m_it.array_iterator);
2084 break;
2085 }
2086
2087 case value_t::binary:
2088 {
2089 m_value = *first.m_object->m_value.binary;
2090 break;
2091 }
2092
2093 default:
2094 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
2095 }
2096
2097 set_parents();
2098 assert_invariant();
2099 }
2100
2101
2102 ///////////////////////////////////////
2103 // other constructors and destructor //
2104 ///////////////////////////////////////
2105
2106 template<typename JsonRef,
2107 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
2108 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)2109 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
2110
2111 /*!
2112 @brief copy constructor
2113
2114 Creates a copy of a given JSON value.
2115
2116 @param[in] other the JSON value to copy
2117
2118 @post `*this == other`
2119
2120 @complexity Linear in the size of @a other.
2121
2122 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2123 changes to any JSON value.
2124
2125 @requirement This function helps `basic_json` satisfying the
2126 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2127 requirements:
2128 - The complexity is linear.
2129 - As postcondition, it holds: `other == basic_json(other)`.
2130
2131 @liveexample{The following code shows an example for the copy
2132 constructor.,basic_json__basic_json}
2133
2134 @since version 1.0.0
2135 */
basic_json(const basic_json & other)2136 basic_json(const basic_json& other)
2137 : m_type(other.m_type)
2138 {
2139 // check of passed value is valid
2140 other.assert_invariant();
2141
2142 switch (m_type)
2143 {
2144 case value_t::object:
2145 {
2146 m_value = *other.m_value.object;
2147 break;
2148 }
2149
2150 case value_t::array:
2151 {
2152 m_value = *other.m_value.array;
2153 break;
2154 }
2155
2156 case value_t::string:
2157 {
2158 m_value = *other.m_value.string;
2159 break;
2160 }
2161
2162 case value_t::boolean:
2163 {
2164 m_value = other.m_value.boolean;
2165 break;
2166 }
2167
2168 case value_t::number_integer:
2169 {
2170 m_value = other.m_value.number_integer;
2171 break;
2172 }
2173
2174 case value_t::number_unsigned:
2175 {
2176 m_value = other.m_value.number_unsigned;
2177 break;
2178 }
2179
2180 case value_t::number_float:
2181 {
2182 m_value = other.m_value.number_float;
2183 break;
2184 }
2185
2186 case value_t::binary:
2187 {
2188 m_value = *other.m_value.binary;
2189 break;
2190 }
2191
2192 default:
2193 break;
2194 }
2195
2196 set_parents();
2197 assert_invariant();
2198 }
2199
2200 /*!
2201 @brief move constructor
2202
2203 Move constructor. Constructs a JSON value with the contents of the given
2204 value @a other using move semantics. It "steals" the resources from @a
2205 other and leaves it as JSON null value.
2206
2207 @param[in,out] other value to move to this object
2208
2209 @post `*this` has the same value as @a other before the call.
2210 @post @a other is a JSON null value.
2211
2212 @complexity Constant.
2213
2214 @exceptionsafety No-throw guarantee: this constructor never throws
2215 exceptions.
2216
2217 @requirement This function helps `basic_json` satisfying the
2218 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
2219 requirements.
2220
2221 @liveexample{The code below shows the move constructor explicitly called
2222 via std::move.,basic_json__moveconstructor}
2223
2224 @since version 1.0.0
2225 */
basic_json(basic_json && other)2226 basic_json(basic_json&& other) noexcept
2227 : m_type(std::move(other.m_type)),
2228 m_value(std::move(other.m_value))
2229 {
2230 // check that passed value is valid
2231 other.assert_invariant(false);
2232
2233 // invalidate payload
2234 other.m_type = value_t::null;
2235 other.m_value = {};
2236
2237 set_parents();
2238 assert_invariant();
2239 }
2240
2241 /*!
2242 @brief copy assignment
2243
2244 Copy assignment operator. Copies a JSON value via the "copy and swap"
2245 strategy: It is expressed in terms of the copy constructor, destructor,
2246 and the `swap()` member function.
2247
2248 @param[in] other value to copy from
2249
2250 @complexity Linear.
2251
2252 @requirement This function helps `basic_json` satisfying the
2253 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2254 requirements:
2255 - The complexity is linear.
2256
2257 @liveexample{The code below shows and example for the copy assignment. It
2258 creates a copy of value `a` which is then swapped with `b`. Finally\, the
2259 copy of `a` (which is the null value after the swap) is
2260 destroyed.,basic_json__copyassignment}
2261
2262 @since version 1.0.0
2263 */
operator =(basic_json other)2264 basic_json& operator=(basic_json other) noexcept (
2265 std::is_nothrow_move_constructible<value_t>::value&&
2266 std::is_nothrow_move_assignable<value_t>::value&&
2267 std::is_nothrow_move_constructible<json_value>::value&&
2268 std::is_nothrow_move_assignable<json_value>::value
2269 )
2270 {
2271 // check that passed value is valid
2272 other.assert_invariant();
2273
2274 using std::swap;
2275 swap(m_type, other.m_type);
2276 swap(m_value, other.m_value);
2277
2278 set_parents();
2279 assert_invariant();
2280 return *this;
2281 }
2282
2283 /*!
2284 @brief destructor
2285
2286 Destroys the JSON value and frees all allocated memory.
2287
2288 @complexity Linear.
2289
2290 @requirement This function helps `basic_json` satisfying the
2291 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
2292 requirements:
2293 - The complexity is linear.
2294 - All stored elements are destroyed and all memory is freed.
2295
2296 @since version 1.0.0
2297 */
~basic_json()2298 ~basic_json() noexcept
2299 {
2300 assert_invariant(false);
2301 m_value.destroy(m_type);
2302 }
2303
2304 /// @}
2305
2306 public:
2307 ///////////////////////
2308 // object inspection //
2309 ///////////////////////
2310
2311 /// @name object inspection
2312 /// Functions to inspect the type of a JSON value.
2313 /// @{
2314
2315 /*!
2316 @brief serialization
2317
2318 Serialization function for JSON values. The function tries to mimic
2319 Python's `json.dumps()` function, and currently supports its @a indent
2320 and @a ensure_ascii parameters.
2321
2322 @param[in] indent If indent is nonnegative, then array elements and object
2323 members will be pretty-printed with that indent level. An indent level of
2324 `0` will only insert newlines. `-1` (the default) selects the most compact
2325 representation.
2326 @param[in] indent_char The character to use for indentation if @a indent is
2327 greater than `0`. The default is ` ` (space).
2328 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
2329 in the output are escaped with `\uXXXX` sequences, and the result consists
2330 of ASCII characters only.
2331 @param[in] error_handler how to react on decoding errors; there are three
2332 possible values: `strict` (throws and exception in case a decoding error
2333 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
2334 and `ignore` (ignore invalid UTF-8 sequences during serialization; all
2335 bytes are copied to the output unchanged).
2336
2337 @return string containing the serialization of the JSON value
2338
2339 @throw type_error.316 if a string stored inside the JSON value is not
2340 UTF-8 encoded and @a error_handler is set to strict
2341
2342 @note Binary values are serialized as object containing two keys:
2343 - "bytes": an array of bytes as integers
2344 - "subtype": the subtype as integer or "null" if the binary has no subtype
2345
2346 @complexity Linear.
2347
2348 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2349 changes in the JSON value.
2350
2351 @liveexample{The following example shows the effect of different @a indent\,
2352 @a indent_char\, and @a ensure_ascii parameters to the result of the
2353 serialization.,dump}
2354
2355 @see https://docs.python.org/2/library/json.html#json.dump
2356
2357 @since version 1.0.0; indentation character @a indent_char, option
2358 @a ensure_ascii and exceptions added in version 3.0.0; error
2359 handlers added in version 3.4.0; serialization of binary values added
2360 in version 3.8.0.
2361 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const2362 string_t dump(const int indent = -1,
2363 const char indent_char = ' ',
2364 const bool ensure_ascii = false,
2365 const error_handler_t error_handler = error_handler_t::strict) const
2366 {
2367 string_t result;
2368 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
2369
2370 if (indent >= 0)
2371 {
2372 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
2373 }
2374 else
2375 {
2376 s.dump(*this, false, ensure_ascii, 0);
2377 }
2378
2379 return result;
2380 }
2381
2382 /*!
2383 @brief return the type of the JSON value (explicit)
2384
2385 Return the type of the JSON value as a value from the @ref value_t
2386 enumeration.
2387
2388 @return the type of the JSON value
2389 Value type | return value
2390 ------------------------- | -------------------------
2391 null | value_t::null
2392 boolean | value_t::boolean
2393 string | value_t::string
2394 number (integer) | value_t::number_integer
2395 number (unsigned integer) | value_t::number_unsigned
2396 number (floating-point) | value_t::number_float
2397 object | value_t::object
2398 array | value_t::array
2399 binary | value_t::binary
2400 discarded | value_t::discarded
2401
2402 @complexity Constant.
2403
2404 @exceptionsafety No-throw guarantee: this member function never throws
2405 exceptions.
2406
2407 @liveexample{The following code exemplifies `type()` for all JSON
2408 types.,type}
2409
2410 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
2411 @sa see @ref type_name() -- return the type as string
2412
2413 @since version 1.0.0
2414 */
type() const2415 constexpr value_t type() const noexcept
2416 {
2417 return m_type;
2418 }
2419
2420 /*!
2421 @brief return whether type is primitive
2422
2423 This function returns true if and only if the JSON type is primitive
2424 (string, number, boolean, or null).
2425
2426 @return `true` if type is primitive (string, number, boolean, or null),
2427 `false` otherwise.
2428
2429 @complexity Constant.
2430
2431 @exceptionsafety No-throw guarantee: this member function never throws
2432 exceptions.
2433
2434 @liveexample{The following code exemplifies `is_primitive()` for all JSON
2435 types.,is_primitive}
2436
2437 @sa see @ref is_structured() -- returns whether JSON value is structured
2438 @sa see @ref is_null() -- returns whether JSON value is `null`
2439 @sa see @ref is_string() -- returns whether JSON value is a string
2440 @sa see @ref is_boolean() -- returns whether JSON value is a boolean
2441 @sa see @ref is_number() -- returns whether JSON value is a number
2442 @sa see @ref is_binary() -- returns whether JSON value is a binary array
2443
2444 @since version 1.0.0
2445 */
is_primitive() const2446 constexpr bool is_primitive() const noexcept
2447 {
2448 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
2449 }
2450
2451 /*!
2452 @brief return whether type is structured
2453
2454 This function returns true if and only if the JSON type is structured
2455 (array or object).
2456
2457 @return `true` if type is structured (array or object), `false` otherwise.
2458
2459 @complexity Constant.
2460
2461 @exceptionsafety No-throw guarantee: this member function never throws
2462 exceptions.
2463
2464 @liveexample{The following code exemplifies `is_structured()` for all JSON
2465 types.,is_structured}
2466
2467 @sa see @ref is_primitive() -- returns whether value is primitive
2468 @sa see @ref is_array() -- returns whether value is an array
2469 @sa see @ref is_object() -- returns whether value is an object
2470
2471 @since version 1.0.0
2472 */
is_structured() const2473 constexpr bool is_structured() const noexcept
2474 {
2475 return is_array() || is_object();
2476 }
2477
2478 /*!
2479 @brief return whether value is null
2480
2481 This function returns true if and only if the JSON value is null.
2482
2483 @return `true` if type is null, `false` otherwise.
2484
2485 @complexity Constant.
2486
2487 @exceptionsafety No-throw guarantee: this member function never throws
2488 exceptions.
2489
2490 @liveexample{The following code exemplifies `is_null()` for all JSON
2491 types.,is_null}
2492
2493 @since version 1.0.0
2494 */
is_null() const2495 constexpr bool is_null() const noexcept
2496 {
2497 return m_type == value_t::null;
2498 }
2499
2500 /*!
2501 @brief return whether value is a boolean
2502
2503 This function returns true if and only if the JSON value is a boolean.
2504
2505 @return `true` if type is boolean, `false` otherwise.
2506
2507 @complexity Constant.
2508
2509 @exceptionsafety No-throw guarantee: this member function never throws
2510 exceptions.
2511
2512 @liveexample{The following code exemplifies `is_boolean()` for all JSON
2513 types.,is_boolean}
2514
2515 @since version 1.0.0
2516 */
is_boolean() const2517 constexpr bool is_boolean() const noexcept
2518 {
2519 return m_type == value_t::boolean;
2520 }
2521
2522 /*!
2523 @brief return whether value is a number
2524
2525 This function returns true if and only if the JSON value is a number. This
2526 includes both integer (signed and unsigned) and floating-point values.
2527
2528 @return `true` if type is number (regardless whether integer, unsigned
2529 integer or floating-type), `false` otherwise.
2530
2531 @complexity Constant.
2532
2533 @exceptionsafety No-throw guarantee: this member function never throws
2534 exceptions.
2535
2536 @liveexample{The following code exemplifies `is_number()` for all JSON
2537 types.,is_number}
2538
2539 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
2540 integer number
2541 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
2542 number
2543 @sa see @ref is_number_float() -- check if value is a floating-point number
2544
2545 @since version 1.0.0
2546 */
is_number() const2547 constexpr bool is_number() const noexcept
2548 {
2549 return is_number_integer() || is_number_float();
2550 }
2551
2552 /*!
2553 @brief return whether value is an integer number
2554
2555 This function returns true if and only if the JSON value is a signed or
2556 unsigned integer number. This excludes floating-point values.
2557
2558 @return `true` if type is an integer or unsigned integer number, `false`
2559 otherwise.
2560
2561 @complexity Constant.
2562
2563 @exceptionsafety No-throw guarantee: this member function never throws
2564 exceptions.
2565
2566 @liveexample{The following code exemplifies `is_number_integer()` for all
2567 JSON types.,is_number_integer}
2568
2569 @sa see @ref is_number() -- check if value is a number
2570 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
2571 number
2572 @sa see @ref is_number_float() -- check if value is a floating-point number
2573
2574 @since version 1.0.0
2575 */
is_number_integer() const2576 constexpr bool is_number_integer() const noexcept
2577 {
2578 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
2579 }
2580
2581 /*!
2582 @brief return whether value is an unsigned integer number
2583
2584 This function returns true if and only if the JSON value is an unsigned
2585 integer number. This excludes floating-point and signed integer values.
2586
2587 @return `true` if type is an unsigned integer number, `false` otherwise.
2588
2589 @complexity Constant.
2590
2591 @exceptionsafety No-throw guarantee: this member function never throws
2592 exceptions.
2593
2594 @liveexample{The following code exemplifies `is_number_unsigned()` for all
2595 JSON types.,is_number_unsigned}
2596
2597 @sa see @ref is_number() -- check if value is a number
2598 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
2599 integer number
2600 @sa see @ref is_number_float() -- check if value is a floating-point number
2601
2602 @since version 2.0.0
2603 */
is_number_unsigned() const2604 constexpr bool is_number_unsigned() const noexcept
2605 {
2606 return m_type == value_t::number_unsigned;
2607 }
2608
2609 /*!
2610 @brief return whether value is a floating-point number
2611
2612 This function returns true if and only if the JSON value is a
2613 floating-point number. This excludes signed and unsigned integer values.
2614
2615 @return `true` if type is a floating-point number, `false` otherwise.
2616
2617 @complexity Constant.
2618
2619 @exceptionsafety No-throw guarantee: this member function never throws
2620 exceptions.
2621
2622 @liveexample{The following code exemplifies `is_number_float()` for all
2623 JSON types.,is_number_float}
2624
2625 @sa see @ref is_number() -- check if value is number
2626 @sa see @ref is_number_integer() -- check if value is an integer number
2627 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
2628 number
2629
2630 @since version 1.0.0
2631 */
is_number_float() const2632 constexpr bool is_number_float() const noexcept
2633 {
2634 return m_type == value_t::number_float;
2635 }
2636
2637 /*!
2638 @brief return whether value is an object
2639
2640 This function returns true if and only if the JSON value is an object.
2641
2642 @return `true` if type is object, `false` otherwise.
2643
2644 @complexity Constant.
2645
2646 @exceptionsafety No-throw guarantee: this member function never throws
2647 exceptions.
2648
2649 @liveexample{The following code exemplifies `is_object()` for all JSON
2650 types.,is_object}
2651
2652 @since version 1.0.0
2653 */
is_object() const2654 constexpr bool is_object() const noexcept
2655 {
2656 return m_type == value_t::object;
2657 }
2658
2659 /*!
2660 @brief return whether value is an array
2661
2662 This function returns true if and only if the JSON value is an array.
2663
2664 @return `true` if type is array, `false` otherwise.
2665
2666 @complexity Constant.
2667
2668 @exceptionsafety No-throw guarantee: this member function never throws
2669 exceptions.
2670
2671 @liveexample{The following code exemplifies `is_array()` for all JSON
2672 types.,is_array}
2673
2674 @since version 1.0.0
2675 */
is_array() const2676 constexpr bool is_array() const noexcept
2677 {
2678 return m_type == value_t::array;
2679 }
2680
2681 /*!
2682 @brief return whether value is a string
2683
2684 This function returns true if and only if the JSON value is a string.
2685
2686 @return `true` if type is string, `false` otherwise.
2687
2688 @complexity Constant.
2689
2690 @exceptionsafety No-throw guarantee: this member function never throws
2691 exceptions.
2692
2693 @liveexample{The following code exemplifies `is_string()` for all JSON
2694 types.,is_string}
2695
2696 @since version 1.0.0
2697 */
is_string() const2698 constexpr bool is_string() const noexcept
2699 {
2700 return m_type == value_t::string;
2701 }
2702
2703 /*!
2704 @brief return whether value is a binary array
2705
2706 This function returns true if and only if the JSON value is a binary array.
2707
2708 @return `true` if type is binary array, `false` otherwise.
2709
2710 @complexity Constant.
2711
2712 @exceptionsafety No-throw guarantee: this member function never throws
2713 exceptions.
2714
2715 @liveexample{The following code exemplifies `is_binary()` for all JSON
2716 types.,is_binary}
2717
2718 @since version 3.8.0
2719 */
is_binary() const2720 constexpr bool is_binary() const noexcept
2721 {
2722 return m_type == value_t::binary;
2723 }
2724
2725 /*!
2726 @brief return whether value is discarded
2727
2728 This function returns true if and only if the JSON value was discarded
2729 during parsing with a callback function (see @ref parser_callback_t).
2730
2731 @note This function will always be `false` for JSON values after parsing.
2732 That is, discarded values can only occur during parsing, but will be
2733 removed when inside a structured value or replaced by null in other cases.
2734
2735 @return `true` if type is discarded, `false` otherwise.
2736
2737 @complexity Constant.
2738
2739 @exceptionsafety No-throw guarantee: this member function never throws
2740 exceptions.
2741
2742 @liveexample{The following code exemplifies `is_discarded()` for all JSON
2743 types.,is_discarded}
2744
2745 @since version 1.0.0
2746 */
is_discarded() const2747 constexpr bool is_discarded() const noexcept
2748 {
2749 return m_type == value_t::discarded;
2750 }
2751
2752 /*!
2753 @brief return the type of the JSON value (implicit)
2754
2755 Implicitly return the type of the JSON value as a value from the @ref
2756 value_t enumeration.
2757
2758 @return the type of the JSON value
2759
2760 @complexity Constant.
2761
2762 @exceptionsafety No-throw guarantee: this member function never throws
2763 exceptions.
2764
2765 @liveexample{The following code exemplifies the @ref value_t operator for
2766 all JSON types.,operator__value_t}
2767
2768 @sa see @ref type() -- return the type of the JSON value (explicit)
2769 @sa see @ref type_name() -- return the type as string
2770
2771 @since version 1.0.0
2772 */
operator value_t() const2773 constexpr operator value_t() const noexcept
2774 {
2775 return m_type;
2776 }
2777
2778 /// @}
2779
2780 private:
2781 //////////////////
2782 // value access //
2783 //////////////////
2784
2785 /// get a boolean (explicit)
get_impl(boolean_t *) const2786 boolean_t get_impl(boolean_t* /*unused*/) const
2787 {
2788 if (JSON_HEDLEY_LIKELY(is_boolean()))
2789 {
2790 return m_value.boolean;
2791 }
2792
2793 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
2794 }
2795
2796 /// get a pointer to the value (object)
get_impl_ptr(object_t *)2797 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
2798 {
2799 return is_object() ? m_value.object : nullptr;
2800 }
2801
2802 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const2803 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
2804 {
2805 return is_object() ? m_value.object : nullptr;
2806 }
2807
2808 /// get a pointer to the value (array)
get_impl_ptr(array_t *)2809 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
2810 {
2811 return is_array() ? m_value.array : nullptr;
2812 }
2813
2814 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const2815 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
2816 {
2817 return is_array() ? m_value.array : nullptr;
2818 }
2819
2820 /// get a pointer to the value (string)
get_impl_ptr(string_t *)2821 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
2822 {
2823 return is_string() ? m_value.string : nullptr;
2824 }
2825
2826 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const2827 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
2828 {
2829 return is_string() ? m_value.string : nullptr;
2830 }
2831
2832 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)2833 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
2834 {
2835 return is_boolean() ? &m_value.boolean : nullptr;
2836 }
2837
2838 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const2839 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
2840 {
2841 return is_boolean() ? &m_value.boolean : nullptr;
2842 }
2843
2844 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)2845 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
2846 {
2847 return is_number_integer() ? &m_value.number_integer : nullptr;
2848 }
2849
2850 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const2851 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
2852 {
2853 return is_number_integer() ? &m_value.number_integer : nullptr;
2854 }
2855
2856 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)2857 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
2858 {
2859 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2860 }
2861
2862 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const2863 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
2864 {
2865 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
2866 }
2867
2868 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)2869 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
2870 {
2871 return is_number_float() ? &m_value.number_float : nullptr;
2872 }
2873
2874 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const2875 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
2876 {
2877 return is_number_float() ? &m_value.number_float : nullptr;
2878 }
2879
2880 /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)2881 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
2882 {
2883 return is_binary() ? m_value.binary : nullptr;
2884 }
2885
2886 /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const2887 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
2888 {
2889 return is_binary() ? m_value.binary : nullptr;
2890 }
2891
2892 /*!
2893 @brief helper function to implement get_ref()
2894
2895 This function helps to implement get_ref() without code duplication for
2896 const and non-const overloads
2897
2898 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
2899
2900 @throw type_error.303 if ReferenceType does not match underlying value
2901 type of the current JSON
2902 */
2903 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)2904 static ReferenceType get_ref_impl(ThisType& obj)
2905 {
2906 // delegate the call to get_ptr<>()
2907 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
2908
2909 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
2910 {
2911 return *ptr;
2912 }
2913
2914 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
2915 }
2916
2917 public:
2918 /// @name value access
2919 /// Direct access to the stored value of a JSON value.
2920 /// @{
2921
2922 /*!
2923 @brief get a pointer value (implicit)
2924
2925 Implicit pointer access to the internally stored JSON value. No copies are
2926 made.
2927
2928 @warning Writing data to the pointee of the result yields an undefined
2929 state.
2930
2931 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
2932 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
2933 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
2934 assertion.
2935
2936 @return pointer to the internally stored JSON value if the requested
2937 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
2938
2939 @complexity Constant.
2940
2941 @liveexample{The example below shows how pointers to internal values of a
2942 JSON value can be requested. Note that no type conversions are made and a
2943 `nullptr` is returned if the value and the requested pointer type does not
2944 match.,get_ptr}
2945
2946 @since version 1.0.0
2947 */
2948 template<typename PointerType, typename std::enable_if<
2949 std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()2950 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2951 {
2952 // delegate the call to get_impl_ptr<>()
2953 return get_impl_ptr(static_cast<PointerType>(nullptr));
2954 }
2955
2956 /*!
2957 @brief get a pointer value (implicit)
2958 @copydoc get_ptr()
2959 */
2960 template < typename PointerType, typename std::enable_if <
2961 std::is_pointer<PointerType>::value&&
2962 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const2963 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
2964 {
2965 // delegate the call to get_impl_ptr<>() const
2966 return get_impl_ptr(static_cast<PointerType>(nullptr));
2967 }
2968
2969 private:
2970 /*!
2971 @brief get a value (explicit)
2972
2973 Explicit type conversion between the JSON value and a compatible value
2974 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
2975 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
2976 The value is converted by calling the @ref json_serializer<ValueType>
2977 `from_json()` method.
2978
2979 The function is equivalent to executing
2980 @code {.cpp}
2981 ValueType ret;
2982 JSONSerializer<ValueType>::from_json(*this, ret);
2983 return ret;
2984 @endcode
2985
2986 This overloads is chosen if:
2987 - @a ValueType is not @ref basic_json,
2988 - @ref json_serializer<ValueType> has a `from_json()` method of the form
2989 `void from_json(const basic_json&, ValueType&)`, and
2990 - @ref json_serializer<ValueType> does not have a `from_json()` method of
2991 the form `ValueType from_json(const basic_json&)`
2992
2993 @tparam ValueType the returned value type
2994
2995 @return copy of the JSON value, converted to @a ValueType
2996
2997 @throw what @ref json_serializer<ValueType> `from_json()` method throws
2998
2999 @liveexample{The example below shows several conversions from JSON values
3000 to other types. There a few things to note: (1) Floating-point numbers can
3001 be converted to integers\, (2) A JSON array can be converted to a standard
3002 `std::vector<short>`\, (3) A JSON object can be converted to C++
3003 associative containers such as `std::unordered_map<std::string\,
3004 json>`.,get__ValueType_const}
3005
3006 @since version 2.1.0
3007 */
3008 template < typename ValueType,
3009 detail::enable_if_t <
3010 detail::is_default_constructible<ValueType>::value&&
3011 detail::has_from_json<basic_json_t, ValueType>::value,
3012 int > = 0 >
3013 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
3014 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3015 {
3016 ValueType ret{};
3017 JSONSerializer<ValueType>::from_json(*this, ret);
3018 return ret;
3019 }
3020
3021 /*!
3022 @brief get a value (explicit); special case
3023
3024 Explicit type conversion between the JSON value and a compatible value
3025 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
3026 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
3027 The value is converted by calling the @ref json_serializer<ValueType>
3028 `from_json()` method.
3029
3030 The function is equivalent to executing
3031 @code {.cpp}
3032 return JSONSerializer<ValueType>::from_json(*this);
3033 @endcode
3034
3035 This overloads is chosen if:
3036 - @a ValueType is not @ref basic_json and
3037 - @ref json_serializer<ValueType> has a `from_json()` method of the form
3038 `ValueType from_json(const basic_json&)`
3039
3040 @note If @ref json_serializer<ValueType> has both overloads of
3041 `from_json()`, this one is chosen.
3042
3043 @tparam ValueType the returned value type
3044
3045 @return copy of the JSON value, converted to @a ValueType
3046
3047 @throw what @ref json_serializer<ValueType> `from_json()` method throws
3048
3049 @since version 2.1.0
3050 */
3051 template < typename ValueType,
3052 detail::enable_if_t <
3053 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
3054 int > = 0 >
3055 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
3056 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
3057 {
3058 return JSONSerializer<ValueType>::from_json(*this);
3059 }
3060
3061 /*!
3062 @brief get special-case overload
3063
3064 This overloads converts the current @ref basic_json in a different
3065 @ref basic_json type
3066
3067 @tparam BasicJsonType == @ref basic_json
3068
3069 @return a copy of *this, converted into @a BasicJsonType
3070
3071 @complexity Depending on the implementation of the called `from_json()`
3072 method.
3073
3074 @since version 3.2.0
3075 */
3076 template < typename BasicJsonType,
3077 detail::enable_if_t <
3078 detail::is_basic_json<BasicJsonType>::value,
3079 int > = 0 >
3080 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
3081 {
3082 return *this;
3083 }
3084
3085 /*!
3086 @brief get special-case overload
3087
3088 This overloads avoids a lot of template boilerplate, it can be seen as the
3089 identity method
3090
3091 @tparam BasicJsonType == @ref basic_json
3092
3093 @return a copy of *this
3094
3095 @complexity Constant.
3096
3097 @since version 2.1.0
3098 */
3099 template<typename BasicJsonType,
3100 detail::enable_if_t<
3101 std::is_same<BasicJsonType, basic_json_t>::value,
3102 int> = 0>
get_impl(detail::priority_tag<3>) const3103 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
3104 {
3105 return *this;
3106 }
3107
3108 /*!
3109 @brief get a pointer value (explicit)
3110 @copydoc get()
3111 */
3112 template<typename PointerType,
3113 detail::enable_if_t<
3114 std::is_pointer<PointerType>::value,
3115 int> = 0>
get_impl(detail::priority_tag<4>) const3116 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
3117 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
3118 {
3119 // delegate the call to get_ptr
3120 return get_ptr<PointerType>();
3121 }
3122
3123 public:
3124 /*!
3125 @brief get a (pointer) value (explicit)
3126
3127 Performs explicit type conversion between the JSON value and a compatible value if required.
3128
3129 - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
3130 No copies are made.
3131
3132 - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
3133 from the current @ref basic_json.
3134
3135 - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
3136 method.
3137
3138 @tparam ValueTypeCV the provided value type
3139 @tparam ValueType the returned value type
3140
3141 @return copy of the JSON value, converted to @tparam ValueType if necessary
3142
3143 @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
3144
3145 @since version 2.1.0
3146 */
3147 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
3148 #if defined(JSON_HAS_CPP_14)
3149 constexpr
3150 #endif
get() const3151 auto get() const noexcept(
3152 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
3153 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
3154 {
3155 // we cannot static_assert on ValueTypeCV being non-const, because
3156 // there is support for get<const basic_json_t>(), which is why we
3157 // still need the uncvref
3158 static_assert(!std::is_reference<ValueTypeCV>::value,
3159 "get() cannot be used with reference types, you might want to use get_ref()");
3160 return get_impl<ValueType>(detail::priority_tag<4> {});
3161 }
3162
3163 /*!
3164 @brief get a pointer value (explicit)
3165
3166 Explicit pointer access to the internally stored JSON value. No copies are
3167 made.
3168
3169 @warning The pointer becomes invalid if the underlying JSON object
3170 changes.
3171
3172 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
3173 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
3174 @ref number_unsigned_t, or @ref number_float_t.
3175
3176 @return pointer to the internally stored JSON value if the requested
3177 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
3178
3179 @complexity Constant.
3180
3181 @liveexample{The example below shows how pointers to internal values of a
3182 JSON value can be requested. Note that no type conversions are made and a
3183 `nullptr` is returned if the value and the requested pointer type does not
3184 match.,get__PointerType}
3185
3186 @sa see @ref get_ptr() for explicit pointer-member access
3187
3188 @since version 1.0.0
3189 */
3190 template<typename PointerType, typename std::enable_if<
3191 std::is_pointer<PointerType>::value, int>::type = 0>
get()3192 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
3193 {
3194 // delegate the call to get_ptr
3195 return get_ptr<PointerType>();
3196 }
3197
3198 /*!
3199 @brief get a value (explicit)
3200
3201 Explicit type conversion between the JSON value and a compatible value.
3202 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
3203 `from_json()` method.
3204
3205 The function is equivalent to executing
3206 @code {.cpp}
3207 ValueType v;
3208 JSONSerializer<ValueType>::from_json(*this, v);
3209 @endcode
3210
3211 This overloads is chosen if:
3212 - @a ValueType is not @ref basic_json,
3213 - @ref json_serializer<ValueType> has a `from_json()` method of the form
3214 `void from_json(const basic_json&, ValueType&)`, and
3215
3216 @tparam ValueType the input parameter type.
3217
3218 @return the input parameter, allowing chaining calls.
3219
3220 @throw what @ref json_serializer<ValueType> `from_json()` method throws
3221
3222 @liveexample{The example below shows several conversions from JSON values
3223 to other types. There a few things to note: (1) Floating-point numbers can
3224 be converted to integers\, (2) A JSON array can be converted to a standard
3225 `std::vector<short>`\, (3) A JSON object can be converted to C++
3226 associative containers such as `std::unordered_map<std::string\,
3227 json>`.,get_to}
3228
3229 @since version 3.3.0
3230 */
3231 template < typename ValueType,
3232 detail::enable_if_t <
3233 !detail::is_basic_json<ValueType>::value&&
3234 detail::has_from_json<basic_json_t, ValueType>::value,
3235 int > = 0 >
3236 ValueType & get_to(ValueType& v) const noexcept(noexcept(
3237 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
3238 {
3239 JSONSerializer<ValueType>::from_json(*this, v);
3240 return v;
3241 }
3242
3243 // specialization to allow to call get_to with a basic_json value
3244 // see https://github.com/nlohmann/json/issues/2175
3245 template<typename ValueType,
3246 detail::enable_if_t <
3247 detail::is_basic_json<ValueType>::value,
3248 int> = 0>
3249 ValueType & get_to(ValueType& v) const
3250 {
3251 v = *this;
3252 return v;
3253 }
3254
3255 template <
3256 typename T, std::size_t N,
3257 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3258 detail::enable_if_t <
3259 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
3260 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3261 noexcept(noexcept(JSONSerializer<Array>::from_json(
3262 std::declval<const basic_json_t&>(), v)))
3263 {
3264 JSONSerializer<Array>::from_json(*this, v);
3265 return v;
3266 }
3267
3268 /*!
3269 @brief get a reference value (implicit)
3270
3271 Implicit reference access to the internally stored JSON value. No copies
3272 are made.
3273
3274 @warning Writing data to the referee of the result yields an undefined
3275 state.
3276
3277 @tparam ReferenceType reference type; must be a reference to @ref array_t,
3278 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
3279 @ref number_float_t. Enforced by static assertion.
3280
3281 @return reference to the internally stored JSON value if the requested
3282 reference type @a ReferenceType fits to the JSON value; throws
3283 type_error.303 otherwise
3284
3285 @throw type_error.303 in case passed type @a ReferenceType is incompatible
3286 with the stored JSON value; see example below
3287
3288 @complexity Constant.
3289
3290 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
3291
3292 @since version 1.1.0
3293 */
3294 template<typename ReferenceType, typename std::enable_if<
3295 std::is_reference<ReferenceType>::value, int>::type = 0>
3296 ReferenceType get_ref()
3297 {
3298 // delegate call to get_ref_impl
3299 return get_ref_impl<ReferenceType>(*this);
3300 }
3301
3302 /*!
3303 @brief get a reference value (implicit)
3304 @copydoc get_ref()
3305 */
3306 template < typename ReferenceType, typename std::enable_if <
3307 std::is_reference<ReferenceType>::value&&
3308 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
3309 ReferenceType get_ref() const
3310 {
3311 // delegate call to get_ref_impl
3312 return get_ref_impl<ReferenceType>(*this);
3313 }
3314
3315 /*!
3316 @brief get a value (implicit)
3317
3318 Implicit type conversion between the JSON value and a compatible value.
3319 The call is realized by calling @ref get() const.
3320
3321 @tparam ValueType non-pointer type compatible to the JSON value, for
3322 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
3323 `std::vector` types for JSON arrays. The character type of @ref string_t
3324 as well as an initializer list of this type is excluded to avoid
3325 ambiguities as these types implicitly convert to `std::string`.
3326
3327 @return copy of the JSON value, converted to type @a ValueType
3328
3329 @throw type_error.302 in case passed type @a ValueType is incompatible
3330 to the JSON value type (e.g., the JSON value is of type boolean, but a
3331 string is requested); see example below
3332
3333 @complexity Linear in the size of the JSON value.
3334
3335 @liveexample{The example below shows several conversions from JSON values
3336 to other types. There a few things to note: (1) Floating-point numbers can
3337 be converted to integers\, (2) A JSON array can be converted to a standard
3338 `std::vector<short>`\, (3) A JSON object can be converted to C++
3339 associative containers such as `std::unordered_map<std::string\,
3340 json>`.,operator__ValueType}
3341
3342 @since version 1.0.0
3343 */
3344 template < typename ValueType, typename std::enable_if <
3345 !std::is_pointer<ValueType>::value&&
3346 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
3347 !std::is_same<ValueType, typename string_t::value_type>::value&&
3348 !detail::is_basic_json<ValueType>::value
3349 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3350 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
3351 && !std::is_same<ValueType, typename std::string_view>::value
3352 #endif
3353 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
3354 , int >::type = 0 >
operator ValueType() const3355 JSON_EXPLICIT operator ValueType() const
3356 {
3357 // delegate the call to get<>() const
3358 return get<ValueType>();
3359 }
3360
3361 /*!
3362 @return reference to the binary value
3363
3364 @throw type_error.302 if the value is not binary
3365
3366 @sa see @ref is_binary() to check if the value is binary
3367
3368 @since version 3.8.0
3369 */
get_binary()3370 binary_t& get_binary()
3371 {
3372 if (!is_binary())
3373 {
3374 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
3375 }
3376
3377 return *get_ptr<binary_t*>();
3378 }
3379
3380 /// @copydoc get_binary()
get_binary() const3381 const binary_t& get_binary() const
3382 {
3383 if (!is_binary())
3384 {
3385 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
3386 }
3387
3388 return *get_ptr<const binary_t*>();
3389 }
3390
3391 /// @}
3392
3393
3394 ////////////////////
3395 // element access //
3396 ////////////////////
3397
3398 /// @name element access
3399 /// Access to the JSON value.
3400 /// @{
3401
3402 /*!
3403 @brief access specified array element with bounds checking
3404
3405 Returns a reference to the element at specified location @a idx, with
3406 bounds checking.
3407
3408 @param[in] idx index of the element to access
3409
3410 @return reference to the element at index @a idx
3411
3412 @throw type_error.304 if the JSON value is not an array; in this case,
3413 calling `at` with an index makes no sense. See example below.
3414 @throw out_of_range.401 if the index @a idx is out of range of the array;
3415 that is, `idx >= size()`. See example below.
3416
3417 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3418 changes in the JSON value.
3419
3420 @complexity Constant.
3421
3422 @since version 1.0.0
3423
3424 @liveexample{The example below shows how array elements can be read and
3425 written using `at()`. It also demonstrates the different exceptions that
3426 can be thrown.,at__size_type}
3427 */
at(size_type idx)3428 reference at(size_type idx)
3429 {
3430 // at only works for arrays
3431 if (JSON_HEDLEY_LIKELY(is_array()))
3432 {
3433 JSON_TRY
3434 {
3435 return set_parent(m_value.array->at(idx));
3436 }
3437 JSON_CATCH (std::out_of_range&)
3438 {
3439 // create better exception explanation
3440 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
3441 }
3442 }
3443 else
3444 {
3445 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
3446 }
3447 }
3448
3449 /*!
3450 @brief access specified array element with bounds checking
3451
3452 Returns a const reference to the element at specified location @a idx,
3453 with bounds checking.
3454
3455 @param[in] idx index of the element to access
3456
3457 @return const reference to the element at index @a idx
3458
3459 @throw type_error.304 if the JSON value is not an array; in this case,
3460 calling `at` with an index makes no sense. See example below.
3461 @throw out_of_range.401 if the index @a idx is out of range of the array;
3462 that is, `idx >= size()`. See example below.
3463
3464 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3465 changes in the JSON value.
3466
3467 @complexity Constant.
3468
3469 @since version 1.0.0
3470
3471 @liveexample{The example below shows how array elements can be read using
3472 `at()`. It also demonstrates the different exceptions that can be thrown.,
3473 at__size_type_const}
3474 */
at(size_type idx) const3475 const_reference at(size_type idx) const
3476 {
3477 // at only works for arrays
3478 if (JSON_HEDLEY_LIKELY(is_array()))
3479 {
3480 JSON_TRY
3481 {
3482 return m_value.array->at(idx);
3483 }
3484 JSON_CATCH (std::out_of_range&)
3485 {
3486 // create better exception explanation
3487 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
3488 }
3489 }
3490 else
3491 {
3492 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
3493 }
3494 }
3495
3496 /*!
3497 @brief access specified object element with bounds checking
3498
3499 Returns a reference to the element at with specified key @a key, with
3500 bounds checking.
3501
3502 @param[in] key key of the element to access
3503
3504 @return reference to the element at key @a key
3505
3506 @throw type_error.304 if the JSON value is not an object; in this case,
3507 calling `at` with a key makes no sense. See example below.
3508 @throw out_of_range.403 if the key @a key is is not stored in the object;
3509 that is, `find(key) == end()`. See example below.
3510
3511 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3512 changes in the JSON value.
3513
3514 @complexity Logarithmic in the size of the container.
3515
3516 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
3517 access by reference
3518 @sa see @ref value() for access by value with a default value
3519
3520 @since version 1.0.0
3521
3522 @liveexample{The example below shows how object elements can be read and
3523 written using `at()`. It also demonstrates the different exceptions that
3524 can be thrown.,at__object_t_key_type}
3525 */
at(const typename object_t::key_type & key)3526 reference at(const typename object_t::key_type& key)
3527 {
3528 // at only works for objects
3529 if (JSON_HEDLEY_LIKELY(is_object()))
3530 {
3531 JSON_TRY
3532 {
3533 return set_parent(m_value.object->at(key));
3534 }
3535 JSON_CATCH (std::out_of_range&)
3536 {
3537 // create better exception explanation
3538 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
3539 }
3540 }
3541 else
3542 {
3543 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
3544 }
3545 }
3546
3547 /*!
3548 @brief access specified object element with bounds checking
3549
3550 Returns a const reference to the element at with specified key @a key,
3551 with bounds checking.
3552
3553 @param[in] key key of the element to access
3554
3555 @return const reference to the element at key @a key
3556
3557 @throw type_error.304 if the JSON value is not an object; in this case,
3558 calling `at` with a key makes no sense. See example below.
3559 @throw out_of_range.403 if the key @a key is is not stored in the object;
3560 that is, `find(key) == end()`. See example below.
3561
3562 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3563 changes in the JSON value.
3564
3565 @complexity Logarithmic in the size of the container.
3566
3567 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
3568 access by reference
3569 @sa see @ref value() for access by value with a default value
3570
3571 @since version 1.0.0
3572
3573 @liveexample{The example below shows how object elements can be read using
3574 `at()`. It also demonstrates the different exceptions that can be thrown.,
3575 at__object_t_key_type_const}
3576 */
at(const typename object_t::key_type & key) const3577 const_reference at(const typename object_t::key_type& key) const
3578 {
3579 // at only works for objects
3580 if (JSON_HEDLEY_LIKELY(is_object()))
3581 {
3582 JSON_TRY
3583 {
3584 return m_value.object->at(key);
3585 }
3586 JSON_CATCH (std::out_of_range&)
3587 {
3588 // create better exception explanation
3589 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
3590 }
3591 }
3592 else
3593 {
3594 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
3595 }
3596 }
3597
3598 /*!
3599 @brief access specified array element
3600
3601 Returns a reference to the element at specified location @a idx.
3602
3603 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
3604 then the array is silently filled up with `null` values to make `idx` a
3605 valid reference to the last stored element.
3606
3607 @param[in] idx index of the element to access
3608
3609 @return reference to the element at index @a idx
3610
3611 @throw type_error.305 if the JSON value is not an array or null; in that
3612 cases, using the [] operator with an index makes no sense.
3613
3614 @complexity Constant if @a idx is in the range of the array. Otherwise
3615 linear in `idx - size()`.
3616
3617 @liveexample{The example below shows how array elements can be read and
3618 written using `[]` operator. Note the addition of `null`
3619 values.,operatorarray__size_type}
3620
3621 @since version 1.0.0
3622 */
operator [](size_type idx)3623 reference operator[](size_type idx)
3624 {
3625 // implicitly convert null value to an empty array
3626 if (is_null())
3627 {
3628 m_type = value_t::array;
3629 m_value.array = create<array_t>();
3630 assert_invariant();
3631 }
3632
3633 // operator[] only works for arrays
3634 if (JSON_HEDLEY_LIKELY(is_array()))
3635 {
3636 // fill up array with null values if given idx is outside range
3637 if (idx >= m_value.array->size())
3638 {
3639 #if JSON_DIAGNOSTICS
3640 // remember array size before resizing
3641 const auto previous_size = m_value.array->size();
3642 #endif
3643 m_value.array->resize(idx + 1);
3644
3645 #if JSON_DIAGNOSTICS
3646 // set parent for values added above
3647 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
3648 #endif
3649 }
3650
3651 return m_value.array->operator[](idx);
3652 }
3653
3654 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
3655 }
3656
3657 /*!
3658 @brief access specified array element
3659
3660 Returns a const reference to the element at specified location @a idx.
3661
3662 @param[in] idx index of the element to access
3663
3664 @return const reference to the element at index @a idx
3665
3666 @throw type_error.305 if the JSON value is not an array; in that case,
3667 using the [] operator with an index makes no sense.
3668
3669 @complexity Constant.
3670
3671 @liveexample{The example below shows how array elements can be read using
3672 the `[]` operator.,operatorarray__size_type_const}
3673
3674 @since version 1.0.0
3675 */
operator [](size_type idx) const3676 const_reference operator[](size_type idx) const
3677 {
3678 // const operator[] only works for arrays
3679 if (JSON_HEDLEY_LIKELY(is_array()))
3680 {
3681 return m_value.array->operator[](idx);
3682 }
3683
3684 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
3685 }
3686
3687 /*!
3688 @brief access specified object element
3689
3690 Returns a reference to the element at with specified key @a key.
3691
3692 @note If @a key is not found in the object, then it is silently added to
3693 the object and filled with a `null` value to make `key` a valid reference.
3694 In case the value was `null` before, it is converted to an object.
3695
3696 @param[in] key key of the element to access
3697
3698 @return reference to the element at key @a key
3699
3700 @throw type_error.305 if the JSON value is not an object or null; in that
3701 cases, using the [] operator with a key makes no sense.
3702
3703 @complexity Logarithmic in the size of the container.
3704
3705 @liveexample{The example below shows how object elements can be read and
3706 written using the `[]` operator.,operatorarray__key_type}
3707
3708 @sa see @ref at(const typename object_t::key_type&) for access by reference
3709 with range checking
3710 @sa see @ref value() for access by value with a default value
3711
3712 @since version 1.0.0
3713 */
operator [](const typename object_t::key_type & key)3714 reference operator[](const typename object_t::key_type& key)
3715 {
3716 // implicitly convert null value to an empty object
3717 if (is_null())
3718 {
3719 m_type = value_t::object;
3720 m_value.object = create<object_t>();
3721 assert_invariant();
3722 }
3723
3724 // operator[] only works for objects
3725 if (JSON_HEDLEY_LIKELY(is_object()))
3726 {
3727 return set_parent(m_value.object->operator[](key));
3728 }
3729
3730 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
3731 }
3732
3733 /*!
3734 @brief read-only access specified object element
3735
3736 Returns a const reference to the element at with specified key @a key. No
3737 bounds checking is performed.
3738
3739 @warning If the element with key @a key does not exist, the behavior is
3740 undefined.
3741
3742 @param[in] key key of the element to access
3743
3744 @return const reference to the element at key @a key
3745
3746 @pre The element with key @a key must exist. **This precondition is
3747 enforced with an assertion.**
3748
3749 @throw type_error.305 if the JSON value is not an object; in that case,
3750 using the [] operator with a key makes no sense.
3751
3752 @complexity Logarithmic in the size of the container.
3753
3754 @liveexample{The example below shows how object elements can be read using
3755 the `[]` operator.,operatorarray__key_type_const}
3756
3757 @sa see @ref at(const typename object_t::key_type&) for access by reference
3758 with range checking
3759 @sa see @ref value() for access by value with a default value
3760
3761 @since version 1.0.0
3762 */
operator [](const typename object_t::key_type & key) const3763 const_reference operator[](const typename object_t::key_type& key) const
3764 {
3765 // const operator[] only works for objects
3766 if (JSON_HEDLEY_LIKELY(is_object()))
3767 {
3768 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
3769 return m_value.object->find(key)->second;
3770 }
3771
3772 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
3773 }
3774
3775 /*!
3776 @brief access specified object element
3777
3778 Returns a reference to the element at with specified key @a key.
3779
3780 @note If @a key is not found in the object, then it is silently added to
3781 the object and filled with a `null` value to make `key` a valid reference.
3782 In case the value was `null` before, it is converted to an object.
3783
3784 @param[in] key key of the element to access
3785
3786 @return reference to the element at key @a key
3787
3788 @throw type_error.305 if the JSON value is not an object or null; in that
3789 cases, using the [] operator with a key makes no sense.
3790
3791 @complexity Logarithmic in the size of the container.
3792
3793 @liveexample{The example below shows how object elements can be read and
3794 written using the `[]` operator.,operatorarray__key_type}
3795
3796 @sa see @ref at(const typename object_t::key_type&) for access by reference
3797 with range checking
3798 @sa see @ref value() for access by value with a default value
3799
3800 @since version 1.1.0
3801 */
3802 template<typename T>
3803 JSON_HEDLEY_NON_NULL(2)
operator [](T * key)3804 reference operator[](T* key)
3805 {
3806 // implicitly convert null to object
3807 if (is_null())
3808 {
3809 m_type = value_t::object;
3810 m_value = value_t::object;
3811 assert_invariant();
3812 }
3813
3814 // at only works for objects
3815 if (JSON_HEDLEY_LIKELY(is_object()))
3816 {
3817 return set_parent(m_value.object->operator[](key));
3818 }
3819
3820 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
3821 }
3822
3823 /*!
3824 @brief read-only access specified object element
3825
3826 Returns a const reference to the element at with specified key @a key. No
3827 bounds checking is performed.
3828
3829 @warning If the element with key @a key does not exist, the behavior is
3830 undefined.
3831
3832 @param[in] key key of the element to access
3833
3834 @return const reference to the element at key @a key
3835
3836 @pre The element with key @a key must exist. **This precondition is
3837 enforced with an assertion.**
3838
3839 @throw type_error.305 if the JSON value is not an object; in that case,
3840 using the [] operator with a key makes no sense.
3841
3842 @complexity Logarithmic in the size of the container.
3843
3844 @liveexample{The example below shows how object elements can be read using
3845 the `[]` operator.,operatorarray__key_type_const}
3846
3847 @sa see @ref at(const typename object_t::key_type&) for access by reference
3848 with range checking
3849 @sa see @ref value() for access by value with a default value
3850
3851 @since version 1.1.0
3852 */
3853 template<typename T>
3854 JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const3855 const_reference operator[](T* key) const
3856 {
3857 // at only works for objects
3858 if (JSON_HEDLEY_LIKELY(is_object()))
3859 {
3860 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
3861 return m_value.object->find(key)->second;
3862 }
3863
3864 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
3865 }
3866
3867 /*!
3868 @brief access specified object element with default value
3869
3870 Returns either a copy of an object's element at the specified key @a key
3871 or a given default value if no element with key @a key exists.
3872
3873 The function is basically equivalent to executing
3874 @code {.cpp}
3875 try {
3876 return at(key);
3877 } catch(out_of_range) {
3878 return default_value;
3879 }
3880 @endcode
3881
3882 @note Unlike @ref at(const typename object_t::key_type&), this function
3883 does not throw if the given key @a key was not found.
3884
3885 @note Unlike @ref operator[](const typename object_t::key_type& key), this
3886 function does not implicitly add an element to the position defined by @a
3887 key. This function is furthermore also applicable to const objects.
3888
3889 @param[in] key key of the element to access
3890 @param[in] default_value the value to return if @a key is not found
3891
3892 @tparam ValueType type compatible to JSON values, for instance `int` for
3893 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
3894 JSON arrays. Note the type of the expected value at @a key and the default
3895 value @a default_value must be compatible.
3896
3897 @return copy of the element at key @a key or @a default_value if @a key
3898 is not found
3899
3900 @throw type_error.302 if @a default_value does not match the type of the
3901 value at @a key
3902 @throw type_error.306 if the JSON value is not an object; in that case,
3903 using `value()` with a key makes no sense.
3904
3905 @complexity Logarithmic in the size of the container.
3906
3907 @liveexample{The example below shows how object elements can be queried
3908 with a default value.,basic_json__value}
3909
3910 @sa see @ref at(const typename object_t::key_type&) for access by reference
3911 with range checking
3912 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
3913 access by reference
3914
3915 @since version 1.0.0
3916 */
3917 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
3918 template < class ValueType, typename std::enable_if <
3919 detail::is_getable<basic_json_t, ValueType>::value
3920 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
3921 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
3922 {
3923 // at only works for objects
3924 if (JSON_HEDLEY_LIKELY(is_object()))
3925 {
3926 // if key is found, return value and given default value otherwise
3927 const auto it = find(key);
3928 if (it != end())
3929 {
3930 return it->template get<ValueType>();
3931 }
3932
3933 return default_value;
3934 }
3935
3936 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
3937 }
3938
3939 /*!
3940 @brief overload for a default value of type const char*
3941 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
3942 */
value(const typename object_t::key_type & key,const char * default_value) const3943 string_t value(const typename object_t::key_type& key, const char* default_value) const
3944 {
3945 return value(key, string_t(default_value));
3946 }
3947
3948 /*!
3949 @brief access specified object element via JSON Pointer with default value
3950
3951 Returns either a copy of an object's element at the specified key @a key
3952 or a given default value if no element with key @a key exists.
3953
3954 The function is basically equivalent to executing
3955 @code {.cpp}
3956 try {
3957 return at(ptr);
3958 } catch(out_of_range) {
3959 return default_value;
3960 }
3961 @endcode
3962
3963 @note Unlike @ref at(const json_pointer&), this function does not throw
3964 if the given key @a key was not found.
3965
3966 @param[in] ptr a JSON pointer to the element to access
3967 @param[in] default_value the value to return if @a ptr found no value
3968
3969 @tparam ValueType type compatible to JSON values, for instance `int` for
3970 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
3971 JSON arrays. Note the type of the expected value at @a key and the default
3972 value @a default_value must be compatible.
3973
3974 @return copy of the element at key @a key or @a default_value if @a key
3975 is not found
3976
3977 @throw type_error.302 if @a default_value does not match the type of the
3978 value at @a ptr
3979 @throw type_error.306 if the JSON value is not an object; in that case,
3980 using `value()` with a key makes no sense.
3981
3982 @complexity Logarithmic in the size of the container.
3983
3984 @liveexample{The example below shows how object elements can be queried
3985 with a default value.,basic_json__value_ptr}
3986
3987 @sa see @ref operator[](const json_pointer&) for unchecked access by reference
3988
3989 @since version 2.0.2
3990 */
3991 template<class ValueType, typename std::enable_if<
3992 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
3993 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
3994 {
3995 // at only works for objects
3996 if (JSON_HEDLEY_LIKELY(is_object()))
3997 {
3998 // if pointer resolves a value, return it or use default value
3999 JSON_TRY
4000 {
4001 return ptr.get_checked(this).template get<ValueType>();
4002 }
4003 JSON_INTERNAL_CATCH (out_of_range&)
4004 {
4005 return default_value;
4006 }
4007 }
4008
4009 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
4010 }
4011
4012 /*!
4013 @brief overload for a default value of type const char*
4014 @copydoc basic_json::value(const json_pointer&, ValueType) const
4015 */
4016 JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const4017 string_t value(const json_pointer& ptr, const char* default_value) const
4018 {
4019 return value(ptr, string_t(default_value));
4020 }
4021
4022 /*!
4023 @brief access the first element
4024
4025 Returns a reference to the first element in the container. For a JSON
4026 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
4027
4028 @return In case of a structured type (array or object), a reference to the
4029 first element is returned. In case of number, string, boolean, or binary
4030 values, a reference to the value is returned.
4031
4032 @complexity Constant.
4033
4034 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
4035 or an empty array or object (undefined behavior, **guarded by
4036 assertions**).
4037 @post The JSON value remains unchanged.
4038
4039 @throw invalid_iterator.214 when called on `null` value
4040
4041 @liveexample{The following code shows an example for `front()`.,front}
4042
4043 @sa see @ref back() -- access the last element
4044
4045 @since version 1.0.0
4046 */
front()4047 reference front()
4048 {
4049 return *begin();
4050 }
4051
4052 /*!
4053 @copydoc basic_json::front()
4054 */
front() const4055 const_reference front() const
4056 {
4057 return *cbegin();
4058 }
4059
4060 /*!
4061 @brief access the last element
4062
4063 Returns a reference to the last element in the container. For a JSON
4064 container `c`, the expression `c.back()` is equivalent to
4065 @code {.cpp}
4066 auto tmp = c.end();
4067 --tmp;
4068 return *tmp;
4069 @endcode
4070
4071 @return In case of a structured type (array or object), a reference to the
4072 last element is returned. In case of number, string, boolean, or binary
4073 values, a reference to the value is returned.
4074
4075 @complexity Constant.
4076
4077 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
4078 or an empty array or object (undefined behavior, **guarded by
4079 assertions**).
4080 @post The JSON value remains unchanged.
4081
4082 @throw invalid_iterator.214 when called on a `null` value. See example
4083 below.
4084
4085 @liveexample{The following code shows an example for `back()`.,back}
4086
4087 @sa see @ref front() -- access the first element
4088
4089 @since version 1.0.0
4090 */
back()4091 reference back()
4092 {
4093 auto tmp = end();
4094 --tmp;
4095 return *tmp;
4096 }
4097
4098 /*!
4099 @copydoc basic_json::back()
4100 */
back() const4101 const_reference back() const
4102 {
4103 auto tmp = cend();
4104 --tmp;
4105 return *tmp;
4106 }
4107
4108 /*!
4109 @brief remove element given an iterator
4110
4111 Removes the element specified by iterator @a pos. The iterator @a pos must
4112 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
4113 but is not dereferenceable) cannot be used as a value for @a pos.
4114
4115 If called on a primitive type other than `null`, the resulting JSON value
4116 will be `null`.
4117
4118 @param[in] pos iterator to the element to remove
4119 @return Iterator following the last removed element. If the iterator @a
4120 pos refers to the last element, the `end()` iterator is returned.
4121
4122 @tparam IteratorType an @ref iterator or @ref const_iterator
4123
4124 @post Invalidates iterators and references at or after the point of the
4125 erase, including the `end()` iterator.
4126
4127 @throw type_error.307 if called on a `null` value; example: `"cannot use
4128 erase() with null"`
4129 @throw invalid_iterator.202 if called on an iterator which does not belong
4130 to the current JSON value; example: `"iterator does not fit current
4131 value"`
4132 @throw invalid_iterator.205 if called on a primitive type with invalid
4133 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
4134 out of range"`
4135
4136 @complexity The complexity depends on the type:
4137 - objects: amortized constant
4138 - arrays: linear in distance between @a pos and the end of the container
4139 - strings and binary: linear in the length of the member
4140 - other types: constant
4141
4142 @liveexample{The example shows the result of `erase()` for different JSON
4143 types.,erase__IteratorType}
4144
4145 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
4146 the given range
4147 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
4148 from an object at the given key
4149 @sa see @ref erase(const size_type) -- removes the element from an array at
4150 the given index
4151
4152 @since version 1.0.0
4153 */
4154 template < class IteratorType, typename std::enable_if <
4155 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
4156 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
4157 = 0 >
4158 IteratorType erase(IteratorType pos)
4159 {
4160 // make sure iterator fits the current value
4161 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
4162 {
4163 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
4164 }
4165
4166 IteratorType result = end();
4167
4168 switch (m_type)
4169 {
4170 case value_t::boolean:
4171 case value_t::number_float:
4172 case value_t::number_integer:
4173 case value_t::number_unsigned:
4174 case value_t::string:
4175 case value_t::binary:
4176 {
4177 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
4178 {
4179 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
4180 }
4181
4182 if (is_string())
4183 {
4184 AllocatorType<string_t> alloc;
4185 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
4186 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
4187 m_value.string = nullptr;
4188 }
4189 else if (is_binary())
4190 {
4191 AllocatorType<binary_t> alloc;
4192 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
4193 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
4194 m_value.binary = nullptr;
4195 }
4196
4197 m_type = value_t::null;
4198 assert_invariant();
4199 break;
4200 }
4201
4202 case value_t::object:
4203 {
4204 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4205 break;
4206 }
4207
4208 case value_t::array:
4209 {
4210 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4211 break;
4212 }
4213
4214 default:
4215 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
4216 }
4217
4218 return result;
4219 }
4220
4221 /*!
4222 @brief remove elements given an iterator range
4223
4224 Removes the element specified by the range `[first; last)`. The iterator
4225 @a first does not need to be dereferenceable if `first == last`: erasing
4226 an empty range is a no-op.
4227
4228 If called on a primitive type other than `null`, the resulting JSON value
4229 will be `null`.
4230
4231 @param[in] first iterator to the beginning of the range to remove
4232 @param[in] last iterator past the end of the range to remove
4233 @return Iterator following the last removed element. If the iterator @a
4234 second refers to the last element, the `end()` iterator is returned.
4235
4236 @tparam IteratorType an @ref iterator or @ref const_iterator
4237
4238 @post Invalidates iterators and references at or after the point of the
4239 erase, including the `end()` iterator.
4240
4241 @throw type_error.307 if called on a `null` value; example: `"cannot use
4242 erase() with null"`
4243 @throw invalid_iterator.203 if called on iterators which does not belong
4244 to the current JSON value; example: `"iterators do not fit current value"`
4245 @throw invalid_iterator.204 if called on a primitive type with invalid
4246 iterators (i.e., if `first != begin()` and `last != end()`); example:
4247 `"iterators out of range"`
4248
4249 @complexity The complexity depends on the type:
4250 - objects: `log(size()) + std::distance(first, last)`
4251 - arrays: linear in the distance between @a first and @a last, plus linear
4252 in the distance between @a last and end of the container
4253 - strings and binary: linear in the length of the member
4254 - other types: constant
4255
4256 @liveexample{The example shows the result of `erase()` for different JSON
4257 types.,erase__IteratorType_IteratorType}
4258
4259 @sa see @ref erase(IteratorType) -- removes the element at a given position
4260 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
4261 from an object at the given key
4262 @sa see @ref erase(const size_type) -- removes the element from an array at
4263 the given index
4264
4265 @since version 1.0.0
4266 */
4267 template < class IteratorType, typename std::enable_if <
4268 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
4269 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
4270 = 0 >
4271 IteratorType erase(IteratorType first, IteratorType last)
4272 {
4273 // make sure iterator fits the current value
4274 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
4275 {
4276 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
4277 }
4278
4279 IteratorType result = end();
4280
4281 switch (m_type)
4282 {
4283 case value_t::boolean:
4284 case value_t::number_float:
4285 case value_t::number_integer:
4286 case value_t::number_unsigned:
4287 case value_t::string:
4288 case value_t::binary:
4289 {
4290 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
4291 || !last.m_it.primitive_iterator.is_end()))
4292 {
4293 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
4294 }
4295
4296 if (is_string())
4297 {
4298 AllocatorType<string_t> alloc;
4299 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
4300 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
4301 m_value.string = nullptr;
4302 }
4303 else if (is_binary())
4304 {
4305 AllocatorType<binary_t> alloc;
4306 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
4307 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
4308 m_value.binary = nullptr;
4309 }
4310
4311 m_type = value_t::null;
4312 assert_invariant();
4313 break;
4314 }
4315
4316 case value_t::object:
4317 {
4318 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4319 last.m_it.object_iterator);
4320 break;
4321 }
4322
4323 case value_t::array:
4324 {
4325 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4326 last.m_it.array_iterator);
4327 break;
4328 }
4329
4330 default:
4331 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
4332 }
4333
4334 return result;
4335 }
4336
4337 /*!
4338 @brief remove element from a JSON object given a key
4339
4340 Removes elements from a JSON object with the key value @a key.
4341
4342 @param[in] key value of the elements to remove
4343
4344 @return Number of elements removed. If @a ObjectType is the default
4345 `std::map` type, the return value will always be `0` (@a key was not
4346 found) or `1` (@a key was found).
4347
4348 @post References and iterators to the erased elements are invalidated.
4349 Other references and iterators are not affected.
4350
4351 @throw type_error.307 when called on a type other than JSON object;
4352 example: `"cannot use erase() with null"`
4353
4354 @complexity `log(size()) + count(key)`
4355
4356 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
4357
4358 @sa see @ref erase(IteratorType) -- removes the element at a given position
4359 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
4360 the given range
4361 @sa see @ref erase(const size_type) -- removes the element from an array at
4362 the given index
4363
4364 @since version 1.0.0
4365 */
erase(const typename object_t::key_type & key)4366 size_type erase(const typename object_t::key_type& key)
4367 {
4368 // this erase only works for objects
4369 if (JSON_HEDLEY_LIKELY(is_object()))
4370 {
4371 return m_value.object->erase(key);
4372 }
4373
4374 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
4375 }
4376
4377 /*!
4378 @brief remove element from a JSON array given an index
4379
4380 Removes element from a JSON array at the index @a idx.
4381
4382 @param[in] idx index of the element to remove
4383
4384 @throw type_error.307 when called on a type other than JSON object;
4385 example: `"cannot use erase() with null"`
4386 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
4387 is out of range"`
4388
4389 @complexity Linear in distance between @a idx and the end of the container.
4390
4391 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
4392
4393 @sa see @ref erase(IteratorType) -- removes the element at a given position
4394 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
4395 the given range
4396 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
4397 from an object at the given key
4398
4399 @since version 1.0.0
4400 */
erase(const size_type idx)4401 void erase(const size_type idx)
4402 {
4403 // this erase only works for arrays
4404 if (JSON_HEDLEY_LIKELY(is_array()))
4405 {
4406 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
4407 {
4408 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
4409 }
4410
4411 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4412 }
4413 else
4414 {
4415 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
4416 }
4417 }
4418
4419 /// @}
4420
4421
4422 ////////////
4423 // lookup //
4424 ////////////
4425
4426 /// @name lookup
4427 /// @{
4428
4429 /*!
4430 @brief find an element in a JSON object
4431
4432 Finds an element in a JSON object with key equivalent to @a key. If the
4433 element is not found or the JSON value is not an object, end() is
4434 returned.
4435
4436 @note This method always returns @ref end() when executed on a JSON type
4437 that is not an object.
4438
4439 @param[in] key key value of the element to search for.
4440
4441 @return Iterator to an element with key equivalent to @a key. If no such
4442 element is found or the JSON value is not an object, past-the-end (see
4443 @ref end()) iterator is returned.
4444
4445 @complexity Logarithmic in the size of the JSON object.
4446
4447 @liveexample{The example shows how `find()` is used.,find__key_type}
4448
4449 @sa see @ref contains(KeyT&&) const -- checks whether a key exists
4450
4451 @since version 1.0.0
4452 */
4453 template<typename KeyT>
find(KeyT && key)4454 iterator find(KeyT&& key)
4455 {
4456 auto result = end();
4457
4458 if (is_object())
4459 {
4460 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
4461 }
4462
4463 return result;
4464 }
4465
4466 /*!
4467 @brief find an element in a JSON object
4468 @copydoc find(KeyT&&)
4469 */
4470 template<typename KeyT>
find(KeyT && key) const4471 const_iterator find(KeyT&& key) const
4472 {
4473 auto result = cend();
4474
4475 if (is_object())
4476 {
4477 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
4478 }
4479
4480 return result;
4481 }
4482
4483 /*!
4484 @brief returns the number of occurrences of a key in a JSON object
4485
4486 Returns the number of elements with key @a key. If ObjectType is the
4487 default `std::map` type, the return value will always be `0` (@a key was
4488 not found) or `1` (@a key was found).
4489
4490 @note This method always returns `0` when executed on a JSON type that is
4491 not an object.
4492
4493 @param[in] key key value of the element to count
4494
4495 @return Number of elements with key @a key. If the JSON value is not an
4496 object, the return value will be `0`.
4497
4498 @complexity Logarithmic in the size of the JSON object.
4499
4500 @liveexample{The example shows how `count()` is used.,count}
4501
4502 @since version 1.0.0
4503 */
4504 template<typename KeyT>
count(KeyT && key) const4505 size_type count(KeyT&& key) const
4506 {
4507 // return 0 for all nonobject types
4508 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
4509 }
4510
4511 /*!
4512 @brief check the existence of an element in a JSON object
4513
4514 Check whether an element exists in a JSON object with key equivalent to
4515 @a key. If the element is not found or the JSON value is not an object,
4516 false is returned.
4517
4518 @note This method always returns false when executed on a JSON type
4519 that is not an object.
4520
4521 @param[in] key key value to check its existence.
4522
4523 @return true if an element with specified @a key exists. If no such
4524 element with such key is found or the JSON value is not an object,
4525 false is returned.
4526
4527 @complexity Logarithmic in the size of the JSON object.
4528
4529 @liveexample{The following code shows an example for `contains()`.,contains}
4530
4531 @sa see @ref find(KeyT&&) -- returns an iterator to an object element
4532 @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
4533
4534 @since version 3.6.0
4535 */
4536 template < typename KeyT, typename std::enable_if <
4537 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const4538 bool contains(KeyT && key) const
4539 {
4540 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
4541 }
4542
4543 /*!
4544 @brief check the existence of an element in a JSON object given a JSON pointer
4545
4546 Check whether the given JSON pointer @a ptr can be resolved in the current
4547 JSON value.
4548
4549 @note This method can be executed on any JSON value type.
4550
4551 @param[in] ptr JSON pointer to check its existence.
4552
4553 @return true if the JSON pointer can be resolved to a stored value, false
4554 otherwise.
4555
4556 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
4557
4558 @throw parse_error.106 if an array index begins with '0'
4559 @throw parse_error.109 if an array index was not a number
4560
4561 @complexity Logarithmic in the size of the JSON object.
4562
4563 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
4564
4565 @sa see @ref contains(KeyT &&) const -- checks the existence of a key
4566
4567 @since version 3.7.0
4568 */
contains(const json_pointer & ptr) const4569 bool contains(const json_pointer& ptr) const
4570 {
4571 return ptr.contains(this);
4572 }
4573
4574 /// @}
4575
4576
4577 ///////////////
4578 // iterators //
4579 ///////////////
4580
4581 /// @name iterators
4582 /// @{
4583
4584 /*!
4585 @brief returns an iterator to the first element
4586
4587 Returns an iterator to the first element.
4588
4589 @image html range-begin-end.svg "Illustration from cppreference.com"
4590
4591 @return iterator to the first element
4592
4593 @complexity Constant.
4594
4595 @requirement This function helps `basic_json` satisfying the
4596 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
4597 requirements:
4598 - The complexity is constant.
4599
4600 @liveexample{The following code shows an example for `begin()`.,begin}
4601
4602 @sa see @ref cbegin() -- returns a const iterator to the beginning
4603 @sa see @ref end() -- returns an iterator to the end
4604 @sa see @ref cend() -- returns a const iterator to the end
4605
4606 @since version 1.0.0
4607 */
begin()4608 iterator begin() noexcept
4609 {
4610 iterator result(this);
4611 result.set_begin();
4612 return result;
4613 }
4614
4615 /*!
4616 @copydoc basic_json::cbegin()
4617 */
begin() const4618 const_iterator begin() const noexcept
4619 {
4620 return cbegin();
4621 }
4622
4623 /*!
4624 @brief returns a const iterator to the first element
4625
4626 Returns a const iterator to the first element.
4627
4628 @image html range-begin-end.svg "Illustration from cppreference.com"
4629
4630 @return const iterator to the first element
4631
4632 @complexity Constant.
4633
4634 @requirement This function helps `basic_json` satisfying the
4635 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
4636 requirements:
4637 - The complexity is constant.
4638 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
4639
4640 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
4641
4642 @sa see @ref begin() -- returns an iterator to the beginning
4643 @sa see @ref end() -- returns an iterator to the end
4644 @sa see @ref cend() -- returns a const iterator to the end
4645
4646 @since version 1.0.0
4647 */
cbegin() const4648 const_iterator cbegin() const noexcept
4649 {
4650 const_iterator result(this);
4651 result.set_begin();
4652 return result;
4653 }
4654
4655 /*!
4656 @brief returns an iterator to one past the last element
4657
4658 Returns an iterator to one past the last element.
4659
4660 @image html range-begin-end.svg "Illustration from cppreference.com"
4661
4662 @return iterator one past the last element
4663
4664 @complexity Constant.
4665
4666 @requirement This function helps `basic_json` satisfying the
4667 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
4668 requirements:
4669 - The complexity is constant.
4670
4671 @liveexample{The following code shows an example for `end()`.,end}
4672
4673 @sa see @ref cend() -- returns a const iterator to the end
4674 @sa see @ref begin() -- returns an iterator to the beginning
4675 @sa see @ref cbegin() -- returns a const iterator to the beginning
4676
4677 @since version 1.0.0
4678 */
end()4679 iterator end() noexcept
4680 {
4681 iterator result(this);
4682 result.set_end();
4683 return result;
4684 }
4685
4686 /*!
4687 @copydoc basic_json::cend()
4688 */
end() const4689 const_iterator end() const noexcept
4690 {
4691 return cend();
4692 }
4693
4694 /*!
4695 @brief returns a const iterator to one past the last element
4696
4697 Returns a const iterator to one past the last element.
4698
4699 @image html range-begin-end.svg "Illustration from cppreference.com"
4700
4701 @return const iterator one past the last element
4702
4703 @complexity Constant.
4704
4705 @requirement This function helps `basic_json` satisfying the
4706 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
4707 requirements:
4708 - The complexity is constant.
4709 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
4710
4711 @liveexample{The following code shows an example for `cend()`.,cend}
4712
4713 @sa see @ref end() -- returns an iterator to the end
4714 @sa see @ref begin() -- returns an iterator to the beginning
4715 @sa see @ref cbegin() -- returns a const iterator to the beginning
4716
4717 @since version 1.0.0
4718 */
cend() const4719 const_iterator cend() const noexcept
4720 {
4721 const_iterator result(this);
4722 result.set_end();
4723 return result;
4724 }
4725
4726 /*!
4727 @brief returns an iterator to the reverse-beginning
4728
4729 Returns an iterator to the reverse-beginning; that is, the last element.
4730
4731 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4732
4733 @complexity Constant.
4734
4735 @requirement This function helps `basic_json` satisfying the
4736 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
4737 requirements:
4738 - The complexity is constant.
4739 - Has the semantics of `reverse_iterator(end())`.
4740
4741 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
4742
4743 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
4744 @sa see @ref rend() -- returns a reverse iterator to the end
4745 @sa see @ref crend() -- returns a const reverse iterator to the end
4746
4747 @since version 1.0.0
4748 */
rbegin()4749 reverse_iterator rbegin() noexcept
4750 {
4751 return reverse_iterator(end());
4752 }
4753
4754 /*!
4755 @copydoc basic_json::crbegin()
4756 */
rbegin() const4757 const_reverse_iterator rbegin() const noexcept
4758 {
4759 return crbegin();
4760 }
4761
4762 /*!
4763 @brief returns an iterator to the reverse-end
4764
4765 Returns an iterator to the reverse-end; that is, one before the first
4766 element.
4767
4768 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4769
4770 @complexity Constant.
4771
4772 @requirement This function helps `basic_json` satisfying the
4773 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
4774 requirements:
4775 - The complexity is constant.
4776 - Has the semantics of `reverse_iterator(begin())`.
4777
4778 @liveexample{The following code shows an example for `rend()`.,rend}
4779
4780 @sa see @ref crend() -- returns a const reverse iterator to the end
4781 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
4782 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
4783
4784 @since version 1.0.0
4785 */
rend()4786 reverse_iterator rend() noexcept
4787 {
4788 return reverse_iterator(begin());
4789 }
4790
4791 /*!
4792 @copydoc basic_json::crend()
4793 */
rend() const4794 const_reverse_iterator rend() const noexcept
4795 {
4796 return crend();
4797 }
4798
4799 /*!
4800 @brief returns a const reverse iterator to the last element
4801
4802 Returns a const iterator to the reverse-beginning; that is, the last
4803 element.
4804
4805 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4806
4807 @complexity Constant.
4808
4809 @requirement This function helps `basic_json` satisfying the
4810 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
4811 requirements:
4812 - The complexity is constant.
4813 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
4814
4815 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
4816
4817 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
4818 @sa see @ref rend() -- returns a reverse iterator to the end
4819 @sa see @ref crend() -- returns a const reverse iterator to the end
4820
4821 @since version 1.0.0
4822 */
crbegin() const4823 const_reverse_iterator crbegin() const noexcept
4824 {
4825 return const_reverse_iterator(cend());
4826 }
4827
4828 /*!
4829 @brief returns a const reverse iterator to one before the first
4830
4831 Returns a const reverse iterator to the reverse-end; that is, one before
4832 the first element.
4833
4834 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4835
4836 @complexity Constant.
4837
4838 @requirement This function helps `basic_json` satisfying the
4839 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
4840 requirements:
4841 - The complexity is constant.
4842 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
4843
4844 @liveexample{The following code shows an example for `crend()`.,crend}
4845
4846 @sa see @ref rend() -- returns a reverse iterator to the end
4847 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
4848 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
4849
4850 @since version 1.0.0
4851 */
crend() const4852 const_reverse_iterator crend() const noexcept
4853 {
4854 return const_reverse_iterator(cbegin());
4855 }
4856
4857 public:
4858 /*!
4859 @brief wrapper to access iterator member functions in range-based for
4860
4861 This function allows to access @ref iterator::key() and @ref
4862 iterator::value() during range-based for loops. In these loops, a
4863 reference to the JSON values is returned, so there is no access to the
4864 underlying iterator.
4865
4866 For loop without iterator_wrapper:
4867
4868 @code{cpp}
4869 for (auto it = j_object.begin(); it != j_object.end(); ++it)
4870 {
4871 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
4872 }
4873 @endcode
4874
4875 Range-based for loop without iterator proxy:
4876
4877 @code{cpp}
4878 for (auto it : j_object)
4879 {
4880 // "it" is of type json::reference and has no key() member
4881 std::cout << "value: " << it << '\n';
4882 }
4883 @endcode
4884
4885 Range-based for loop with iterator proxy:
4886
4887 @code{cpp}
4888 for (auto it : json::iterator_wrapper(j_object))
4889 {
4890 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
4891 }
4892 @endcode
4893
4894 @note When iterating over an array, `key()` will return the index of the
4895 element as string (see example).
4896
4897 @param[in] ref reference to a JSON value
4898 @return iteration proxy object wrapping @a ref with an interface to use in
4899 range-based for loops
4900
4901 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
4902
4903 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4904 changes in the JSON value.
4905
4906 @complexity Constant.
4907
4908 @note The name of this function is not yet final and may change in the
4909 future.
4910
4911 @deprecated This stream operator is deprecated and will be removed in
4912 future 4.0.0 of the library. Please use @ref items() instead;
4913 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
4914 */
items()4915 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
4916 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
4917 {
4918 return ref.items();
4919 }
4920
4921 /*!
4922 @copydoc iterator_wrapper(reference)
4923 */
items()4924 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
4925 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
4926 {
4927 return ref.items();
4928 }
4929
4930 /*!
4931 @brief helper to access iterator member functions in range-based for
4932
4933 This function allows to access @ref iterator::key() and @ref
4934 iterator::value() during range-based for loops. In these loops, a
4935 reference to the JSON values is returned, so there is no access to the
4936 underlying iterator.
4937
4938 For loop without `items()` function:
4939
4940 @code{cpp}
4941 for (auto it = j_object.begin(); it != j_object.end(); ++it)
4942 {
4943 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
4944 }
4945 @endcode
4946
4947 Range-based for loop without `items()` function:
4948
4949 @code{cpp}
4950 for (auto it : j_object)
4951 {
4952 // "it" is of type json::reference and has no key() member
4953 std::cout << "value: " << it << '\n';
4954 }
4955 @endcode
4956
4957 Range-based for loop with `items()` function:
4958
4959 @code{cpp}
4960 for (auto& el : j_object.items())
4961 {
4962 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
4963 }
4964 @endcode
4965
4966 The `items()` function also allows to use
4967 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
4968 (C++17):
4969
4970 @code{cpp}
4971 for (auto& [key, val] : j_object.items())
4972 {
4973 std::cout << "key: " << key << ", value:" << val << '\n';
4974 }
4975 @endcode
4976
4977 @note When iterating over an array, `key()` will return the index of the
4978 element as string (see example). For primitive types (e.g., numbers),
4979 `key()` returns an empty string.
4980
4981 @warning Using `items()` on temporary objects is dangerous. Make sure the
4982 object's lifetime exeeds the iteration. See
4983 <https://github.com/nlohmann/json/issues/2040> for more
4984 information.
4985
4986 @return iteration proxy object wrapping @a ref with an interface to use in
4987 range-based for loops
4988
4989 @liveexample{The following code shows how the function is used.,items}
4990
4991 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4992 changes in the JSON value.
4993
4994 @complexity Constant.
4995
4996 @since version 3.1.0, structured bindings support since 3.5.0.
4997 */
items()4998 iteration_proxy<iterator> items() noexcept
4999 {
5000 return iteration_proxy<iterator>(*this);
5001 }
5002
5003 /*!
5004 @copydoc items()
5005 */
items() const5006 iteration_proxy<const_iterator> items() const noexcept
5007 {
5008 return iteration_proxy<const_iterator>(*this);
5009 }
5010
5011 /// @}
5012
5013
5014 //////////////
5015 // capacity //
5016 //////////////
5017
5018 /// @name capacity
5019 /// @{
5020
5021 /*!
5022 @brief checks whether the container is empty.
5023
5024 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
5025
5026 @return The return value depends on the different types and is
5027 defined as follows:
5028 Value type | return value
5029 ----------- | -------------
5030 null | `true`
5031 boolean | `false`
5032 string | `false`
5033 number | `false`
5034 binary | `false`
5035 object | result of function `object_t::empty()`
5036 array | result of function `array_t::empty()`
5037
5038 @liveexample{The following code uses `empty()` to check if a JSON
5039 object contains any elements.,empty}
5040
5041 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5042 the Container concept; that is, their `empty()` functions have constant
5043 complexity.
5044
5045 @iterators No changes.
5046
5047 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5048
5049 @note This function does not return whether a string stored as JSON value
5050 is empty - it returns whether the JSON container itself is empty which is
5051 false in the case of a string.
5052
5053 @requirement This function helps `basic_json` satisfying the
5054 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
5055 requirements:
5056 - The complexity is constant.
5057 - Has the semantics of `begin() == end()`.
5058
5059 @sa see @ref size() -- returns the number of elements
5060
5061 @since version 1.0.0
5062 */
empty() const5063 bool empty() const noexcept
5064 {
5065 switch (m_type)
5066 {
5067 case value_t::null:
5068 {
5069 // null values are empty
5070 return true;
5071 }
5072
5073 case value_t::array:
5074 {
5075 // delegate call to array_t::empty()
5076 return m_value.array->empty();
5077 }
5078
5079 case value_t::object:
5080 {
5081 // delegate call to object_t::empty()
5082 return m_value.object->empty();
5083 }
5084
5085 default:
5086 {
5087 // all other types are nonempty
5088 return false;
5089 }
5090 }
5091 }
5092
5093 /*!
5094 @brief returns the number of elements
5095
5096 Returns the number of elements in a JSON value.
5097
5098 @return The return value depends on the different types and is
5099 defined as follows:
5100 Value type | return value
5101 ----------- | -------------
5102 null | `0`
5103 boolean | `1`
5104 string | `1`
5105 number | `1`
5106 binary | `1`
5107 object | result of function object_t::size()
5108 array | result of function array_t::size()
5109
5110 @liveexample{The following code calls `size()` on the different value
5111 types.,size}
5112
5113 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5114 the Container concept; that is, their size() functions have constant
5115 complexity.
5116
5117 @iterators No changes.
5118
5119 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5120
5121 @note This function does not return the length of a string stored as JSON
5122 value - it returns the number of elements in the JSON value which is 1 in
5123 the case of a string.
5124
5125 @requirement This function helps `basic_json` satisfying the
5126 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
5127 requirements:
5128 - The complexity is constant.
5129 - Has the semantics of `std::distance(begin(), end())`.
5130
5131 @sa see @ref empty() -- checks whether the container is empty
5132 @sa see @ref max_size() -- returns the maximal number of elements
5133
5134 @since version 1.0.0
5135 */
size() const5136 size_type size() const noexcept
5137 {
5138 switch (m_type)
5139 {
5140 case value_t::null:
5141 {
5142 // null values are empty
5143 return 0;
5144 }
5145
5146 case value_t::array:
5147 {
5148 // delegate call to array_t::size()
5149 return m_value.array->size();
5150 }
5151
5152 case value_t::object:
5153 {
5154 // delegate call to object_t::size()
5155 return m_value.object->size();
5156 }
5157
5158 default:
5159 {
5160 // all other types have size 1
5161 return 1;
5162 }
5163 }
5164 }
5165
5166 /*!
5167 @brief returns the maximum possible number of elements
5168
5169 Returns the maximum number of elements a JSON value is able to hold due to
5170 system or library implementation limitations, i.e. `std::distance(begin(),
5171 end())` for the JSON value.
5172
5173 @return The return value depends on the different types and is
5174 defined as follows:
5175 Value type | return value
5176 ----------- | -------------
5177 null | `0` (same as `size()`)
5178 boolean | `1` (same as `size()`)
5179 string | `1` (same as `size()`)
5180 number | `1` (same as `size()`)
5181 binary | `1` (same as `size()`)
5182 object | result of function `object_t::max_size()`
5183 array | result of function `array_t::max_size()`
5184
5185 @liveexample{The following code calls `max_size()` on the different value
5186 types. Note the output is implementation specific.,max_size}
5187
5188 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5189 the Container concept; that is, their `max_size()` functions have constant
5190 complexity.
5191
5192 @iterators No changes.
5193
5194 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5195
5196 @requirement This function helps `basic_json` satisfying the
5197 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
5198 requirements:
5199 - The complexity is constant.
5200 - Has the semantics of returning `b.size()` where `b` is the largest
5201 possible JSON value.
5202
5203 @sa see @ref size() -- returns the number of elements
5204
5205 @since version 1.0.0
5206 */
max_size() const5207 size_type max_size() const noexcept
5208 {
5209 switch (m_type)
5210 {
5211 case value_t::array:
5212 {
5213 // delegate call to array_t::max_size()
5214 return m_value.array->max_size();
5215 }
5216
5217 case value_t::object:
5218 {
5219 // delegate call to object_t::max_size()
5220 return m_value.object->max_size();
5221 }
5222
5223 default:
5224 {
5225 // all other types have max_size() == size()
5226 return size();
5227 }
5228 }
5229 }
5230
5231 /// @}
5232
5233
5234 ///////////////
5235 // modifiers //
5236 ///////////////
5237
5238 /// @name modifiers
5239 /// @{
5240
5241 /*!
5242 @brief clears the contents
5243
5244 Clears the content of a JSON value and resets it to the default value as
5245 if @ref basic_json(value_t) would have been called with the current value
5246 type from @ref type():
5247
5248 Value type | initial value
5249 ----------- | -------------
5250 null | `null`
5251 boolean | `false`
5252 string | `""`
5253 number | `0`
5254 binary | An empty byte vector
5255 object | `{}`
5256 array | `[]`
5257
5258 @post Has the same effect as calling
5259 @code {.cpp}
5260 *this = basic_json(type());
5261 @endcode
5262
5263 @liveexample{The example below shows the effect of `clear()` to different
5264 JSON types.,clear}
5265
5266 @complexity Linear in the size of the JSON value.
5267
5268 @iterators All iterators, pointers and references related to this container
5269 are invalidated.
5270
5271 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5272
5273 @sa see @ref basic_json(value_t) -- constructor that creates an object with the
5274 same value than calling `clear()`
5275
5276 @since version 1.0.0
5277 */
clear()5278 void clear() noexcept
5279 {
5280 switch (m_type)
5281 {
5282 case value_t::number_integer:
5283 {
5284 m_value.number_integer = 0;
5285 break;
5286 }
5287
5288 case value_t::number_unsigned:
5289 {
5290 m_value.number_unsigned = 0;
5291 break;
5292 }
5293
5294 case value_t::number_float:
5295 {
5296 m_value.number_float = 0.0;
5297 break;
5298 }
5299
5300 case value_t::boolean:
5301 {
5302 m_value.boolean = false;
5303 break;
5304 }
5305
5306 case value_t::string:
5307 {
5308 m_value.string->clear();
5309 break;
5310 }
5311
5312 case value_t::binary:
5313 {
5314 m_value.binary->clear();
5315 break;
5316 }
5317
5318 case value_t::array:
5319 {
5320 m_value.array->clear();
5321 break;
5322 }
5323
5324 case value_t::object:
5325 {
5326 m_value.object->clear();
5327 break;
5328 }
5329
5330 default:
5331 break;
5332 }
5333 }
5334
5335 /*!
5336 @brief add an object to an array
5337
5338 Appends the given element @a val to the end of the JSON value. If the
5339 function is called on a JSON null value, an empty array is created before
5340 appending @a val.
5341
5342 @param[in] val the value to add to the JSON array
5343
5344 @throw type_error.308 when called on a type other than JSON array or
5345 null; example: `"cannot use push_back() with number"`
5346
5347 @complexity Amortized constant.
5348
5349 @liveexample{The example shows how `push_back()` and `+=` can be used to
5350 add elements to a JSON array. Note how the `null` value was silently
5351 converted to a JSON array.,push_back}
5352
5353 @since version 1.0.0
5354 */
push_back(basic_json && val)5355 void push_back(basic_json&& val)
5356 {
5357 // push_back only works for null objects or arrays
5358 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5359 {
5360 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
5361 }
5362
5363 // transform null object into an array
5364 if (is_null())
5365 {
5366 m_type = value_t::array;
5367 m_value = value_t::array;
5368 assert_invariant();
5369 }
5370
5371 // add element to array (move semantics)
5372 m_value.array->push_back(std::move(val));
5373 set_parent(m_value.array->back());
5374 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
5375 }
5376
5377 /*!
5378 @brief add an object to an array
5379 @copydoc push_back(basic_json&&)
5380 */
operator +=(basic_json && val)5381 reference operator+=(basic_json&& val)
5382 {
5383 push_back(std::move(val));
5384 return *this;
5385 }
5386
5387 /*!
5388 @brief add an object to an array
5389 @copydoc push_back(basic_json&&)
5390 */
push_back(const basic_json & val)5391 void push_back(const basic_json& val)
5392 {
5393 // push_back only works for null objects or arrays
5394 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5395 {
5396 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
5397 }
5398
5399 // transform null object into an array
5400 if (is_null())
5401 {
5402 m_type = value_t::array;
5403 m_value = value_t::array;
5404 assert_invariant();
5405 }
5406
5407 // add element to array
5408 m_value.array->push_back(val);
5409 set_parent(m_value.array->back());
5410 }
5411
5412 /*!
5413 @brief add an object to an array
5414 @copydoc push_back(basic_json&&)
5415 */
operator +=(const basic_json & val)5416 reference operator+=(const basic_json& val)
5417 {
5418 push_back(val);
5419 return *this;
5420 }
5421
5422 /*!
5423 @brief add an object to an object
5424
5425 Inserts the given element @a val to the JSON object. If the function is
5426 called on a JSON null value, an empty object is created before inserting
5427 @a val.
5428
5429 @param[in] val the value to add to the JSON object
5430
5431 @throw type_error.308 when called on a type other than JSON object or
5432 null; example: `"cannot use push_back() with number"`
5433
5434 @complexity Logarithmic in the size of the container, O(log(`size()`)).
5435
5436 @liveexample{The example shows how `push_back()` and `+=` can be used to
5437 add elements to a JSON object. Note how the `null` value was silently
5438 converted to a JSON object.,push_back__object_t__value}
5439
5440 @since version 1.0.0
5441 */
push_back(const typename object_t::value_type & val)5442 void push_back(const typename object_t::value_type& val)
5443 {
5444 // push_back only works for null objects or objects
5445 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
5446 {
5447 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
5448 }
5449
5450 // transform null object into an object
5451 if (is_null())
5452 {
5453 m_type = value_t::object;
5454 m_value = value_t::object;
5455 assert_invariant();
5456 }
5457
5458 // add element to object
5459 auto res = m_value.object->insert(val);
5460 set_parent(res.first->second);
5461 }
5462
5463 /*!
5464 @brief add an object to an object
5465 @copydoc push_back(const typename object_t::value_type&)
5466 */
operator +=(const typename object_t::value_type & val)5467 reference operator+=(const typename object_t::value_type& val)
5468 {
5469 push_back(val);
5470 return *this;
5471 }
5472
5473 /*!
5474 @brief add an object to an object
5475
5476 This function allows to use `push_back` with an initializer list. In case
5477
5478 1. the current value is an object,
5479 2. the initializer list @a init contains only two elements, and
5480 3. the first element of @a init is a string,
5481
5482 @a init is converted into an object element and added using
5483 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
5484 is converted to a JSON value and added using @ref push_back(basic_json&&).
5485
5486 @param[in] init an initializer list
5487
5488 @complexity Linear in the size of the initializer list @a init.
5489
5490 @note This function is required to resolve an ambiguous overload error,
5491 because pairs like `{"key", "value"}` can be both interpreted as
5492 `object_t::value_type` or `std::initializer_list<basic_json>`, see
5493 https://github.com/nlohmann/json/issues/235 for more information.
5494
5495 @liveexample{The example shows how initializer lists are treated as
5496 objects when possible.,push_back__initializer_list}
5497 */
push_back(initializer_list_t init)5498 void push_back(initializer_list_t init)
5499 {
5500 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
5501 {
5502 basic_json&& key = init.begin()->moved_or_copied();
5503 push_back(typename object_t::value_type(
5504 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
5505 }
5506 else
5507 {
5508 push_back(basic_json(init));
5509 }
5510 }
5511
5512 /*!
5513 @brief add an object to an object
5514 @copydoc push_back(initializer_list_t)
5515 */
operator +=(initializer_list_t init)5516 reference operator+=(initializer_list_t init)
5517 {
5518 push_back(init);
5519 return *this;
5520 }
5521
5522 /*!
5523 @brief add an object to an array
5524
5525 Creates a JSON value from the passed parameters @a args to the end of the
5526 JSON value. If the function is called on a JSON null value, an empty array
5527 is created before appending the value created from @a args.
5528
5529 @param[in] args arguments to forward to a constructor of @ref basic_json
5530 @tparam Args compatible types to create a @ref basic_json object
5531
5532 @return reference to the inserted element
5533
5534 @throw type_error.311 when called on a type other than JSON array or
5535 null; example: `"cannot use emplace_back() with number"`
5536
5537 @complexity Amortized constant.
5538
5539 @liveexample{The example shows how `push_back()` can be used to add
5540 elements to a JSON array. Note how the `null` value was silently converted
5541 to a JSON array.,emplace_back}
5542
5543 @since version 2.0.8, returns reference since 3.7.0
5544 */
5545 template<class... Args>
emplace_back(Args &&...args)5546 reference emplace_back(Args&& ... args)
5547 {
5548 // emplace_back only works for null objects or arrays
5549 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
5550 {
5551 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
5552 }
5553
5554 // transform null object into an array
5555 if (is_null())
5556 {
5557 m_type = value_t::array;
5558 m_value = value_t::array;
5559 assert_invariant();
5560 }
5561
5562 // add element to array (perfect forwarding)
5563 #ifdef JSON_HAS_CPP_17
5564 return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
5565 #else
5566 m_value.array->emplace_back(std::forward<Args>(args)...);
5567 return set_parent(m_value.array->back());
5568 #endif
5569 }
5570
5571 /*!
5572 @brief add an object to an object if key does not exist
5573
5574 Inserts a new element into a JSON object constructed in-place with the
5575 given @a args if there is no element with the key in the container. If the
5576 function is called on a JSON null value, an empty object is created before
5577 appending the value created from @a args.
5578
5579 @param[in] args arguments to forward to a constructor of @ref basic_json
5580 @tparam Args compatible types to create a @ref basic_json object
5581
5582 @return a pair consisting of an iterator to the inserted element, or the
5583 already-existing element if no insertion happened, and a bool
5584 denoting whether the insertion took place.
5585
5586 @throw type_error.311 when called on a type other than JSON object or
5587 null; example: `"cannot use emplace() with number"`
5588
5589 @complexity Logarithmic in the size of the container, O(log(`size()`)).
5590
5591 @liveexample{The example shows how `emplace()` can be used to add elements
5592 to a JSON object. Note how the `null` value was silently converted to a
5593 JSON object. Further note how no value is added if there was already one
5594 value stored with the same key.,emplace}
5595
5596 @since version 2.0.8
5597 */
5598 template<class... Args>
emplace(Args &&...args)5599 std::pair<iterator, bool> emplace(Args&& ... args)
5600 {
5601 // emplace only works for null objects or arrays
5602 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
5603 {
5604 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
5605 }
5606
5607 // transform null object into an object
5608 if (is_null())
5609 {
5610 m_type = value_t::object;
5611 m_value = value_t::object;
5612 assert_invariant();
5613 }
5614
5615 // add element to array (perfect forwarding)
5616 auto res = m_value.object->emplace(std::forward<Args>(args)...);
5617 set_parent(res.first->second);
5618
5619 // create result iterator and set iterator to the result of emplace
5620 auto it = begin();
5621 it.m_it.object_iterator = res.first;
5622
5623 // return pair of iterator and boolean
5624 return {it, res.second};
5625 }
5626
5627 /// Helper for insertion of an iterator
5628 /// @note: This uses std::distance to support GCC 4.8,
5629 /// see https://github.com/nlohmann/json/pull/1257
5630 template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)5631 iterator insert_iterator(const_iterator pos, Args&& ... args)
5632 {
5633 iterator result(this);
5634 JSON_ASSERT(m_value.array != nullptr);
5635
5636 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
5637 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
5638 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
5639
5640 // This could have been written as:
5641 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5642 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
5643
5644 return result;
5645 }
5646
5647 /*!
5648 @brief inserts element
5649
5650 Inserts element @a val before iterator @a pos.
5651
5652 @param[in] pos iterator before which the content will be inserted; may be
5653 the end() iterator
5654 @param[in] val element to insert
5655 @return iterator pointing to the inserted @a val.
5656
5657 @throw type_error.309 if called on JSON values other than arrays;
5658 example: `"cannot use insert() with string"`
5659 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
5660 example: `"iterator does not fit current value"`
5661
5662 @complexity Constant plus linear in the distance between @a pos and end of
5663 the container.
5664
5665 @liveexample{The example shows how `insert()` is used.,insert}
5666
5667 @since version 1.0.0
5668 */
insert(const_iterator pos,const basic_json & val)5669 iterator insert(const_iterator pos, const basic_json& val)
5670 {
5671 // insert only works for arrays
5672 if (JSON_HEDLEY_LIKELY(is_array()))
5673 {
5674 // check if iterator pos fits to this JSON value
5675 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5676 {
5677 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
5678 }
5679
5680 // insert to array and return iterator
5681 return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
5682 }
5683
5684 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
5685 }
5686
5687 /*!
5688 @brief inserts element
5689 @copydoc insert(const_iterator, const basic_json&)
5690 */
insert(const_iterator pos,basic_json && val)5691 iterator insert(const_iterator pos, basic_json&& val)
5692 {
5693 return insert(pos, val);
5694 }
5695
5696 /*!
5697 @brief inserts elements
5698
5699 Inserts @a cnt copies of @a val before iterator @a pos.
5700
5701 @param[in] pos iterator before which the content will be inserted; may be
5702 the end() iterator
5703 @param[in] cnt number of copies of @a val to insert
5704 @param[in] val element to insert
5705 @return iterator pointing to the first element inserted, or @a pos if
5706 `cnt==0`
5707
5708 @throw type_error.309 if called on JSON values other than arrays; example:
5709 `"cannot use insert() with string"`
5710 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
5711 example: `"iterator does not fit current value"`
5712
5713 @complexity Linear in @a cnt plus linear in the distance between @a pos
5714 and end of the container.
5715
5716 @liveexample{The example shows how `insert()` is used.,insert__count}
5717
5718 @since version 1.0.0
5719 */
insert(const_iterator pos,size_type cnt,const basic_json & val)5720 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
5721 {
5722 // insert only works for arrays
5723 if (JSON_HEDLEY_LIKELY(is_array()))
5724 {
5725 // check if iterator pos fits to this JSON value
5726 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5727 {
5728 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
5729 }
5730
5731 // insert to array and return iterator
5732 return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
5733 }
5734
5735 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
5736 }
5737
5738 /*!
5739 @brief inserts elements
5740
5741 Inserts elements from range `[first, last)` before iterator @a pos.
5742
5743 @param[in] pos iterator before which the content will be inserted; may be
5744 the end() iterator
5745 @param[in] first begin of the range of elements to insert
5746 @param[in] last end of the range of elements to insert
5747
5748 @throw type_error.309 if called on JSON values other than arrays; example:
5749 `"cannot use insert() with string"`
5750 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
5751 example: `"iterator does not fit current value"`
5752 @throw invalid_iterator.210 if @a first and @a last do not belong to the
5753 same JSON value; example: `"iterators do not fit"`
5754 @throw invalid_iterator.211 if @a first or @a last are iterators into
5755 container for which insert is called; example: `"passed iterators may not
5756 belong to container"`
5757
5758 @return iterator pointing to the first element inserted, or @a pos if
5759 `first==last`
5760
5761 @complexity Linear in `std::distance(first, last)` plus linear in the
5762 distance between @a pos and end of the container.
5763
5764 @liveexample{The example shows how `insert()` is used.,insert__range}
5765
5766 @since version 1.0.0
5767 */
insert(const_iterator pos,const_iterator first,const_iterator last)5768 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
5769 {
5770 // insert only works for arrays
5771 if (JSON_HEDLEY_UNLIKELY(!is_array()))
5772 {
5773 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
5774 }
5775
5776 // check if iterator pos fits to this JSON value
5777 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5778 {
5779 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
5780 }
5781
5782 // check if range iterators belong to the same JSON object
5783 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5784 {
5785 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
5786 }
5787
5788 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
5789 {
5790 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
5791 }
5792
5793 // insert to array and return iterator
5794 return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
5795 }
5796
5797 /*!
5798 @brief inserts elements
5799
5800 Inserts elements from initializer list @a ilist before iterator @a pos.
5801
5802 @param[in] pos iterator before which the content will be inserted; may be
5803 the end() iterator
5804 @param[in] ilist initializer list to insert the values from
5805
5806 @throw type_error.309 if called on JSON values other than arrays; example:
5807 `"cannot use insert() with string"`
5808 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
5809 example: `"iterator does not fit current value"`
5810
5811 @return iterator pointing to the first element inserted, or @a pos if
5812 `ilist` is empty
5813
5814 @complexity Linear in `ilist.size()` plus linear in the distance between
5815 @a pos and end of the container.
5816
5817 @liveexample{The example shows how `insert()` is used.,insert__ilist}
5818
5819 @since version 1.0.0
5820 */
insert(const_iterator pos,initializer_list_t ilist)5821 iterator insert(const_iterator pos, initializer_list_t ilist)
5822 {
5823 // insert only works for arrays
5824 if (JSON_HEDLEY_UNLIKELY(!is_array()))
5825 {
5826 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
5827 }
5828
5829 // check if iterator pos fits to this JSON value
5830 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
5831 {
5832 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
5833 }
5834
5835 // insert to array and return iterator
5836 return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
5837 }
5838
5839 /*!
5840 @brief inserts elements
5841
5842 Inserts elements from range `[first, last)`.
5843
5844 @param[in] first begin of the range of elements to insert
5845 @param[in] last end of the range of elements to insert
5846
5847 @throw type_error.309 if called on JSON values other than objects; example:
5848 `"cannot use insert() with string"`
5849 @throw invalid_iterator.202 if iterator @a first or @a last does does not
5850 point to an object; example: `"iterators first and last must point to
5851 objects"`
5852 @throw invalid_iterator.210 if @a first and @a last do not belong to the
5853 same JSON value; example: `"iterators do not fit"`
5854
5855 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
5856 of elements to insert.
5857
5858 @liveexample{The example shows how `insert()` is used.,insert__range_object}
5859
5860 @since version 3.0.0
5861 */
insert(const_iterator first,const_iterator last)5862 void insert(const_iterator first, const_iterator last)
5863 {
5864 // insert only works for objects
5865 if (JSON_HEDLEY_UNLIKELY(!is_object()))
5866 {
5867 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
5868 }
5869
5870 // check if range iterators belong to the same JSON object
5871 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5872 {
5873 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
5874 }
5875
5876 // passed iterators must belong to objects
5877 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
5878 {
5879 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
5880 }
5881
5882 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
5883 }
5884
5885 /*!
5886 @brief updates a JSON object from another object, overwriting existing keys
5887
5888 Inserts all values from JSON object @a j and overwrites existing keys.
5889
5890 @param[in] j JSON object to read values from
5891
5892 @throw type_error.312 if called on JSON values other than objects; example:
5893 `"cannot use update() with string"`
5894
5895 @complexity O(N*log(size() + N)), where N is the number of elements to
5896 insert.
5897
5898 @liveexample{The example shows how `update()` is used.,update}
5899
5900 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
5901
5902 @since version 3.0.0
5903 */
update(const_reference j)5904 void update(const_reference j)
5905 {
5906 // implicitly convert null value to an empty object
5907 if (is_null())
5908 {
5909 m_type = value_t::object;
5910 m_value.object = create<object_t>();
5911 assert_invariant();
5912 }
5913
5914 if (JSON_HEDLEY_UNLIKELY(!is_object()))
5915 {
5916 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
5917 }
5918 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
5919 {
5920 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
5921 }
5922
5923 for (auto it = j.cbegin(); it != j.cend(); ++it)
5924 {
5925 m_value.object->operator[](it.key()) = it.value();
5926 }
5927 }
5928
5929 /*!
5930 @brief updates a JSON object from another object, overwriting existing keys
5931
5932 Inserts all values from from range `[first, last)` and overwrites existing
5933 keys.
5934
5935 @param[in] first begin of the range of elements to insert
5936 @param[in] last end of the range of elements to insert
5937
5938 @throw type_error.312 if called on JSON values other than objects; example:
5939 `"cannot use update() with string"`
5940 @throw invalid_iterator.202 if iterator @a first or @a last does does not
5941 point to an object; example: `"iterators first and last must point to
5942 objects"`
5943 @throw invalid_iterator.210 if @a first and @a last do not belong to the
5944 same JSON value; example: `"iterators do not fit"`
5945
5946 @complexity O(N*log(size() + N)), where N is the number of elements to
5947 insert.
5948
5949 @liveexample{The example shows how `update()` is used__range.,update}
5950
5951 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
5952
5953 @since version 3.0.0
5954 */
update(const_iterator first,const_iterator last)5955 void update(const_iterator first, const_iterator last)
5956 {
5957 // implicitly convert null value to an empty object
5958 if (is_null())
5959 {
5960 m_type = value_t::object;
5961 m_value.object = create<object_t>();
5962 assert_invariant();
5963 }
5964
5965 if (JSON_HEDLEY_UNLIKELY(!is_object()))
5966 {
5967 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
5968 }
5969
5970 // check if range iterators belong to the same JSON object
5971 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
5972 {
5973 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
5974 }
5975
5976 // passed iterators must belong to objects
5977 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
5978 || !last.m_object->is_object()))
5979 {
5980 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
5981 }
5982
5983 for (auto it = first; it != last; ++it)
5984 {
5985 m_value.object->operator[](it.key()) = it.value();
5986 }
5987 }
5988
5989 /*!
5990 @brief exchanges the values
5991
5992 Exchanges the contents of the JSON value with those of @a other. Does not
5993 invoke any move, copy, or swap operations on individual elements. All
5994 iterators and references remain valid. The past-the-end iterator is
5995 invalidated.
5996
5997 @param[in,out] other JSON value to exchange the contents with
5998
5999 @complexity Constant.
6000
6001 @liveexample{The example below shows how JSON values can be swapped with
6002 `swap()`.,swap__reference}
6003
6004 @since version 1.0.0
6005 */
swap(reference other)6006 void swap(reference other) noexcept (
6007 std::is_nothrow_move_constructible<value_t>::value&&
6008 std::is_nothrow_move_assignable<value_t>::value&&
6009 std::is_nothrow_move_constructible<json_value>::value&&
6010 std::is_nothrow_move_assignable<json_value>::value
6011 )
6012 {
6013 std::swap(m_type, other.m_type);
6014 std::swap(m_value, other.m_value);
6015
6016 set_parents();
6017 other.set_parents();
6018 assert_invariant();
6019 }
6020
6021 /*!
6022 @brief exchanges the values
6023
6024 Exchanges the contents of the JSON value from @a left with those of @a right. Does not
6025 invoke any move, copy, or swap operations on individual elements. All
6026 iterators and references remain valid. The past-the-end iterator is
6027 invalidated. implemented as a friend function callable via ADL.
6028
6029 @param[in,out] left JSON value to exchange the contents with
6030 @param[in,out] right JSON value to exchange the contents with
6031
6032 @complexity Constant.
6033
6034 @liveexample{The example below shows how JSON values can be swapped with
6035 `swap()`.,swap__reference}
6036
6037 @since version 1.0.0
6038 */
swap(reference left,reference right)6039 friend void swap(reference left, reference right) noexcept (
6040 std::is_nothrow_move_constructible<value_t>::value&&
6041 std::is_nothrow_move_assignable<value_t>::value&&
6042 std::is_nothrow_move_constructible<json_value>::value&&
6043 std::is_nothrow_move_assignable<json_value>::value
6044 )
6045 {
6046 left.swap(right);
6047 }
6048
6049 /*!
6050 @brief exchanges the values
6051
6052 Exchanges the contents of a JSON array with those of @a other. Does not
6053 invoke any move, copy, or swap operations on individual elements. All
6054 iterators and references remain valid. The past-the-end iterator is
6055 invalidated.
6056
6057 @param[in,out] other array to exchange the contents with
6058
6059 @throw type_error.310 when JSON value is not an array; example: `"cannot
6060 use swap() with string"`
6061
6062 @complexity Constant.
6063
6064 @liveexample{The example below shows how arrays can be swapped with
6065 `swap()`.,swap__array_t}
6066
6067 @since version 1.0.0
6068 */
swap(array_t & other)6069 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
6070 {
6071 // swap only works for arrays
6072 if (JSON_HEDLEY_LIKELY(is_array()))
6073 {
6074 std::swap(*(m_value.array), other);
6075 }
6076 else
6077 {
6078 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
6079 }
6080 }
6081
6082 /*!
6083 @brief exchanges the values
6084
6085 Exchanges the contents of a JSON object with those of @a other. Does not
6086 invoke any move, copy, or swap operations on individual elements. All
6087 iterators and references remain valid. The past-the-end iterator is
6088 invalidated.
6089
6090 @param[in,out] other object to exchange the contents with
6091
6092 @throw type_error.310 when JSON value is not an object; example:
6093 `"cannot use swap() with string"`
6094
6095 @complexity Constant.
6096
6097 @liveexample{The example below shows how objects can be swapped with
6098 `swap()`.,swap__object_t}
6099
6100 @since version 1.0.0
6101 */
swap(object_t & other)6102 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
6103 {
6104 // swap only works for objects
6105 if (JSON_HEDLEY_LIKELY(is_object()))
6106 {
6107 std::swap(*(m_value.object), other);
6108 }
6109 else
6110 {
6111 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
6112 }
6113 }
6114
6115 /*!
6116 @brief exchanges the values
6117
6118 Exchanges the contents of a JSON string with those of @a other. Does not
6119 invoke any move, copy, or swap operations on individual elements. All
6120 iterators and references remain valid. The past-the-end iterator is
6121 invalidated.
6122
6123 @param[in,out] other string to exchange the contents with
6124
6125 @throw type_error.310 when JSON value is not a string; example: `"cannot
6126 use swap() with boolean"`
6127
6128 @complexity Constant.
6129
6130 @liveexample{The example below shows how strings can be swapped with
6131 `swap()`.,swap__string_t}
6132
6133 @since version 1.0.0
6134 */
swap(string_t & other)6135 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
6136 {
6137 // swap only works for strings
6138 if (JSON_HEDLEY_LIKELY(is_string()))
6139 {
6140 std::swap(*(m_value.string), other);
6141 }
6142 else
6143 {
6144 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
6145 }
6146 }
6147
6148 /*!
6149 @brief exchanges the values
6150
6151 Exchanges the contents of a JSON string with those of @a other. Does not
6152 invoke any move, copy, or swap operations on individual elements. All
6153 iterators and references remain valid. The past-the-end iterator is
6154 invalidated.
6155
6156 @param[in,out] other binary to exchange the contents with
6157
6158 @throw type_error.310 when JSON value is not a string; example: `"cannot
6159 use swap() with boolean"`
6160
6161 @complexity Constant.
6162
6163 @liveexample{The example below shows how strings can be swapped with
6164 `swap()`.,swap__binary_t}
6165
6166 @since version 3.8.0
6167 */
swap(binary_t & other)6168 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
6169 {
6170 // swap only works for strings
6171 if (JSON_HEDLEY_LIKELY(is_binary()))
6172 {
6173 std::swap(*(m_value.binary), other);
6174 }
6175 else
6176 {
6177 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
6178 }
6179 }
6180
6181 /// @copydoc swap(binary_t&)
swap(typename binary_t::container_type & other)6182 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
6183 {
6184 // swap only works for strings
6185 if (JSON_HEDLEY_LIKELY(is_binary()))
6186 {
6187 std::swap(*(m_value.binary), other);
6188 }
6189 else
6190 {
6191 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
6192 }
6193 }
6194
6195 /// @}
6196
6197 public:
6198 //////////////////////////////////////////
6199 // lexicographical comparison operators //
6200 //////////////////////////////////////////
6201
6202 /// @name lexicographical comparison operators
6203 /// @{
6204
6205 /*!
6206 @brief comparison: equal
6207
6208 Compares two JSON values for equality according to the following rules:
6209 - Two JSON values are equal if (1) they are from the same type and (2)
6210 their stored values are the same according to their respective
6211 `operator==`.
6212 - Integer and floating-point numbers are automatically converted before
6213 comparison. Note that two NaN values are always treated as unequal.
6214 - Two JSON null values are equal.
6215
6216 @note Floating-point inside JSON values numbers are compared with
6217 `json::number_float_t::operator==` which is `double::operator==` by
6218 default. To compare floating-point while respecting an epsilon, an alternative
6219 [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
6220 could be used, for instance
6221 @code {.cpp}
6222 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
6223 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
6224 {
6225 return std::abs(a - b) <= epsilon;
6226 }
6227 @endcode
6228 Or you can self-defined operator equal function like this:
6229 @code {.cpp}
6230 bool my_equal(const_reference lhs, const_reference rhs) {
6231 const auto lhs_type lhs.type();
6232 const auto rhs_type rhs.type();
6233 if (lhs_type == rhs_type) {
6234 switch(lhs_type)
6235 // self_defined case
6236 case value_t::number_float:
6237 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
6238 // other cases remain the same with the original
6239 ...
6240 }
6241 ...
6242 }
6243 @endcode
6244
6245 @note NaN values never compare equal to themselves or to other NaN values.
6246
6247 @param[in] lhs first JSON value to consider
6248 @param[in] rhs second JSON value to consider
6249 @return whether the values @a lhs and @a rhs are equal
6250
6251 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6252
6253 @complexity Linear.
6254
6255 @liveexample{The example demonstrates comparing several JSON
6256 types.,operator__equal}
6257
6258 @since version 1.0.0
6259 */
operator ==(const_reference lhs,const_reference rhs)6260 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
6261 {
6262 const auto lhs_type = lhs.type();
6263 const auto rhs_type = rhs.type();
6264
6265 if (lhs_type == rhs_type)
6266 {
6267 switch (lhs_type)
6268 {
6269 case value_t::array:
6270 return *lhs.m_value.array == *rhs.m_value.array;
6271
6272 case value_t::object:
6273 return *lhs.m_value.object == *rhs.m_value.object;
6274
6275 case value_t::null:
6276 return true;
6277
6278 case value_t::string:
6279 return *lhs.m_value.string == *rhs.m_value.string;
6280
6281 case value_t::boolean:
6282 return lhs.m_value.boolean == rhs.m_value.boolean;
6283
6284 case value_t::number_integer:
6285 return lhs.m_value.number_integer == rhs.m_value.number_integer;
6286
6287 case value_t::number_unsigned:
6288 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
6289
6290 case value_t::number_float:
6291 return lhs.m_value.number_float == rhs.m_value.number_float;
6292
6293 case value_t::binary:
6294 return *lhs.m_value.binary == *rhs.m_value.binary;
6295
6296 default:
6297 return false;
6298 }
6299 }
6300 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
6301 {
6302 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
6303 }
6304 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
6305 {
6306 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
6307 }
6308 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
6309 {
6310 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
6311 }
6312 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
6313 {
6314 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
6315 }
6316 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
6317 {
6318 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
6319 }
6320 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
6321 {
6322 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6323 }
6324
6325 return false;
6326 }
6327
6328 /*!
6329 @brief comparison: equal
6330 @copydoc operator==(const_reference, const_reference)
6331 */
6332 template<typename ScalarType, typename std::enable_if<
6333 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,ScalarType rhs)6334 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
6335 {
6336 return lhs == basic_json(rhs);
6337 }
6338
6339 /*!
6340 @brief comparison: equal
6341 @copydoc operator==(const_reference, const_reference)
6342 */
6343 template<typename ScalarType, typename std::enable_if<
6344 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(ScalarType lhs,const_reference rhs)6345 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
6346 {
6347 return basic_json(lhs) == rhs;
6348 }
6349
6350 /*!
6351 @brief comparison: not equal
6352
6353 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
6354
6355 @param[in] lhs first JSON value to consider
6356 @param[in] rhs second JSON value to consider
6357 @return whether the values @a lhs and @a rhs are not equal
6358
6359 @complexity Linear.
6360
6361 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6362
6363 @liveexample{The example demonstrates comparing several JSON
6364 types.,operator__notequal}
6365
6366 @since version 1.0.0
6367 */
operator !=(const_reference lhs,const_reference rhs)6368 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
6369 {
6370 return !(lhs == rhs);
6371 }
6372
6373 /*!
6374 @brief comparison: not equal
6375 @copydoc operator!=(const_reference, const_reference)
6376 */
6377 template<typename ScalarType, typename std::enable_if<
6378 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,ScalarType rhs)6379 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
6380 {
6381 return lhs != basic_json(rhs);
6382 }
6383
6384 /*!
6385 @brief comparison: not equal
6386 @copydoc operator!=(const_reference, const_reference)
6387 */
6388 template<typename ScalarType, typename std::enable_if<
6389 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(ScalarType lhs,const_reference rhs)6390 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
6391 {
6392 return basic_json(lhs) != rhs;
6393 }
6394
6395 /*!
6396 @brief comparison: less than
6397
6398 Compares whether one JSON value @a lhs is less than another JSON value @a
6399 rhs according to the following rules:
6400 - If @a lhs and @a rhs have the same type, the values are compared using
6401 the default `<` operator.
6402 - Integer and floating-point numbers are automatically converted before
6403 comparison
6404 - In case @a lhs and @a rhs have different types, the values are ignored
6405 and the order of the types is considered, see
6406 @ref operator<(const value_t, const value_t).
6407
6408 @param[in] lhs first JSON value to consider
6409 @param[in] rhs second JSON value to consider
6410 @return whether @a lhs is less than @a rhs
6411
6412 @complexity Linear.
6413
6414 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6415
6416 @liveexample{The example demonstrates comparing several JSON
6417 types.,operator__less}
6418
6419 @since version 1.0.0
6420 */
operator <(const_reference lhs,const_reference rhs)6421 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6422 {
6423 const auto lhs_type = lhs.type();
6424 const auto rhs_type = rhs.type();
6425
6426 if (lhs_type == rhs_type)
6427 {
6428 switch (lhs_type)
6429 {
6430 case value_t::array:
6431 // note parentheses are necessary, see
6432 // https://github.com/nlohmann/json/issues/1530
6433 return (*lhs.m_value.array) < (*rhs.m_value.array);
6434
6435 case value_t::object:
6436 return (*lhs.m_value.object) < (*rhs.m_value.object);
6437
6438 case value_t::null:
6439 return false;
6440
6441 case value_t::string:
6442 return (*lhs.m_value.string) < (*rhs.m_value.string);
6443
6444 case value_t::boolean:
6445 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
6446
6447 case value_t::number_integer:
6448 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
6449
6450 case value_t::number_unsigned:
6451 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
6452
6453 case value_t::number_float:
6454 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
6455
6456 case value_t::binary:
6457 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
6458
6459 default:
6460 return false;
6461 }
6462 }
6463 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
6464 {
6465 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6466 }
6467 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
6468 {
6469 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6470 }
6471 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
6472 {
6473 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6474 }
6475 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
6476 {
6477 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6478 }
6479 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
6480 {
6481 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6482 }
6483 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
6484 {
6485 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6486 }
6487
6488 // We only reach this line if we cannot compare values. In that case,
6489 // we compare types. Note we have to call the operator explicitly,
6490 // because MSVC has problems otherwise.
6491 return operator<(lhs_type, rhs_type);
6492 }
6493
6494 /*!
6495 @brief comparison: less than
6496 @copydoc operator<(const_reference, const_reference)
6497 */
6498 template<typename ScalarType, typename std::enable_if<
6499 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,ScalarType rhs)6500 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
6501 {
6502 return lhs < basic_json(rhs);
6503 }
6504
6505 /*!
6506 @brief comparison: less than
6507 @copydoc operator<(const_reference, const_reference)
6508 */
6509 template<typename ScalarType, typename std::enable_if<
6510 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(ScalarType lhs,const_reference rhs)6511 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
6512 {
6513 return basic_json(lhs) < rhs;
6514 }
6515
6516 /*!
6517 @brief comparison: less than or equal
6518
6519 Compares whether one JSON value @a lhs is less than or equal to another
6520 JSON value by calculating `not (rhs < lhs)`.
6521
6522 @param[in] lhs first JSON value to consider
6523 @param[in] rhs second JSON value to consider
6524 @return whether @a lhs is less than or equal to @a rhs
6525
6526 @complexity Linear.
6527
6528 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6529
6530 @liveexample{The example demonstrates comparing several JSON
6531 types.,operator__greater}
6532
6533 @since version 1.0.0
6534 */
operator <=(const_reference lhs,const_reference rhs)6535 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6536 {
6537 return !(rhs < lhs);
6538 }
6539
6540 /*!
6541 @brief comparison: less than or equal
6542 @copydoc operator<=(const_reference, const_reference)
6543 */
6544 template<typename ScalarType, typename std::enable_if<
6545 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,ScalarType rhs)6546 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
6547 {
6548 return lhs <= basic_json(rhs);
6549 }
6550
6551 /*!
6552 @brief comparison: less than or equal
6553 @copydoc operator<=(const_reference, const_reference)
6554 */
6555 template<typename ScalarType, typename std::enable_if<
6556 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(ScalarType lhs,const_reference rhs)6557 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
6558 {
6559 return basic_json(lhs) <= rhs;
6560 }
6561
6562 /*!
6563 @brief comparison: greater than
6564
6565 Compares whether one JSON value @a lhs is greater than another
6566 JSON value by calculating `not (lhs <= rhs)`.
6567
6568 @param[in] lhs first JSON value to consider
6569 @param[in] rhs second JSON value to consider
6570 @return whether @a lhs is greater than to @a rhs
6571
6572 @complexity Linear.
6573
6574 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6575
6576 @liveexample{The example demonstrates comparing several JSON
6577 types.,operator__lessequal}
6578
6579 @since version 1.0.0
6580 */
operator >(const_reference lhs,const_reference rhs)6581 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6582 {
6583 return !(lhs <= rhs);
6584 }
6585
6586 /*!
6587 @brief comparison: greater than
6588 @copydoc operator>(const_reference, const_reference)
6589 */
6590 template<typename ScalarType, typename std::enable_if<
6591 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,ScalarType rhs)6592 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
6593 {
6594 return lhs > basic_json(rhs);
6595 }
6596
6597 /*!
6598 @brief comparison: greater than
6599 @copydoc operator>(const_reference, const_reference)
6600 */
6601 template<typename ScalarType, typename std::enable_if<
6602 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(ScalarType lhs,const_reference rhs)6603 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
6604 {
6605 return basic_json(lhs) > rhs;
6606 }
6607
6608 /*!
6609 @brief comparison: greater than or equal
6610
6611 Compares whether one JSON value @a lhs is greater than or equal to another
6612 JSON value by calculating `not (lhs < rhs)`.
6613
6614 @param[in] lhs first JSON value to consider
6615 @param[in] rhs second JSON value to consider
6616 @return whether @a lhs is greater than or equal to @a rhs
6617
6618 @complexity Linear.
6619
6620 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6621
6622 @liveexample{The example demonstrates comparing several JSON
6623 types.,operator__greaterequal}
6624
6625 @since version 1.0.0
6626 */
operator >=(const_reference lhs,const_reference rhs)6627 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6628 {
6629 return !(lhs < rhs);
6630 }
6631
6632 /*!
6633 @brief comparison: greater than or equal
6634 @copydoc operator>=(const_reference, const_reference)
6635 */
6636 template<typename ScalarType, typename std::enable_if<
6637 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,ScalarType rhs)6638 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
6639 {
6640 return lhs >= basic_json(rhs);
6641 }
6642
6643 /*!
6644 @brief comparison: greater than or equal
6645 @copydoc operator>=(const_reference, const_reference)
6646 */
6647 template<typename ScalarType, typename std::enable_if<
6648 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(ScalarType lhs,const_reference rhs)6649 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
6650 {
6651 return basic_json(lhs) >= rhs;
6652 }
6653
6654 /// @}
6655
6656 ///////////////////
6657 // serialization //
6658 ///////////////////
6659
6660 /// @name serialization
6661 /// @{
6662
6663 /*!
6664 @brief serialize to stream
6665
6666 Serialize the given JSON value @a j to the output stream @a o. The JSON
6667 value will be serialized using the @ref dump member function.
6668
6669 - The indentation of the output can be controlled with the member variable
6670 `width` of the output stream @a o. For instance, using the manipulator
6671 `std::setw(4)` on @a o sets the indentation level to `4` and the
6672 serialization result is the same as calling `dump(4)`.
6673
6674 - The indentation character can be controlled with the member variable
6675 `fill` of the output stream @a o. For instance, the manipulator
6676 `std::setfill('\\t')` sets indentation to use a tab character rather than
6677 the default space character.
6678
6679 @param[in,out] o stream to serialize to
6680 @param[in] j JSON value to serialize
6681
6682 @return the stream @a o
6683
6684 @throw type_error.316 if a string stored inside the JSON value is not
6685 UTF-8 encoded
6686
6687 @complexity Linear.
6688
6689 @liveexample{The example below shows the serialization with different
6690 parameters to `width` to adjust the indentation level.,operator_serialize}
6691
6692 @since version 1.0.0; indentation character added in version 3.0.0
6693 */
operator <<(std::ostream & o,const basic_json & j)6694 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
6695 {
6696 // read width member and use it as indentation parameter if nonzero
6697 const bool pretty_print = o.width() > 0;
6698 const auto indentation = pretty_print ? o.width() : 0;
6699
6700 // reset width to 0 for subsequent calls to this stream
6701 o.width(0);
6702
6703 // do the actual serialization
6704 serializer s(detail::output_adapter<char>(o), o.fill());
6705 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
6706 return o;
6707 }
6708
6709 /*!
6710 @brief serialize to stream
6711 @deprecated This stream operator is deprecated and will be removed in
6712 future 4.0.0 of the library. Please use
6713 @ref operator<<(std::ostream&, const basic_json&)
6714 instead; that is, replace calls like `j >> o;` with `o << j;`.
6715 @since version 1.0.0; deprecated since version 3.0.0
6716 */
6717 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)6718 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
6719 {
6720 return o << j;
6721 }
6722
6723 /// @}
6724
6725
6726 /////////////////////
6727 // deserialization //
6728 /////////////////////
6729
6730 /// @name deserialization
6731 /// @{
6732
6733 /*!
6734 @brief deserialize from a compatible input
6735
6736 @tparam InputType A compatible input, for instance
6737 - an std::istream object
6738 - a FILE pointer
6739 - a C-style array of characters
6740 - a pointer to a null-terminated string of single byte characters
6741 - an object obj for which begin(obj) and end(obj) produces a valid pair of
6742 iterators.
6743
6744 @param[in] i input to read from
6745 @param[in] cb a parser callback function of type @ref parser_callback_t
6746 which is used to control the deserialization by filtering unwanted values
6747 (optional)
6748 @param[in] allow_exceptions whether to throw exceptions in case of a
6749 parse error (optional, true by default)
6750 @param[in] ignore_comments whether comments should be ignored and treated
6751 like whitespace (true) or yield a parse error (true); (optional, false by
6752 default)
6753
6754 @return deserialized JSON value; in case of a parse error and
6755 @a allow_exceptions set to `false`, the return value will be
6756 value_t::discarded.
6757
6758 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
6759 of input; expected string literal""`
6760 @throw parse_error.102 if to_unicode fails or surrogate error
6761 @throw parse_error.103 if to_unicode fails
6762
6763 @complexity Linear in the length of the input. The parser is a predictive
6764 LL(1) parser. The complexity can be higher if the parser callback function
6765 @a cb or reading from the input @a i has a super-linear complexity.
6766
6767 @note A UTF-8 byte order mark is silently ignored.
6768
6769 @liveexample{The example below demonstrates the `parse()` function reading
6770 from an array.,parse__array__parser_callback_t}
6771
6772 @liveexample{The example below demonstrates the `parse()` function with
6773 and without callback function.,parse__string__parser_callback_t}
6774
6775 @liveexample{The example below demonstrates the `parse()` function with
6776 and without callback function.,parse__istream__parser_callback_t}
6777
6778 @liveexample{The example below demonstrates the `parse()` function reading
6779 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
6780
6781 @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
6782 ignore comments.
6783 */
6784 template<typename InputType>
6785 JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)6786 static basic_json parse(InputType&& i,
6787 const parser_callback_t cb = nullptr,
6788 const bool allow_exceptions = true,
6789 const bool ignore_comments = false)
6790 {
6791 basic_json result;
6792 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
6793 return result;
6794 }
6795
6796 /*!
6797 @brief deserialize from a pair of character iterators
6798
6799 The value_type of the iterator must be a integral type with size of 1, 2 or
6800 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
6801
6802 @param[in] first iterator to start of character range
6803 @param[in] last iterator to end of character range
6804 @param[in] cb a parser callback function of type @ref parser_callback_t
6805 which is used to control the deserialization by filtering unwanted values
6806 (optional)
6807 @param[in] allow_exceptions whether to throw exceptions in case of a
6808 parse error (optional, true by default)
6809 @param[in] ignore_comments whether comments should be ignored and treated
6810 like whitespace (true) or yield a parse error (true); (optional, false by
6811 default)
6812
6813 @return deserialized JSON value; in case of a parse error and
6814 @a allow_exceptions set to `false`, the return value will be
6815 value_t::discarded.
6816
6817 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
6818 of input; expected string literal""`
6819 @throw parse_error.102 if to_unicode fails or surrogate error
6820 @throw parse_error.103 if to_unicode fails
6821 */
6822 template<typename IteratorType>
6823 JSON_HEDLEY_WARN_UNUSED_RESULT
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)6824 static basic_json parse(IteratorType first,
6825 IteratorType last,
6826 const parser_callback_t cb = nullptr,
6827 const bool allow_exceptions = true,
6828 const bool ignore_comments = false)
6829 {
6830 basic_json result;
6831 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
6832 return result;
6833 }
6834
6835 JSON_HEDLEY_WARN_UNUSED_RESULT
6836 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
parse(detail::span_input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)6837 static basic_json parse(detail::span_input_adapter&& i,
6838 const parser_callback_t cb = nullptr,
6839 const bool allow_exceptions = true,
6840 const bool ignore_comments = false)
6841 {
6842 basic_json result;
6843 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
6844 return result;
6845 }
6846
6847 /*!
6848 @brief check if the input is valid JSON
6849
6850 Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
6851 function, this function neither throws an exception in case of invalid JSON
6852 input (i.e., a parse error) nor creates diagnostic information.
6853
6854 @tparam InputType A compatible input, for instance
6855 - an std::istream object
6856 - a FILE pointer
6857 - a C-style array of characters
6858 - a pointer to a null-terminated string of single byte characters
6859 - an object obj for which begin(obj) and end(obj) produces a valid pair of
6860 iterators.
6861
6862 @param[in] i input to read from
6863 @param[in] ignore_comments whether comments should be ignored and treated
6864 like whitespace (true) or yield a parse error (true); (optional, false by
6865 default)
6866
6867 @return Whether the input read from @a i is valid JSON.
6868
6869 @complexity Linear in the length of the input. The parser is a predictive
6870 LL(1) parser.
6871
6872 @note A UTF-8 byte order mark is silently ignored.
6873
6874 @liveexample{The example below demonstrates the `accept()` function reading
6875 from a string.,accept__string}
6876 */
6877 template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)6878 static bool accept(InputType&& i,
6879 const bool ignore_comments = false)
6880 {
6881 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
6882 }
6883
6884 template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)6885 static bool accept(IteratorType first, IteratorType last,
6886 const bool ignore_comments = false)
6887 {
6888 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
6889 }
6890
6891 JSON_HEDLEY_WARN_UNUSED_RESULT
6892 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)6893 static bool accept(detail::span_input_adapter&& i,
6894 const bool ignore_comments = false)
6895 {
6896 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
6897 }
6898
6899 /*!
6900 @brief generate SAX events
6901
6902 The SAX event lister must follow the interface of @ref json_sax.
6903
6904 This function reads from a compatible input. Examples are:
6905 - an std::istream object
6906 - a FILE pointer
6907 - a C-style array of characters
6908 - a pointer to a null-terminated string of single byte characters
6909 - an object obj for which begin(obj) and end(obj) produces a valid pair of
6910 iterators.
6911
6912 @param[in] i input to read from
6913 @param[in,out] sax SAX event listener
6914 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
6915 @param[in] strict whether the input has to be consumed completely
6916 @param[in] ignore_comments whether comments should be ignored and treated
6917 like whitespace (true) or yield a parse error (true); (optional, false by
6918 default); only applies to the JSON file format.
6919
6920 @return return value of the last processed SAX event
6921
6922 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
6923 of input; expected string literal""`
6924 @throw parse_error.102 if to_unicode fails or surrogate error
6925 @throw parse_error.103 if to_unicode fails
6926
6927 @complexity Linear in the length of the input. The parser is a predictive
6928 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
6929 a super-linear complexity.
6930
6931 @note A UTF-8 byte order mark is silently ignored.
6932
6933 @liveexample{The example below demonstrates the `sax_parse()` function
6934 reading from string and processing the events with a user-defined SAX
6935 event consumer.,sax_parse}
6936
6937 @since version 3.2.0
6938 */
6939 template <typename InputType, typename SAX>
6940 JSON_HEDLEY_NON_NULL(2)
sax_parse(InputType && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)6941 static bool sax_parse(InputType&& i, SAX* sax,
6942 input_format_t format = input_format_t::json,
6943 const bool strict = true,
6944 const bool ignore_comments = false)
6945 {
6946 auto ia = detail::input_adapter(std::forward<InputType>(i));
6947 return format == input_format_t::json
6948 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6949 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6950 }
6951
6952 template<class IteratorType, class SAX>
6953 JSON_HEDLEY_NON_NULL(3)
sax_parse(IteratorType first,IteratorType last,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)6954 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
6955 input_format_t format = input_format_t::json,
6956 const bool strict = true,
6957 const bool ignore_comments = false)
6958 {
6959 auto ia = detail::input_adapter(std::move(first), std::move(last));
6960 return format == input_format_t::json
6961 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6962 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6963 }
6964
6965 template <typename SAX>
6966 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
6967 JSON_HEDLEY_NON_NULL(2)
sax_parse(detail::span_input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)6968 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
6969 input_format_t format = input_format_t::json,
6970 const bool strict = true,
6971 const bool ignore_comments = false)
6972 {
6973 auto ia = i.get();
6974 return format == input_format_t::json
6975 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
6976 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
6977 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
6978 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
6979 }
6980
6981 /*!
6982 @brief deserialize from stream
6983 @deprecated This stream operator is deprecated and will be removed in
6984 version 4.0.0 of the library. Please use
6985 @ref operator>>(std::istream&, basic_json&)
6986 instead; that is, replace calls like `j << i;` with `i >> j;`.
6987 @since version 1.0.0; deprecated since version 3.0.0
6988 */
6989 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)6990 friend std::istream& operator<<(basic_json& j, std::istream& i)
6991 {
6992 return operator>>(i, j);
6993 }
6994
6995 /*!
6996 @brief deserialize from stream
6997
6998 Deserializes an input stream to a JSON value.
6999
7000 @param[in,out] i input stream to read a serialized JSON value from
7001 @param[in,out] j JSON value to write the deserialized input to
7002
7003 @throw parse_error.101 in case of an unexpected token
7004 @throw parse_error.102 if to_unicode fails or surrogate error
7005 @throw parse_error.103 if to_unicode fails
7006
7007 @complexity Linear in the length of the input. The parser is a predictive
7008 LL(1) parser.
7009
7010 @note A UTF-8 byte order mark is silently ignored.
7011
7012 @liveexample{The example below shows how a JSON value is constructed by
7013 reading a serialization from a stream.,operator_deserialize}
7014
7015 @sa parse(std::istream&, const parser_callback_t) for a variant with a
7016 parser callback function to filter values while parsing
7017
7018 @since version 1.0.0
7019 */
operator >>(std::istream & i,basic_json & j)7020 friend std::istream& operator>>(std::istream& i, basic_json& j)
7021 {
7022 parser(detail::input_adapter(i)).parse(false, j);
7023 return i;
7024 }
7025
7026 /// @}
7027
7028 ///////////////////////////
7029 // convenience functions //
7030 ///////////////////////////
7031
7032 /*!
7033 @brief return the type as string
7034
7035 Returns the type name as string to be used in error messages - usually to
7036 indicate that a function was called on a wrong JSON type.
7037
7038 @return a string representation of a the @a m_type member:
7039 Value type | return value
7040 ----------- | -------------
7041 null | `"null"`
7042 boolean | `"boolean"`
7043 string | `"string"`
7044 number | `"number"` (for all number types)
7045 object | `"object"`
7046 array | `"array"`
7047 binary | `"binary"`
7048 discarded | `"discarded"`
7049
7050 @exceptionsafety No-throw guarantee: this function never throws exceptions.
7051
7052 @complexity Constant.
7053
7054 @liveexample{The following code exemplifies `type_name()` for all JSON
7055 types.,type_name}
7056
7057 @sa see @ref type() -- return the type of the JSON value
7058 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
7059
7060 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
7061 since 3.0.0
7062 */
7063 JSON_HEDLEY_RETURNS_NON_NULL
type_name() const7064 const char* type_name() const noexcept
7065 {
7066 {
7067 switch (m_type)
7068 {
7069 case value_t::null:
7070 return "null";
7071 case value_t::object:
7072 return "object";
7073 case value_t::array:
7074 return "array";
7075 case value_t::string:
7076 return "string";
7077 case value_t::boolean:
7078 return "boolean";
7079 case value_t::binary:
7080 return "binary";
7081 case value_t::discarded:
7082 return "discarded";
7083 default:
7084 return "number";
7085 }
7086 }
7087 }
7088
7089
7090 JSON_PRIVATE_UNLESS_TESTED:
7091 //////////////////////
7092 // member variables //
7093 //////////////////////
7094
7095 /// the type of the current element
7096 value_t m_type = value_t::null;
7097
7098 /// the value of the current element
7099 json_value m_value = {};
7100
7101 #if JSON_DIAGNOSTICS
7102 /// a pointer to a parent value (for debugging purposes)
7103 basic_json* m_parent = nullptr;
7104 #endif
7105
7106 //////////////////////////////////////////
7107 // binary serialization/deserialization //
7108 //////////////////////////////////////////
7109
7110 /// @name binary serialization/deserialization support
7111 /// @{
7112
7113 public:
7114 /*!
7115 @brief create a CBOR serialization of a given JSON value
7116
7117 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
7118 Binary Object Representation) serialization format. CBOR is a binary
7119 serialization format which aims to be more compact than JSON itself, yet
7120 more efficient to parse.
7121
7122 The library uses the following mapping from JSON values types to
7123 CBOR types according to the CBOR specification (RFC 7049):
7124
7125 JSON value type | value/range | CBOR type | first byte
7126 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
7127 null | `null` | Null | 0xF6
7128 boolean | `true` | True | 0xF5
7129 boolean | `false` | False | 0xF4
7130 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
7131 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
7132 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
7133 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
7134 number_integer | -24..-1 | Negative integer | 0x20..0x37
7135 number_integer | 0..23 | Integer | 0x00..0x17
7136 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
7137 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
7138 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
7139 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
7140 number_unsigned | 0..23 | Integer | 0x00..0x17
7141 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
7142 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
7143 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
7144 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
7145 number_float | *any value representable by a float* | Single-Precision Float | 0xFA
7146 number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB
7147 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
7148 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
7149 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
7150 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
7151 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
7152 array | *size*: 0..23 | array | 0x80..0x97
7153 array | *size*: 23..255 | array (1 byte follow) | 0x98
7154 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
7155 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
7156 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
7157 object | *size*: 0..23 | map | 0xA0..0xB7
7158 object | *size*: 23..255 | map (1 byte follow) | 0xB8
7159 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
7160 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
7161 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
7162 binary | *size*: 0..23 | byte string | 0x40..0x57
7163 binary | *size*: 23..255 | byte string (1 byte follow) | 0x58
7164 binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59
7165 binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A
7166 binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B
7167
7168 @note The mapping is **complete** in the sense that any JSON value type
7169 can be converted to a CBOR value.
7170
7171 @note If NaN or Infinity are stored inside a JSON number, they are
7172 serialized properly. This behavior differs from the @ref dump()
7173 function which serializes NaN or Infinity to `null`.
7174
7175 @note The following CBOR types are not used in the conversion:
7176 - UTF-8 strings terminated by "break" (0x7F)
7177 - arrays terminated by "break" (0x9F)
7178 - maps terminated by "break" (0xBF)
7179 - byte strings terminated by "break" (0x5F)
7180 - date/time (0xC0..0xC1)
7181 - bignum (0xC2..0xC3)
7182 - decimal fraction (0xC4)
7183 - bigfloat (0xC5)
7184 - expected conversions (0xD5..0xD7)
7185 - simple values (0xE0..0xF3, 0xF8)
7186 - undefined (0xF7)
7187 - half-precision floats (0xF9)
7188 - break (0xFF)
7189
7190 @param[in] j JSON value to serialize
7191 @return CBOR serialization as byte vector
7192
7193 @complexity Linear in the size of the JSON value @a j.
7194
7195 @liveexample{The example shows the serialization of a JSON value to a byte
7196 vector in CBOR format.,to_cbor}
7197
7198 @sa http://cbor.io
7199 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
7200 analogous deserialization
7201 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
7202 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
7203 related UBJSON format
7204
7205 @since version 2.0.9; compact representation of floating-point numbers
7206 since version 3.8.0
7207 */
to_cbor(const basic_json & j)7208 static std::vector<uint8_t> to_cbor(const basic_json& j)
7209 {
7210 std::vector<uint8_t> result;
7211 to_cbor(j, result);
7212 return result;
7213 }
7214
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)7215 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
7216 {
7217 binary_writer<uint8_t>(o).write_cbor(j);
7218 }
7219
to_cbor(const basic_json & j,detail::output_adapter<char> o)7220 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
7221 {
7222 binary_writer<char>(o).write_cbor(j);
7223 }
7224
7225 /*!
7226 @brief create a MessagePack serialization of a given JSON value
7227
7228 Serializes a given JSON value @a j to a byte vector using the MessagePack
7229 serialization format. MessagePack is a binary serialization format which
7230 aims to be more compact than JSON itself, yet more efficient to parse.
7231
7232 The library uses the following mapping from JSON values types to
7233 MessagePack types according to the MessagePack specification:
7234
7235 JSON value type | value/range | MessagePack type | first byte
7236 --------------- | --------------------------------- | ---------------- | ----------
7237 null | `null` | nil | 0xC0
7238 boolean | `true` | true | 0xC3
7239 boolean | `false` | false | 0xC2
7240 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
7241 number_integer | -2147483648..-32769 | int32 | 0xD2
7242 number_integer | -32768..-129 | int16 | 0xD1
7243 number_integer | -128..-33 | int8 | 0xD0
7244 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
7245 number_integer | 0..127 | positive fixint | 0x00..0x7F
7246 number_integer | 128..255 | uint 8 | 0xCC
7247 number_integer | 256..65535 | uint 16 | 0xCD
7248 number_integer | 65536..4294967295 | uint 32 | 0xCE
7249 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
7250 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
7251 number_unsigned | 128..255 | uint 8 | 0xCC
7252 number_unsigned | 256..65535 | uint 16 | 0xCD
7253 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
7254 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
7255 number_float | *any value representable by a float* | float 32 | 0xCA
7256 number_float | *any value NOT representable by a float* | float 64 | 0xCB
7257 string | *length*: 0..31 | fixstr | 0xA0..0xBF
7258 string | *length*: 32..255 | str 8 | 0xD9
7259 string | *length*: 256..65535 | str 16 | 0xDA
7260 string | *length*: 65536..4294967295 | str 32 | 0xDB
7261 array | *size*: 0..15 | fixarray | 0x90..0x9F
7262 array | *size*: 16..65535 | array 16 | 0xDC
7263 array | *size*: 65536..4294967295 | array 32 | 0xDD
7264 object | *size*: 0..15 | fix map | 0x80..0x8F
7265 object | *size*: 16..65535 | map 16 | 0xDE
7266 object | *size*: 65536..4294967295 | map 32 | 0xDF
7267 binary | *size*: 0..255 | bin 8 | 0xC4
7268 binary | *size*: 256..65535 | bin 16 | 0xC5
7269 binary | *size*: 65536..4294967295 | bin 32 | 0xC6
7270
7271 @note The mapping is **complete** in the sense that any JSON value type
7272 can be converted to a MessagePack value.
7273
7274 @note The following values can **not** be converted to a MessagePack value:
7275 - strings with more than 4294967295 bytes
7276 - byte strings with more than 4294967295 bytes
7277 - arrays with more than 4294967295 elements
7278 - objects with more than 4294967295 elements
7279
7280 @note Any MessagePack output created @ref to_msgpack can be successfully
7281 parsed by @ref from_msgpack.
7282
7283 @note If NaN or Infinity are stored inside a JSON number, they are
7284 serialized properly. This behavior differs from the @ref dump()
7285 function which serializes NaN or Infinity to `null`.
7286
7287 @param[in] j JSON value to serialize
7288 @return MessagePack serialization as byte vector
7289
7290 @complexity Linear in the size of the JSON value @a j.
7291
7292 @liveexample{The example shows the serialization of a JSON value to a byte
7293 vector in MessagePack format.,to_msgpack}
7294
7295 @sa http://msgpack.org
7296 @sa see @ref from_msgpack for the analogous deserialization
7297 @sa see @ref to_cbor(const basic_json& for the related CBOR format
7298 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
7299 related UBJSON format
7300
7301 @since version 2.0.9
7302 */
to_msgpack(const basic_json & j)7303 static std::vector<uint8_t> to_msgpack(const basic_json& j)
7304 {
7305 std::vector<uint8_t> result;
7306 to_msgpack(j, result);
7307 return result;
7308 }
7309
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)7310 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
7311 {
7312 binary_writer<uint8_t>(o).write_msgpack(j);
7313 }
7314
to_msgpack(const basic_json & j,detail::output_adapter<char> o)7315 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
7316 {
7317 binary_writer<char>(o).write_msgpack(j);
7318 }
7319
7320 /*!
7321 @brief create a UBJSON serialization of a given JSON value
7322
7323 Serializes a given JSON value @a j to a byte vector using the UBJSON
7324 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
7325 than JSON itself, yet more efficient to parse.
7326
7327 The library uses the following mapping from JSON values types to
7328 UBJSON types according to the UBJSON specification:
7329
7330 JSON value type | value/range | UBJSON type | marker
7331 --------------- | --------------------------------- | ----------- | ------
7332 null | `null` | null | `Z`
7333 boolean | `true` | true | `T`
7334 boolean | `false` | false | `F`
7335 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
7336 number_integer | -2147483648..-32769 | int32 | `l`
7337 number_integer | -32768..-129 | int16 | `I`
7338 number_integer | -128..127 | int8 | `i`
7339 number_integer | 128..255 | uint8 | `U`
7340 number_integer | 256..32767 | int16 | `I`
7341 number_integer | 32768..2147483647 | int32 | `l`
7342 number_integer | 2147483648..9223372036854775807 | int64 | `L`
7343 number_unsigned | 0..127 | int8 | `i`
7344 number_unsigned | 128..255 | uint8 | `U`
7345 number_unsigned | 256..32767 | int16 | `I`
7346 number_unsigned | 32768..2147483647 | int32 | `l`
7347 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
7348 number_unsigned | 2147483649..18446744073709551615 | high-precision | `H`
7349 number_float | *any value* | float64 | `D`
7350 string | *with shortest length indicator* | string | `S`
7351 array | *see notes on optimized format* | array | `[`
7352 object | *see notes on optimized format* | map | `{`
7353
7354 @note The mapping is **complete** in the sense that any JSON value type
7355 can be converted to a UBJSON value.
7356
7357 @note The following values can **not** be converted to a UBJSON value:
7358 - strings with more than 9223372036854775807 bytes (theoretical)
7359
7360 @note The following markers are not used in the conversion:
7361 - `Z`: no-op values are not created.
7362 - `C`: single-byte strings are serialized with `S` markers.
7363
7364 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
7365 by @ref from_ubjson.
7366
7367 @note If NaN or Infinity are stored inside a JSON number, they are
7368 serialized properly. This behavior differs from the @ref dump()
7369 function which serializes NaN or Infinity to `null`.
7370
7371 @note The optimized formats for containers are supported: Parameter
7372 @a use_size adds size information to the beginning of a container and
7373 removes the closing marker. Parameter @a use_type further checks
7374 whether all elements of a container have the same type and adds the
7375 type marker to the beginning of the container. The @a use_type
7376 parameter must only be used together with @a use_size = true. Note
7377 that @a use_size = true alone may result in larger representations -
7378 the benefit of this parameter is that the receiving side is
7379 immediately informed on the number of elements of the container.
7380
7381 @note If the JSON data contains the binary type, the value stored is a list
7382 of integers, as suggested by the UBJSON documentation. In particular,
7383 this means that serialization and the deserialization of a JSON
7384 containing binary values into UBJSON and back will result in a
7385 different JSON object.
7386
7387 @param[in] j JSON value to serialize
7388 @param[in] use_size whether to add size annotations to container types
7389 @param[in] use_type whether to add type annotations to container types
7390 (must be combined with @a use_size = true)
7391 @return UBJSON serialization as byte vector
7392
7393 @complexity Linear in the size of the JSON value @a j.
7394
7395 @liveexample{The example shows the serialization of a JSON value to a byte
7396 vector in UBJSON format.,to_ubjson}
7397
7398 @sa http://ubjson.org
7399 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
7400 analogous deserialization
7401 @sa see @ref to_cbor(const basic_json& for the related CBOR format
7402 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
7403
7404 @since version 3.1.0
7405 */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)7406 static std::vector<uint8_t> to_ubjson(const basic_json& j,
7407 const bool use_size = false,
7408 const bool use_type = false)
7409 {
7410 std::vector<uint8_t> result;
7411 to_ubjson(j, result, use_size, use_type);
7412 return result;
7413 }
7414
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)7415 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
7416 const bool use_size = false, const bool use_type = false)
7417 {
7418 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
7419 }
7420
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)7421 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
7422 const bool use_size = false, const bool use_type = false)
7423 {
7424 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
7425 }
7426
7427
7428 /*!
7429 @brief Serializes the given JSON object `j` to BSON and returns a vector
7430 containing the corresponding BSON-representation.
7431
7432 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
7433 stored as a single entity (a so-called document).
7434
7435 The library uses the following mapping from JSON values types to BSON types:
7436
7437 JSON value type | value/range | BSON type | marker
7438 --------------- | --------------------------------- | ----------- | ------
7439 null | `null` | null | 0x0A
7440 boolean | `true`, `false` | boolean | 0x08
7441 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
7442 number_integer | -2147483648..2147483647 | int32 | 0x10
7443 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
7444 number_unsigned | 0..2147483647 | int32 | 0x10
7445 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
7446 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
7447 number_float | *any value* | double | 0x01
7448 string | *any value* | string | 0x02
7449 array | *any value* | document | 0x04
7450 object | *any value* | document | 0x03
7451 binary | *any value* | binary | 0x05
7452
7453 @warning The mapping is **incomplete**, since only JSON-objects (and things
7454 contained therein) can be serialized to BSON.
7455 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
7456 and the keys may not contain U+0000, since they are serialized a
7457 zero-terminated c-strings.
7458
7459 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
7460 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
7461 @throw type_error.317 if `!j.is_object()`
7462
7463 @pre The input `j` is required to be an object: `j.is_object() == true`.
7464
7465 @note Any BSON output created via @ref to_bson can be successfully parsed
7466 by @ref from_bson.
7467
7468 @param[in] j JSON value to serialize
7469 @return BSON serialization as byte vector
7470
7471 @complexity Linear in the size of the JSON value @a j.
7472
7473 @liveexample{The example shows the serialization of a JSON value to a byte
7474 vector in BSON format.,to_bson}
7475
7476 @sa http://bsonspec.org/spec.html
7477 @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
7478 analogous deserialization
7479 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
7480 related UBJSON format
7481 @sa see @ref to_cbor(const basic_json&) for the related CBOR format
7482 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
7483 */
to_bson(const basic_json & j)7484 static std::vector<uint8_t> to_bson(const basic_json& j)
7485 {
7486 std::vector<uint8_t> result;
7487 to_bson(j, result);
7488 return result;
7489 }
7490
7491 /*!
7492 @brief Serializes the given JSON object `j` to BSON and forwards the
7493 corresponding BSON-representation to the given output_adapter `o`.
7494 @param j The JSON object to convert to BSON.
7495 @param o The output adapter that receives the binary BSON representation.
7496 @pre The input `j` shall be an object: `j.is_object() == true`
7497 @sa see @ref to_bson(const basic_json&)
7498 */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)7499 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
7500 {
7501 binary_writer<uint8_t>(o).write_bson(j);
7502 }
7503
7504 /*!
7505 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
7506 */
to_bson(const basic_json & j,detail::output_adapter<char> o)7507 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
7508 {
7509 binary_writer<char>(o).write_bson(j);
7510 }
7511
7512
7513 /*!
7514 @brief create a JSON value from an input in CBOR format
7515
7516 Deserializes a given input @a i to a JSON value using the CBOR (Concise
7517 Binary Object Representation) serialization format.
7518
7519 The library maps CBOR types to JSON value types as follows:
7520
7521 CBOR type | JSON value type | first byte
7522 ---------------------- | --------------- | ----------
7523 Integer | number_unsigned | 0x00..0x17
7524 Unsigned integer | number_unsigned | 0x18
7525 Unsigned integer | number_unsigned | 0x19
7526 Unsigned integer | number_unsigned | 0x1A
7527 Unsigned integer | number_unsigned | 0x1B
7528 Negative integer | number_integer | 0x20..0x37
7529 Negative integer | number_integer | 0x38
7530 Negative integer | number_integer | 0x39
7531 Negative integer | number_integer | 0x3A
7532 Negative integer | number_integer | 0x3B
7533 Byte string | binary | 0x40..0x57
7534 Byte string | binary | 0x58
7535 Byte string | binary | 0x59
7536 Byte string | binary | 0x5A
7537 Byte string | binary | 0x5B
7538 UTF-8 string | string | 0x60..0x77
7539 UTF-8 string | string | 0x78
7540 UTF-8 string | string | 0x79
7541 UTF-8 string | string | 0x7A
7542 UTF-8 string | string | 0x7B
7543 UTF-8 string | string | 0x7F
7544 array | array | 0x80..0x97
7545 array | array | 0x98
7546 array | array | 0x99
7547 array | array | 0x9A
7548 array | array | 0x9B
7549 array | array | 0x9F
7550 map | object | 0xA0..0xB7
7551 map | object | 0xB8
7552 map | object | 0xB9
7553 map | object | 0xBA
7554 map | object | 0xBB
7555 map | object | 0xBF
7556 False | `false` | 0xF4
7557 True | `true` | 0xF5
7558 Null | `null` | 0xF6
7559 Half-Precision Float | number_float | 0xF9
7560 Single-Precision Float | number_float | 0xFA
7561 Double-Precision Float | number_float | 0xFB
7562
7563 @warning The mapping is **incomplete** in the sense that not all CBOR
7564 types can be converted to a JSON value. The following CBOR types
7565 are not supported and will yield parse errors (parse_error.112):
7566 - date/time (0xC0..0xC1)
7567 - bignum (0xC2..0xC3)
7568 - decimal fraction (0xC4)
7569 - bigfloat (0xC5)
7570 - expected conversions (0xD5..0xD7)
7571 - simple values (0xE0..0xF3, 0xF8)
7572 - undefined (0xF7)
7573
7574 @warning CBOR allows map keys of any type, whereas JSON only allows
7575 strings as keys in object values. Therefore, CBOR maps with keys
7576 other than UTF-8 strings are rejected (parse_error.113).
7577
7578 @note Any CBOR output created @ref to_cbor can be successfully parsed by
7579 @ref from_cbor.
7580
7581 @param[in] i an input in CBOR format convertible to an input adapter
7582 @param[in] strict whether to expect the input to be consumed until EOF
7583 (true by default)
7584 @param[in] allow_exceptions whether to throw exceptions in case of a
7585 parse error (optional, true by default)
7586 @param[in] tag_handler how to treat CBOR tags (optional, error by default)
7587
7588 @return deserialized JSON value; in case of a parse error and
7589 @a allow_exceptions set to `false`, the return value will be
7590 value_t::discarded.
7591
7592 @throw parse_error.110 if the given input ends prematurely or the end of
7593 file was not reached when @a strict was set to true
7594 @throw parse_error.112 if unsupported features from CBOR were
7595 used in the given input @a v or if the input is not valid CBOR
7596 @throw parse_error.113 if a string was expected as map key, but not found
7597
7598 @complexity Linear in the size of the input @a i.
7599
7600 @liveexample{The example shows the deserialization of a byte vector in CBOR
7601 format to a JSON value.,from_cbor}
7602
7603 @sa http://cbor.io
7604 @sa see @ref to_cbor(const basic_json&) for the analogous serialization
7605 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
7606 related MessagePack format
7607 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
7608 related UBJSON format
7609
7610 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
7611 consume input adapters, removed start_index parameter, and added
7612 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
7613 since 3.2.0; added @a tag_handler parameter since 3.9.0.
7614 */
7615 template<typename InputType>
7616 JSON_HEDLEY_WARN_UNUSED_RESULT
from_cbor(InputType && i,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)7617 static basic_json from_cbor(InputType&& i,
7618 const bool strict = true,
7619 const bool allow_exceptions = true,
7620 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7621 {
7622 basic_json result;
7623 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7624 auto ia = detail::input_adapter(std::forward<InputType>(i));
7625 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7626 return res ? result : basic_json(value_t::discarded);
7627 }
7628
7629 /*!
7630 @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
7631 */
7632 template<typename IteratorType>
7633 JSON_HEDLEY_WARN_UNUSED_RESULT
from_cbor(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)7634 static basic_json from_cbor(IteratorType first, IteratorType last,
7635 const bool strict = true,
7636 const bool allow_exceptions = true,
7637 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7638 {
7639 basic_json result;
7640 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7641 auto ia = detail::input_adapter(std::move(first), std::move(last));
7642 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7643 return res ? result : basic_json(value_t::discarded);
7644 }
7645
7646 template<typename T>
7647 JSON_HEDLEY_WARN_UNUSED_RESULT
7648 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
from_cbor(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)7649 static basic_json from_cbor(const T* ptr, std::size_t len,
7650 const bool strict = true,
7651 const bool allow_exceptions = true,
7652 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7653 {
7654 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
7655 }
7656
7657
7658 JSON_HEDLEY_WARN_UNUSED_RESULT
7659 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
from_cbor(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)7660 static basic_json from_cbor(detail::span_input_adapter&& i,
7661 const bool strict = true,
7662 const bool allow_exceptions = true,
7663 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7664 {
7665 basic_json result;
7666 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7667 auto ia = i.get();
7668 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
7669 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
7670 return res ? result : basic_json(value_t::discarded);
7671 }
7672
7673 /*!
7674 @brief create a JSON value from an input in MessagePack format
7675
7676 Deserializes a given input @a i to a JSON value using the MessagePack
7677 serialization format.
7678
7679 The library maps MessagePack types to JSON value types as follows:
7680
7681 MessagePack type | JSON value type | first byte
7682 ---------------- | --------------- | ----------
7683 positive fixint | number_unsigned | 0x00..0x7F
7684 fixmap | object | 0x80..0x8F
7685 fixarray | array | 0x90..0x9F
7686 fixstr | string | 0xA0..0xBF
7687 nil | `null` | 0xC0
7688 false | `false` | 0xC2
7689 true | `true` | 0xC3
7690 float 32 | number_float | 0xCA
7691 float 64 | number_float | 0xCB
7692 uint 8 | number_unsigned | 0xCC
7693 uint 16 | number_unsigned | 0xCD
7694 uint 32 | number_unsigned | 0xCE
7695 uint 64 | number_unsigned | 0xCF
7696 int 8 | number_integer | 0xD0
7697 int 16 | number_integer | 0xD1
7698 int 32 | number_integer | 0xD2
7699 int 64 | number_integer | 0xD3
7700 str 8 | string | 0xD9
7701 str 16 | string | 0xDA
7702 str 32 | string | 0xDB
7703 array 16 | array | 0xDC
7704 array 32 | array | 0xDD
7705 map 16 | object | 0xDE
7706 map 32 | object | 0xDF
7707 bin 8 | binary | 0xC4
7708 bin 16 | binary | 0xC5
7709 bin 32 | binary | 0xC6
7710 ext 8 | binary | 0xC7
7711 ext 16 | binary | 0xC8
7712 ext 32 | binary | 0xC9
7713 fixext 1 | binary | 0xD4
7714 fixext 2 | binary | 0xD5
7715 fixext 4 | binary | 0xD6
7716 fixext 8 | binary | 0xD7
7717 fixext 16 | binary | 0xD8
7718 negative fixint | number_integer | 0xE0-0xFF
7719
7720 @note Any MessagePack output created @ref to_msgpack can be successfully
7721 parsed by @ref from_msgpack.
7722
7723 @param[in] i an input in MessagePack format convertible to an input
7724 adapter
7725 @param[in] strict whether to expect the input to be consumed until EOF
7726 (true by default)
7727 @param[in] allow_exceptions whether to throw exceptions in case of a
7728 parse error (optional, true by default)
7729
7730 @return deserialized JSON value; in case of a parse error and
7731 @a allow_exceptions set to `false`, the return value will be
7732 value_t::discarded.
7733
7734 @throw parse_error.110 if the given input ends prematurely or the end of
7735 file was not reached when @a strict was set to true
7736 @throw parse_error.112 if unsupported features from MessagePack were
7737 used in the given input @a i or if the input is not valid MessagePack
7738 @throw parse_error.113 if a string was expected as map key, but not found
7739
7740 @complexity Linear in the size of the input @a i.
7741
7742 @liveexample{The example shows the deserialization of a byte vector in
7743 MessagePack format to a JSON value.,from_msgpack}
7744
7745 @sa http://msgpack.org
7746 @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
7747 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
7748 related CBOR format
7749 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
7750 the related UBJSON format
7751 @sa see @ref from_bson(InputType&&, const bool, const bool) for
7752 the related BSON format
7753
7754 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
7755 consume input adapters, removed start_index parameter, and added
7756 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
7757 since 3.2.0
7758 */
7759 template<typename InputType>
7760 JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)7761 static basic_json from_msgpack(InputType&& i,
7762 const bool strict = true,
7763 const bool allow_exceptions = true)
7764 {
7765 basic_json result;
7766 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7767 auto ia = detail::input_adapter(std::forward<InputType>(i));
7768 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7769 return res ? result : basic_json(value_t::discarded);
7770 }
7771
7772 /*!
7773 @copydoc from_msgpack(InputType&&, const bool, const bool)
7774 */
7775 template<typename IteratorType>
7776 JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)7777 static basic_json from_msgpack(IteratorType first, IteratorType last,
7778 const bool strict = true,
7779 const bool allow_exceptions = true)
7780 {
7781 basic_json result;
7782 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7783 auto ia = detail::input_adapter(std::move(first), std::move(last));
7784 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7785 return res ? result : basic_json(value_t::discarded);
7786 }
7787
7788
7789 template<typename T>
7790 JSON_HEDLEY_WARN_UNUSED_RESULT
7791 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)7792 static basic_json from_msgpack(const T* ptr, std::size_t len,
7793 const bool strict = true,
7794 const bool allow_exceptions = true)
7795 {
7796 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
7797 }
7798
7799 JSON_HEDLEY_WARN_UNUSED_RESULT
7800 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)7801 static basic_json from_msgpack(detail::span_input_adapter&& i,
7802 const bool strict = true,
7803 const bool allow_exceptions = true)
7804 {
7805 basic_json result;
7806 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7807 auto ia = i.get();
7808 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
7809 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
7810 return res ? result : basic_json(value_t::discarded);
7811 }
7812
7813
7814 /*!
7815 @brief create a JSON value from an input in UBJSON format
7816
7817 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
7818 Binary JSON) serialization format.
7819
7820 The library maps UBJSON types to JSON value types as follows:
7821
7822 UBJSON type | JSON value type | marker
7823 ----------- | --------------------------------------- | ------
7824 no-op | *no value, next value is read* | `N`
7825 null | `null` | `Z`
7826 false | `false` | `F`
7827 true | `true` | `T`
7828 float32 | number_float | `d`
7829 float64 | number_float | `D`
7830 uint8 | number_unsigned | `U`
7831 int8 | number_integer | `i`
7832 int16 | number_integer | `I`
7833 int32 | number_integer | `l`
7834 int64 | number_integer | `L`
7835 high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
7836 string | string | `S`
7837 char | string | `C`
7838 array | array (optimized values are supported) | `[`
7839 object | object (optimized values are supported) | `{`
7840
7841 @note The mapping is **complete** in the sense that any UBJSON value can
7842 be converted to a JSON value.
7843
7844 @param[in] i an input in UBJSON format convertible to an input adapter
7845 @param[in] strict whether to expect the input to be consumed until EOF
7846 (true by default)
7847 @param[in] allow_exceptions whether to throw exceptions in case of a
7848 parse error (optional, true by default)
7849
7850 @return deserialized JSON value; in case of a parse error and
7851 @a allow_exceptions set to `false`, the return value will be
7852 value_t::discarded.
7853
7854 @throw parse_error.110 if the given input ends prematurely or the end of
7855 file was not reached when @a strict was set to true
7856 @throw parse_error.112 if a parse error occurs
7857 @throw parse_error.113 if a string could not be parsed successfully
7858
7859 @complexity Linear in the size of the input @a i.
7860
7861 @liveexample{The example shows the deserialization of a byte vector in
7862 UBJSON format to a JSON value.,from_ubjson}
7863
7864 @sa http://ubjson.org
7865 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
7866 analogous serialization
7867 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
7868 related CBOR format
7869 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
7870 the related MessagePack format
7871 @sa see @ref from_bson(InputType&&, const bool, const bool) for
7872 the related BSON format
7873
7874 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
7875 */
7876 template<typename InputType>
7877 JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)7878 static basic_json from_ubjson(InputType&& i,
7879 const bool strict = true,
7880 const bool allow_exceptions = true)
7881 {
7882 basic_json result;
7883 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7884 auto ia = detail::input_adapter(std::forward<InputType>(i));
7885 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7886 return res ? result : basic_json(value_t::discarded);
7887 }
7888
7889 /*!
7890 @copydoc from_ubjson(InputType&&, const bool, const bool)
7891 */
7892 template<typename IteratorType>
7893 JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)7894 static basic_json from_ubjson(IteratorType first, IteratorType last,
7895 const bool strict = true,
7896 const bool allow_exceptions = true)
7897 {
7898 basic_json result;
7899 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7900 auto ia = detail::input_adapter(std::move(first), std::move(last));
7901 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7902 return res ? result : basic_json(value_t::discarded);
7903 }
7904
7905 template<typename T>
7906 JSON_HEDLEY_WARN_UNUSED_RESULT
7907 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)7908 static basic_json from_ubjson(const T* ptr, std::size_t len,
7909 const bool strict = true,
7910 const bool allow_exceptions = true)
7911 {
7912 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
7913 }
7914
7915 JSON_HEDLEY_WARN_UNUSED_RESULT
7916 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)7917 static basic_json from_ubjson(detail::span_input_adapter&& i,
7918 const bool strict = true,
7919 const bool allow_exceptions = true)
7920 {
7921 basic_json result;
7922 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7923 auto ia = i.get();
7924 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
7925 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
7926 return res ? result : basic_json(value_t::discarded);
7927 }
7928
7929
7930 /*!
7931 @brief Create a JSON value from an input in BSON format
7932
7933 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
7934 serialization format.
7935
7936 The library maps BSON record types to JSON value types as follows:
7937
7938 BSON type | BSON marker byte | JSON value type
7939 --------------- | ---------------- | ---------------------------
7940 double | 0x01 | number_float
7941 string | 0x02 | string
7942 document | 0x03 | object
7943 array | 0x04 | array
7944 binary | 0x05 | binary
7945 undefined | 0x06 | still unsupported
7946 ObjectId | 0x07 | still unsupported
7947 boolean | 0x08 | boolean
7948 UTC Date-Time | 0x09 | still unsupported
7949 null | 0x0A | null
7950 Regular Expr. | 0x0B | still unsupported
7951 DB Pointer | 0x0C | still unsupported
7952 JavaScript Code | 0x0D | still unsupported
7953 Symbol | 0x0E | still unsupported
7954 JavaScript Code | 0x0F | still unsupported
7955 int32 | 0x10 | number_integer
7956 Timestamp | 0x11 | still unsupported
7957 128-bit decimal float | 0x13 | still unsupported
7958 Max Key | 0x7F | still unsupported
7959 Min Key | 0xFF | still unsupported
7960
7961 @warning The mapping is **incomplete**. The unsupported mappings
7962 are indicated in the table above.
7963
7964 @param[in] i an input in BSON format convertible to an input adapter
7965 @param[in] strict whether to expect the input to be consumed until EOF
7966 (true by default)
7967 @param[in] allow_exceptions whether to throw exceptions in case of a
7968 parse error (optional, true by default)
7969
7970 @return deserialized JSON value; in case of a parse error and
7971 @a allow_exceptions set to `false`, the return value will be
7972 value_t::discarded.
7973
7974 @throw parse_error.114 if an unsupported BSON record type is encountered
7975
7976 @complexity Linear in the size of the input @a i.
7977
7978 @liveexample{The example shows the deserialization of a byte vector in
7979 BSON format to a JSON value.,from_bson}
7980
7981 @sa http://bsonspec.org/spec.html
7982 @sa see @ref to_bson(const basic_json&) for the analogous serialization
7983 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
7984 related CBOR format
7985 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
7986 the related MessagePack format
7987 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
7988 related UBJSON format
7989 */
7990 template<typename InputType>
7991 JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)7992 static basic_json from_bson(InputType&& i,
7993 const bool strict = true,
7994 const bool allow_exceptions = true)
7995 {
7996 basic_json result;
7997 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
7998 auto ia = detail::input_adapter(std::forward<InputType>(i));
7999 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
8000 return res ? result : basic_json(value_t::discarded);
8001 }
8002
8003 /*!
8004 @copydoc from_bson(InputType&&, const bool, const bool)
8005 */
8006 template<typename IteratorType>
8007 JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)8008 static basic_json from_bson(IteratorType first, IteratorType last,
8009 const bool strict = true,
8010 const bool allow_exceptions = true)
8011 {
8012 basic_json result;
8013 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
8014 auto ia = detail::input_adapter(std::move(first), std::move(last));
8015 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
8016 return res ? result : basic_json(value_t::discarded);
8017 }
8018
8019 template<typename T>
8020 JSON_HEDLEY_WARN_UNUSED_RESULT
8021 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)8022 static basic_json from_bson(const T* ptr, std::size_t len,
8023 const bool strict = true,
8024 const bool allow_exceptions = true)
8025 {
8026 return from_bson(ptr, ptr + len, strict, allow_exceptions);
8027 }
8028
8029 JSON_HEDLEY_WARN_UNUSED_RESULT
8030 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)8031 static basic_json from_bson(detail::span_input_adapter&& i,
8032 const bool strict = true,
8033 const bool allow_exceptions = true)
8034 {
8035 basic_json result;
8036 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
8037 auto ia = i.get();
8038 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
8039 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
8040 return res ? result : basic_json(value_t::discarded);
8041 }
8042 /// @}
8043
8044 //////////////////////////
8045 // JSON Pointer support //
8046 //////////////////////////
8047
8048 /// @name JSON Pointer functions
8049 /// @{
8050
8051 /*!
8052 @brief access specified element via JSON Pointer
8053
8054 Uses a JSON pointer to retrieve a reference to the respective JSON value.
8055 No bound checking is performed. Similar to @ref operator[](const typename
8056 object_t::key_type&), `null` values are created in arrays and objects if
8057 necessary.
8058
8059 In particular:
8060 - If the JSON pointer points to an object key that does not exist, it
8061 is created an filled with a `null` value before a reference to it
8062 is returned.
8063 - If the JSON pointer points to an array index that does not exist, it
8064 is created an filled with a `null` value before a reference to it
8065 is returned. All indices between the current maximum and the given
8066 index are also filled with `null`.
8067 - The special value `-` is treated as a synonym for the index past the
8068 end.
8069
8070 @param[in] ptr a JSON pointer
8071
8072 @return reference to the element pointed to by @a ptr
8073
8074 @complexity Constant.
8075
8076 @throw parse_error.106 if an array index begins with '0'
8077 @throw parse_error.109 if an array index was not a number
8078 @throw out_of_range.404 if the JSON pointer can not be resolved
8079
8080 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
8081
8082 @since version 2.0.0
8083 */
operator [](const json_pointer & ptr)8084 reference operator[](const json_pointer& ptr)
8085 {
8086 return ptr.get_unchecked(this);
8087 }
8088
8089 /*!
8090 @brief access specified element via JSON Pointer
8091
8092 Uses a JSON pointer to retrieve a reference to the respective JSON value.
8093 No bound checking is performed. The function does not change the JSON
8094 value; no `null` values are created. In particular, the special value
8095 `-` yields an exception.
8096
8097 @param[in] ptr JSON pointer to the desired element
8098
8099 @return const reference to the element pointed to by @a ptr
8100
8101 @complexity Constant.
8102
8103 @throw parse_error.106 if an array index begins with '0'
8104 @throw parse_error.109 if an array index was not a number
8105 @throw out_of_range.402 if the array index '-' is used
8106 @throw out_of_range.404 if the JSON pointer can not be resolved
8107
8108 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
8109
8110 @since version 2.0.0
8111 */
operator [](const json_pointer & ptr) const8112 const_reference operator[](const json_pointer& ptr) const
8113 {
8114 return ptr.get_unchecked(this);
8115 }
8116
8117 /*!
8118 @brief access specified element via JSON Pointer
8119
8120 Returns a reference to the element at with specified JSON pointer @a ptr,
8121 with bounds checking.
8122
8123 @param[in] ptr JSON pointer to the desired element
8124
8125 @return reference to the element pointed to by @a ptr
8126
8127 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
8128 begins with '0'. See example below.
8129
8130 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
8131 is not a number. See example below.
8132
8133 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
8134 is out of range. See example below.
8135
8136 @throw out_of_range.402 if the array index '-' is used in the passed JSON
8137 pointer @a ptr. As `at` provides checked access (and no elements are
8138 implicitly inserted), the index '-' is always invalid. See example below.
8139
8140 @throw out_of_range.403 if the JSON pointer describes a key of an object
8141 which cannot be found. See example below.
8142
8143 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
8144 See example below.
8145
8146 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8147 changes in the JSON value.
8148
8149 @complexity Constant.
8150
8151 @since version 2.0.0
8152
8153 @liveexample{The behavior is shown in the example.,at_json_pointer}
8154 */
at(const json_pointer & ptr)8155 reference at(const json_pointer& ptr)
8156 {
8157 return ptr.get_checked(this);
8158 }
8159
8160 /*!
8161 @brief access specified element via JSON Pointer
8162
8163 Returns a const reference to the element at with specified JSON pointer @a
8164 ptr, with bounds checking.
8165
8166 @param[in] ptr JSON pointer to the desired element
8167
8168 @return reference to the element pointed to by @a ptr
8169
8170 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
8171 begins with '0'. See example below.
8172
8173 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
8174 is not a number. See example below.
8175
8176 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
8177 is out of range. See example below.
8178
8179 @throw out_of_range.402 if the array index '-' is used in the passed JSON
8180 pointer @a ptr. As `at` provides checked access (and no elements are
8181 implicitly inserted), the index '-' is always invalid. See example below.
8182
8183 @throw out_of_range.403 if the JSON pointer describes a key of an object
8184 which cannot be found. See example below.
8185
8186 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
8187 See example below.
8188
8189 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8190 changes in the JSON value.
8191
8192 @complexity Constant.
8193
8194 @since version 2.0.0
8195
8196 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
8197 */
at(const json_pointer & ptr) const8198 const_reference at(const json_pointer& ptr) const
8199 {
8200 return ptr.get_checked(this);
8201 }
8202
8203 /*!
8204 @brief return flattened JSON value
8205
8206 The function creates a JSON object whose keys are JSON pointers (see [RFC
8207 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
8208 primitive. The original JSON value can be restored using the @ref
8209 unflatten() function.
8210
8211 @return an object that maps JSON pointers to primitive values
8212
8213 @note Empty objects and arrays are flattened to `null` and will not be
8214 reconstructed correctly by the @ref unflatten() function.
8215
8216 @complexity Linear in the size the JSON value.
8217
8218 @liveexample{The following code shows how a JSON object is flattened to an
8219 object whose keys consist of JSON pointers.,flatten}
8220
8221 @sa see @ref unflatten() for the reverse function
8222
8223 @since version 2.0.0
8224 */
flatten() const8225 basic_json flatten() const
8226 {
8227 basic_json result(value_t::object);
8228 json_pointer::flatten("", *this, result);
8229 return result;
8230 }
8231
8232 /*!
8233 @brief unflatten a previously flattened JSON value
8234
8235 The function restores the arbitrary nesting of a JSON value that has been
8236 flattened before using the @ref flatten() function. The JSON value must
8237 meet certain constraints:
8238 1. The value must be an object.
8239 2. The keys must be JSON pointers (see
8240 [RFC 6901](https://tools.ietf.org/html/rfc6901))
8241 3. The mapped values must be primitive JSON types.
8242
8243 @return the original JSON from a flattened version
8244
8245 @note Empty objects and arrays are flattened by @ref flatten() to `null`
8246 values and can not unflattened to their original type. Apart from
8247 this example, for a JSON value `j`, the following is always true:
8248 `j == j.flatten().unflatten()`.
8249
8250 @complexity Linear in the size the JSON value.
8251
8252 @throw type_error.314 if value is not an object
8253 @throw type_error.315 if object values are not primitive
8254
8255 @liveexample{The following code shows how a flattened JSON object is
8256 unflattened into the original nested JSON object.,unflatten}
8257
8258 @sa see @ref flatten() for the reverse function
8259
8260 @since version 2.0.0
8261 */
unflatten() const8262 basic_json unflatten() const
8263 {
8264 return json_pointer::unflatten(*this);
8265 }
8266
8267 /// @}
8268
8269 //////////////////////////
8270 // JSON Patch functions //
8271 //////////////////////////
8272
8273 /// @name JSON Patch functions
8274 /// @{
8275
8276 /*!
8277 @brief applies a JSON patch
8278
8279 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
8280 expressing a sequence of operations to apply to a JSON) document. With
8281 this function, a JSON Patch is applied to the current JSON value by
8282 executing all operations from the patch.
8283
8284 @param[in] json_patch JSON patch document
8285 @return patched document
8286
8287 @note The application of a patch is atomic: Either all operations succeed
8288 and the patched document is returned or an exception is thrown. In
8289 any case, the original value is not changed: the patch is applied
8290 to a copy of the value.
8291
8292 @throw parse_error.104 if the JSON patch does not consist of an array of
8293 objects
8294
8295 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
8296 attributes are missing); example: `"operation add must have member path"`
8297
8298 @throw out_of_range.401 if an array index is out of range.
8299
8300 @throw out_of_range.403 if a JSON pointer inside the patch could not be
8301 resolved successfully in the current JSON value; example: `"key baz not
8302 found"`
8303
8304 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
8305 "move")
8306
8307 @throw other_error.501 if "test" operation was unsuccessful
8308
8309 @complexity Linear in the size of the JSON value and the length of the
8310 JSON patch. As usually only a fraction of the JSON value is affected by
8311 the patch, the complexity can usually be neglected.
8312
8313 @liveexample{The following code shows how a JSON patch is applied to a
8314 value.,patch}
8315
8316 @sa see @ref diff -- create a JSON patch by comparing two JSON values
8317
8318 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
8319 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
8320
8321 @since version 2.0.0
8322 */
patch(const basic_json & json_patch) const8323 basic_json patch(const basic_json& json_patch) const
8324 {
8325 // make a working copy to apply the patch to
8326 basic_json result = *this;
8327
8328 // the valid JSON Patch operations
8329 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
8330
8331 const auto get_op = [](const std::string & op)
8332 {
8333 if (op == "add")
8334 {
8335 return patch_operations::add;
8336 }
8337 if (op == "remove")
8338 {
8339 return patch_operations::remove;
8340 }
8341 if (op == "replace")
8342 {
8343 return patch_operations::replace;
8344 }
8345 if (op == "move")
8346 {
8347 return patch_operations::move;
8348 }
8349 if (op == "copy")
8350 {
8351 return patch_operations::copy;
8352 }
8353 if (op == "test")
8354 {
8355 return patch_operations::test;
8356 }
8357
8358 return patch_operations::invalid;
8359 };
8360
8361 // wrapper for "add" operation; add value at ptr
8362 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
8363 {
8364 // adding to the root of the target document means replacing it
8365 if (ptr.empty())
8366 {
8367 result = val;
8368 return;
8369 }
8370
8371 // make sure the top element of the pointer exists
8372 json_pointer top_pointer = ptr.top();
8373 if (top_pointer != ptr)
8374 {
8375 result.at(top_pointer);
8376 }
8377
8378 // get reference to parent of JSON pointer ptr
8379 const auto last_path = ptr.back();
8380 ptr.pop_back();
8381 basic_json& parent = result[ptr];
8382
8383 switch (parent.m_type)
8384 {
8385 case value_t::null:
8386 case value_t::object:
8387 {
8388 // use operator[] to add value
8389 parent[last_path] = val;
8390 break;
8391 }
8392
8393 case value_t::array:
8394 {
8395 if (last_path == "-")
8396 {
8397 // special case: append to back
8398 parent.push_back(val);
8399 }
8400 else
8401 {
8402 const auto idx = json_pointer::array_index(last_path);
8403 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
8404 {
8405 // avoid undefined behavior
8406 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
8407 }
8408
8409 // default case: insert add offset
8410 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
8411 }
8412 break;
8413 }
8414
8415 // if there exists a parent it cannot be primitive
8416 default: // LCOV_EXCL_LINE
8417 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8418 }
8419 };
8420
8421 // wrapper for "remove" operation; remove value at ptr
8422 const auto operation_remove = [this, &result](json_pointer & ptr)
8423 {
8424 // get reference to parent of JSON pointer ptr
8425 const auto last_path = ptr.back();
8426 ptr.pop_back();
8427 basic_json& parent = result.at(ptr);
8428
8429 // remove child
8430 if (parent.is_object())
8431 {
8432 // perform range check
8433 auto it = parent.find(last_path);
8434 if (JSON_HEDLEY_LIKELY(it != parent.end()))
8435 {
8436 parent.erase(it);
8437 }
8438 else
8439 {
8440 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
8441 }
8442 }
8443 else if (parent.is_array())
8444 {
8445 // note erase performs range check
8446 parent.erase(json_pointer::array_index(last_path));
8447 }
8448 };
8449
8450 // type check: top level value must be an array
8451 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
8452 {
8453 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
8454 }
8455
8456 // iterate and apply the operations
8457 for (const auto& val : json_patch)
8458 {
8459 // wrapper to get a value for an operation
8460 const auto get_value = [&val](const std::string & op,
8461 const std::string & member,
8462 bool string_type) -> basic_json &
8463 {
8464 // find value
8465 auto it = val.m_value.object->find(member);
8466
8467 // context-sensitive error message
8468 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
8469
8470 // check if desired value is present
8471 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
8472 {
8473 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
8474 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
8475 }
8476
8477 // check if result is of type string
8478 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
8479 {
8480 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
8481 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
8482 }
8483
8484 // no error: return value
8485 return it->second;
8486 };
8487
8488 // type check: every element of the array must be an object
8489 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
8490 {
8491 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
8492 }
8493
8494 // collect mandatory members
8495 const auto op = get_value("op", "op", true).template get<std::string>();
8496 const auto path = get_value(op, "path", true).template get<std::string>();
8497 json_pointer ptr(path);
8498
8499 switch (get_op(op))
8500 {
8501 case patch_operations::add:
8502 {
8503 operation_add(ptr, get_value("add", "value", false));
8504 break;
8505 }
8506
8507 case patch_operations::remove:
8508 {
8509 operation_remove(ptr);
8510 break;
8511 }
8512
8513 case patch_operations::replace:
8514 {
8515 // the "path" location must exist - use at()
8516 result.at(ptr) = get_value("replace", "value", false);
8517 break;
8518 }
8519
8520 case patch_operations::move:
8521 {
8522 const auto from_path = get_value("move", "from", true).template get<std::string>();
8523 json_pointer from_ptr(from_path);
8524
8525 // the "from" location must exist - use at()
8526 basic_json v = result.at(from_ptr);
8527
8528 // The move operation is functionally identical to a
8529 // "remove" operation on the "from" location, followed
8530 // immediately by an "add" operation at the target
8531 // location with the value that was just removed.
8532 operation_remove(from_ptr);
8533 operation_add(ptr, v);
8534 break;
8535 }
8536
8537 case patch_operations::copy:
8538 {
8539 const auto from_path = get_value("copy", "from", true).template get<std::string>();
8540 const json_pointer from_ptr(from_path);
8541
8542 // the "from" location must exist - use at()
8543 basic_json v = result.at(from_ptr);
8544
8545 // The copy is functionally identical to an "add"
8546 // operation at the target location using the value
8547 // specified in the "from" member.
8548 operation_add(ptr, v);
8549 break;
8550 }
8551
8552 case patch_operations::test:
8553 {
8554 bool success = false;
8555 JSON_TRY
8556 {
8557 // check if "value" matches the one at "path"
8558 // the "path" location must exist - use at()
8559 success = (result.at(ptr) == get_value("test", "value", false));
8560 }
8561 JSON_INTERNAL_CATCH (out_of_range&)
8562 {
8563 // ignore out of range errors: success remains false
8564 }
8565
8566 // throw an exception if test fails
8567 if (JSON_HEDLEY_UNLIKELY(!success))
8568 {
8569 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
8570 }
8571
8572 break;
8573 }
8574
8575 default:
8576 {
8577 // op must be "add", "remove", "replace", "move", "copy", or
8578 // "test"
8579 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
8580 }
8581 }
8582 }
8583
8584 return result;
8585 }
8586
8587 /*!
8588 @brief creates a diff as a JSON patch
8589
8590 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
8591 be changed into the value @a target by calling @ref patch function.
8592
8593 @invariant For two JSON values @a source and @a target, the following code
8594 yields always `true`:
8595 @code {.cpp}
8596 source.patch(diff(source, target)) == target;
8597 @endcode
8598
8599 @note Currently, only `remove`, `add`, and `replace` operations are
8600 generated.
8601
8602 @param[in] source JSON value to compare from
8603 @param[in] target JSON value to compare against
8604 @param[in] path helper value to create JSON pointers
8605
8606 @return a JSON patch to convert the @a source to @a target
8607
8608 @complexity Linear in the lengths of @a source and @a target.
8609
8610 @liveexample{The following code shows how a JSON patch is created as a
8611 diff for two JSON values.,diff}
8612
8613 @sa see @ref patch -- apply a JSON patch
8614 @sa see @ref merge_patch -- apply a JSON Merge Patch
8615
8616 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
8617
8618 @since version 2.0.0
8619 */
8620 JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")8621 static basic_json diff(const basic_json& source, const basic_json& target,
8622 const std::string& path = "")
8623 {
8624 // the patch
8625 basic_json result(value_t::array);
8626
8627 // if the values are the same, return empty patch
8628 if (source == target)
8629 {
8630 return result;
8631 }
8632
8633 if (source.type() != target.type())
8634 {
8635 // different types: replace value
8636 result.push_back(
8637 {
8638 {"op", "replace"}, {"path", path}, {"value", target}
8639 });
8640 return result;
8641 }
8642
8643 switch (source.type())
8644 {
8645 case value_t::array:
8646 {
8647 // first pass: traverse common elements
8648 std::size_t i = 0;
8649 while (i < source.size() && i < target.size())
8650 {
8651 // recursive call to compare array values at index i
8652 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
8653 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
8654 ++i;
8655 }
8656
8657 // i now reached the end of at least one array
8658 // in a second pass, traverse the remaining elements
8659
8660 // remove my remaining elements
8661 const auto end_index = static_cast<difference_type>(result.size());
8662 while (i < source.size())
8663 {
8664 // add operations in reverse order to avoid invalid
8665 // indices
8666 result.insert(result.begin() + end_index, object(
8667 {
8668 {"op", "remove"},
8669 {"path", path + "/" + std::to_string(i)}
8670 }));
8671 ++i;
8672 }
8673
8674 // add other remaining elements
8675 while (i < target.size())
8676 {
8677 result.push_back(
8678 {
8679 {"op", "add"},
8680 {"path", path + "/-"},
8681 {"value", target[i]}
8682 });
8683 ++i;
8684 }
8685
8686 break;
8687 }
8688
8689 case value_t::object:
8690 {
8691 // first pass: traverse this object's elements
8692 for (auto it = source.cbegin(); it != source.cend(); ++it)
8693 {
8694 // escape the key name to be used in a JSON patch
8695 const auto path_key = path + "/" + detail::escape(it.key());
8696
8697 if (target.find(it.key()) != target.end())
8698 {
8699 // recursive call to compare object values at key it
8700 auto temp_diff = diff(it.value(), target[it.key()], path_key);
8701 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
8702 }
8703 else
8704 {
8705 // found a key that is not in o -> remove it
8706 result.push_back(object(
8707 {
8708 {"op", "remove"}, {"path", path_key}
8709 }));
8710 }
8711 }
8712
8713 // second pass: traverse other object's elements
8714 for (auto it = target.cbegin(); it != target.cend(); ++it)
8715 {
8716 if (source.find(it.key()) == source.end())
8717 {
8718 // found a key that is not in this -> add it
8719 const auto path_key = path + "/" + detail::escape(it.key());
8720 result.push_back(
8721 {
8722 {"op", "add"}, {"path", path_key},
8723 {"value", it.value()}
8724 });
8725 }
8726 }
8727
8728 break;
8729 }
8730
8731 default:
8732 {
8733 // both primitive type: replace value
8734 result.push_back(
8735 {
8736 {"op", "replace"}, {"path", path}, {"value", target}
8737 });
8738 break;
8739 }
8740 }
8741
8742 return result;
8743 }
8744
8745 /// @}
8746
8747 ////////////////////////////////
8748 // JSON Merge Patch functions //
8749 ////////////////////////////////
8750
8751 /// @name JSON Merge Patch functions
8752 /// @{
8753
8754 /*!
8755 @brief applies a JSON Merge Patch
8756
8757 The merge patch format is primarily intended for use with the HTTP PATCH
8758 method as a means of describing a set of modifications to a target
8759 resource's content. This function applies a merge patch to the current
8760 JSON value.
8761
8762 The function implements the following algorithm from Section 2 of
8763 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
8764
8765 ```
8766 define MergePatch(Target, Patch):
8767 if Patch is an Object:
8768 if Target is not an Object:
8769 Target = {} // Ignore the contents and set it to an empty Object
8770 for each Name/Value pair in Patch:
8771 if Value is null:
8772 if Name exists in Target:
8773 remove the Name/Value pair from Target
8774 else:
8775 Target[Name] = MergePatch(Target[Name], Value)
8776 return Target
8777 else:
8778 return Patch
8779 ```
8780
8781 Thereby, `Target` is the current object; that is, the patch is applied to
8782 the current value.
8783
8784 @param[in] apply_patch the patch to apply
8785
8786 @complexity Linear in the lengths of @a patch.
8787
8788 @liveexample{The following code shows how a JSON Merge Patch is applied to
8789 a JSON document.,merge_patch}
8790
8791 @sa see @ref patch -- apply a JSON patch
8792 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
8793
8794 @since version 3.0.0
8795 */
merge_patch(const basic_json & apply_patch)8796 void merge_patch(const basic_json& apply_patch)
8797 {
8798 if (apply_patch.is_object())
8799 {
8800 if (!is_object())
8801 {
8802 *this = object();
8803 }
8804 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
8805 {
8806 if (it.value().is_null())
8807 {
8808 erase(it.key());
8809 }
8810 else
8811 {
8812 operator[](it.key()).merge_patch(it.value());
8813 }
8814 }
8815 }
8816 else
8817 {
8818 *this = apply_patch;
8819 }
8820 }
8821
8822 /// @}
8823 };
8824
8825 /*!
8826 @brief user-defined to_string function for JSON values
8827
8828 This function implements a user-defined to_string for JSON objects.
8829
8830 @param[in] j a JSON object
8831 @return a std::string object
8832 */
8833
8834 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)8835 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
8836 {
8837 return j.dump();
8838 }
8839 } // namespace nlohmann
8840
8841 ///////////////////////
8842 // nonmember support //
8843 ///////////////////////
8844
8845 // specialization of std::swap, and std::hash
8846 namespace std
8847 {
8848
8849 /// hash value for JSON objects
8850 template<>
8851 struct hash<nlohmann::json>
8852 {
8853 /*!
8854 @brief return a hash value for a JSON object
8855
8856 @since version 1.0.0
8857 */
operator ()std::hash8858 std::size_t operator()(const nlohmann::json& j) const
8859 {
8860 return nlohmann::detail::hash(j);
8861 }
8862 };
8863
8864 /// specialization for std::less<value_t>
8865 /// @note: do not remove the space after '<',
8866 /// see https://github.com/nlohmann/json/pull/679
8867 template<>
8868 struct less<::nlohmann::detail::value_t>
8869 {
8870 /*!
8871 @brief compare two value_t enum values
8872 @since version 3.0.0
8873 */
operator ()std::less8874 bool operator()(nlohmann::detail::value_t lhs,
8875 nlohmann::detail::value_t rhs) const noexcept
8876 {
8877 return nlohmann::detail::operator<(lhs, rhs);
8878 }
8879 };
8880
8881 // C++20 prohibit function specialization in the std namespace.
8882 #ifndef JSON_HAS_CPP_20
8883
8884 /*!
8885 @brief exchanges the values of two JSON objects
8886
8887 @since version 1.0.0
8888 */
8889 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)8890 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
8891 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
8892 is_nothrow_move_assignable<nlohmann::json>::value
8893 )
8894 {
8895 j1.swap(j2);
8896 }
8897
8898 #endif
8899
8900 } // namespace std
8901
8902 /*!
8903 @brief user-defined string literal for JSON values
8904
8905 This operator implements a user-defined string literal for JSON objects. It
8906 can be used by adding `"_json"` to a string literal and returns a JSON object
8907 if no parse error occurred.
8908
8909 @param[in] s a string representation of a JSON object
8910 @param[in] n the length of string @a s
8911 @return a JSON object
8912
8913 @since version 1.0.0
8914 */
8915 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)8916 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
8917 {
8918 return nlohmann::json::parse(s, s + n);
8919 }
8920
8921 /*!
8922 @brief user-defined string literal for JSON pointer
8923
8924 This operator implements a user-defined string literal for JSON Pointers. It
8925 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
8926 object if no parse error occurred.
8927
8928 @param[in] s a string representation of a JSON Pointer
8929 @param[in] n the length of string @a s
8930 @return a JSON pointer object
8931
8932 @since version 2.0.0
8933 */
8934 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)8935 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
8936 {
8937 return nlohmann::json::json_pointer(std::string(s, n));
8938 }
8939
8940 #include <nlohmann/detail/macro_unscope.hpp>
8941
8942 #endif // INCLUDE_NLOHMANN_JSON_HPP_
8943