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