1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.2.0
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-2018 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 NLOHMANN_JSON_HPP
31 #define NLOHMANN_JSON_HPP
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 2
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <ciso646> // and, not, or
40 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
41 #include <functional> // hash, less
42 #include <initializer_list> // initializer_list
43 #include <iosfwd> // istream, ostream
44 #include <iterator> // iterator_traits, random_access_iterator_tag
45 #include <numeric> // accumulate
46 #include <string> // string, stoi, to_string
47 #include <utility> // declval, forward, move, pair, swap
48
49 // #include <nlohmann/json_fwd.hpp>
50 #ifndef NLOHMANN_JSON_FWD_HPP
51 #define NLOHMANN_JSON_FWD_HPP
52
53 #include <cstdint> // int64_t, uint64_t
54 #include <map> // map
55 #include <memory> // allocator
56 #include <string> // string
57 #include <vector> // vector
58
59 /*!
60 @brief namespace for Niels Lohmann
61 @see https://github.com/nlohmann
62 @since version 1.0.0
63 */
64 namespace nlohmann
65 {
66 /*!
67 @brief default JSONSerializer template argument
68
69 This serializer ignores the template arguments and uses ADL
70 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
71 for serialization.
72 */
73 template<typename T = void, typename SFINAE = void>
74 struct adl_serializer;
75
76 template<template<typename U, typename V, typename... Args> class ObjectType =
77 std::map,
78 template<typename U, typename... Args> class ArrayType = std::vector,
79 class StringType = std::string, class BooleanType = bool,
80 class NumberIntegerType = std::int64_t,
81 class NumberUnsignedType = std::uint64_t,
82 class NumberFloatType = double,
83 template<typename U> class AllocatorType = std::allocator,
84 template<typename T, typename SFINAE = void> class JSONSerializer =
85 adl_serializer>
86 class basic_json;
87
88 /*!
89 @brief JSON Pointer
90
91 A JSON pointer defines a string syntax for identifying a specific value
92 within a JSON document. It can be used with functions `at` and
93 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
94
95 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
96
97 @since version 2.0.0
98 */
99 template<typename BasicJsonType>
100 class json_pointer;
101
102 /*!
103 @brief default JSON class
104
105 This type is the default specialization of the @ref basic_json class which
106 uses the standard template types.
107
108 @since version 1.0.0
109 */
110 using json = basic_json<>;
111 }
112
113 #endif
114
115 // #include <nlohmann/detail/macro_scope.hpp>
116
117
118 // This file contains all internal macro definitions
119 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
120
121 // exclude unsupported compilers
122 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
123 #if defined(__clang__)
124 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
125 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
126 #endif
127 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
128 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
129 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
130 #endif
131 #endif
132 #endif
133
134 // disable float-equal warnings on GCC/clang
135 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
136 #pragma GCC diagnostic push
137 #pragma GCC diagnostic ignored "-Wfloat-equal"
138 #endif
139
140 // disable documentation warnings on clang
141 #if defined(__clang__)
142 #pragma GCC diagnostic push
143 #pragma GCC diagnostic ignored "-Wdocumentation"
144 #endif
145
146 // allow for portable deprecation warnings
147 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
148 #define JSON_DEPRECATED __attribute__((deprecated))
149 #elif defined(_MSC_VER)
150 #define JSON_DEPRECATED __declspec(deprecated)
151 #else
152 #define JSON_DEPRECATED
153 #endif
154
155 // allow to disable exceptions
156 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
157 #define JSON_THROW(exception) throw exception
158 #define JSON_TRY try
159 #define JSON_CATCH(exception) catch(exception)
160 #define JSON_INTERNAL_CATCH(exception) catch(exception)
161 #else
162 #define JSON_THROW(exception) std::abort()
163 #define JSON_TRY if(true)
164 #define JSON_CATCH(exception) if(false)
165 #define JSON_INTERNAL_CATCH(exception) if(false)
166 #endif
167
168 // override exception macros
169 #if defined(JSON_THROW_USER)
170 #undef JSON_THROW
171 #define JSON_THROW JSON_THROW_USER
172 #endif
173 #if defined(JSON_TRY_USER)
174 #undef JSON_TRY
175 #define JSON_TRY JSON_TRY_USER
176 #endif
177 #if defined(JSON_CATCH_USER)
178 #undef JSON_CATCH
179 #define JSON_CATCH JSON_CATCH_USER
180 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
181 #endif
182 #if defined(JSON_INTERNAL_CATCH_USER)
183 #undef JSON_INTERNAL_CATCH
184 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
185 #endif
186
187 // manual branch prediction
188 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
189 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
190 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
191 #else
192 #define JSON_LIKELY(x) x
193 #define JSON_UNLIKELY(x) x
194 #endif
195
196 // C++ language standard detection
197 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
198 #define JSON_HAS_CPP_17
199 #define JSON_HAS_CPP_14
200 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
201 #define JSON_HAS_CPP_14
202 #endif
203
204 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
205 // may be removed in the future once the class is split.
206
207 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
208 template<template<typename, typename, typename...> class ObjectType, \
209 template<typename, typename...> class ArrayType, \
210 class StringType, class BooleanType, class NumberIntegerType, \
211 class NumberUnsignedType, class NumberFloatType, \
212 template<typename> class AllocatorType, \
213 template<typename, typename = void> class JSONSerializer>
214
215 #define NLOHMANN_BASIC_JSON_TPL \
216 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
217 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
218 AllocatorType, JSONSerializer>
219
220 /*!
221 @brief Helper to determine whether there's a key_type for T.
222
223 This helper is used to tell associative containers apart from other containers
224 such as sequence containers. For instance, `std::map` passes the test as it
225 contains a `mapped_type`, whereas `std::vector` fails the test.
226
227 @sa http://stackoverflow.com/a/7728728/266378
228 @since version 1.0.0, overworked in version 2.0.6
229 */
230 #define NLOHMANN_JSON_HAS_HELPER(type) \
231 template<typename T> struct has_##type { \
232 private: \
233 template<typename U, typename = typename U::type> \
234 static int detect(U &&); \
235 static void detect(...); \
236 public: \
237 static constexpr bool value = \
238 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
239 }
240
241 // #include <nlohmann/detail/meta/cpp_future.hpp>
242
243
244 #include <ciso646> // not
245 #include <cstddef> // size_t
246 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
247
248 namespace nlohmann
249 {
250 namespace detail
251 {
252 // alias templates to reduce boilerplate
253 template<bool B, typename T = void>
254 using enable_if_t = typename std::enable_if<B, T>::type;
255
256 template<typename T>
257 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
258
259 // implementation of C++14 index_sequence and affiliates
260 // source: https://stackoverflow.com/a/32223343
261 template<std::size_t... Ints>
262 struct index_sequence
263 {
264 using type = index_sequence;
265 using value_type = std::size_t;
sizenlohmann::detail::index_sequence266 static constexpr std::size_t size() noexcept
267 {
268 return sizeof...(Ints);
269 }
270 };
271
272 template<class Sequence1, class Sequence2>
273 struct merge_and_renumber;
274
275 template<std::size_t... I1, std::size_t... I2>
276 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
277 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
278
279 template<std::size_t N>
280 struct make_index_sequence
281 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
282 typename make_index_sequence < N - N / 2 >::type > {};
283
284 template<> struct make_index_sequence<0> : index_sequence<> {};
285 template<> struct make_index_sequence<1> : index_sequence<0> {};
286
287 template<typename... Ts>
288 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
289
290 /*
291 Implementation of two C++17 constructs: conjunction, negation. This is needed
292 to avoid evaluating all the traits in a condition
293
294 For example: not std::is_same<void, T>::value and has_value_type<T>::value
295 will not compile when T = void (on MSVC at least). Whereas
296 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
297 stop evaluating if negation<...>::value == false
298
299 Please note that those constructs must be used with caution, since symbols can
300 become very long quickly (which can slow down compilation and cause MSVC
301 internal compiler errors). Only use it when you have to (see example ahead).
302 */
303 template<class...> struct conjunction : std::true_type {};
304 template<class B1> struct conjunction<B1> : B1 {};
305 template<class B1, class... Bn>
306 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
307
308 template<class B> struct negation : std::integral_constant<bool, not B::value> {};
309
310 // dispatch utility (taken from ranges-v3)
311 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
312 template<> struct priority_tag<0> {};
313
314 // taken from ranges-v3
315 template<typename T>
316 struct static_const
317 {
318 static constexpr T value{};
319 };
320
321 template<typename T>
322 constexpr T static_const<T>::value;
323 }
324 }
325
326 // #include <nlohmann/detail/meta/type_traits.hpp>
327
328
329 #include <ciso646> // not
330 #include <limits> // numeric_limits
331 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
332 #include <utility> // declval
333
334 // #include <nlohmann/json_fwd.hpp>
335
336 // #include <nlohmann/detail/meta/cpp_future.hpp>
337
338 // #include <nlohmann/detail/macro_scope.hpp>
339
340
341 namespace nlohmann
342 {
343 /*!
344 @brief detail namespace with internal helper functions
345
346 This namespace collects functions that should not be exposed,
347 implementations of some @ref basic_json methods, and meta-programming helpers.
348
349 @since version 2.1.0
350 */
351 namespace detail
352 {
353 /////////////
354 // helpers //
355 /////////////
356
357 template<typename> struct is_basic_json : std::false_type {};
358
359 NLOHMANN_BASIC_JSON_TPL_DECLARATION
360 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
361
362 ////////////////////////
363 // has_/is_ functions //
364 ////////////////////////
365
366 // source: https://stackoverflow.com/a/37193089/4116453
367
368 template <typename T, typename = void>
369 struct is_complete_type : std::false_type {};
370
371 template <typename T>
372 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
373
374 NLOHMANN_JSON_HAS_HELPER(mapped_type);
375 NLOHMANN_JSON_HAS_HELPER(key_type);
376 NLOHMANN_JSON_HAS_HELPER(value_type);
377 NLOHMANN_JSON_HAS_HELPER(iterator);
378
379 template<bool B, class RealType, class CompatibleObjectType>
380 struct is_compatible_object_type_impl : std::false_type {};
381
382 template<class RealType, class CompatibleObjectType>
383 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
384 {
385 static constexpr auto value =
386 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
387 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
388 };
389
390 template<bool B, class RealType, class CompatibleStringType>
391 struct is_compatible_string_type_impl : std::false_type {};
392
393 template<class RealType, class CompatibleStringType>
394 struct is_compatible_string_type_impl<true, RealType, CompatibleStringType>
395 {
396 static constexpr auto value =
397 std::is_same<typename RealType::value_type, typename CompatibleStringType::value_type>::value and
398 std::is_constructible<RealType, CompatibleStringType>::value;
399 };
400
401 template<class BasicJsonType, class CompatibleObjectType>
402 struct is_compatible_object_type
403 {
404 static auto constexpr value = is_compatible_object_type_impl <
405 conjunction<negation<std::is_same<void, CompatibleObjectType>>,
406 has_mapped_type<CompatibleObjectType>,
407 has_key_type<CompatibleObjectType>>::value,
408 typename BasicJsonType::object_t, CompatibleObjectType >::value;
409 };
410
411 template<class BasicJsonType, class CompatibleStringType>
412 struct is_compatible_string_type
413 {
414 static auto constexpr value = is_compatible_string_type_impl <
415 conjunction<negation<std::is_same<void, CompatibleStringType>>,
416 has_value_type<CompatibleStringType>>::value,
417 typename BasicJsonType::string_t, CompatibleStringType >::value;
418 };
419
420 template<typename BasicJsonType, typename T>
421 struct is_basic_json_nested_type
422 {
423 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
424 std::is_same<T, typename BasicJsonType::const_iterator>::value or
425 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
426 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
427 };
428
429 template<class BasicJsonType, class CompatibleArrayType>
430 struct is_compatible_array_type
431 {
432 static auto constexpr value =
433 conjunction<negation<std::is_same<void, CompatibleArrayType>>,
434 negation<is_compatible_object_type<
435 BasicJsonType, CompatibleArrayType>>,
436 negation<std::is_constructible<typename BasicJsonType::string_t,
437 CompatibleArrayType>>,
438 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
439 has_value_type<CompatibleArrayType>,
440 has_iterator<CompatibleArrayType>>::value;
441 };
442
443 template<bool, typename, typename>
444 struct is_compatible_integer_type_impl : std::false_type {};
445
446 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
447 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
448 {
449 // is there an assert somewhere on overflows?
450 using RealLimits = std::numeric_limits<RealIntegerType>;
451 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
452
453 static constexpr auto value =
454 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
455 CompatibleLimits::is_integer and
456 RealLimits::is_signed == CompatibleLimits::is_signed;
457 };
458
459 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
460 struct is_compatible_integer_type
461 {
462 static constexpr auto value =
463 is_compatible_integer_type_impl <
464 std::is_integral<CompatibleNumberIntegerType>::value and
465 not std::is_same<bool, CompatibleNumberIntegerType>::value,
466 RealIntegerType, CompatibleNumberIntegerType > ::value;
467 };
468
469 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
470 template<typename BasicJsonType, typename T>
471 struct has_from_json
472 {
473 private:
474 // also check the return type of from_json
475 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
476 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
477 static int detect(U&&);
478 static void detect(...);
479
480 public:
481 static constexpr bool value = std::is_integral<decltype(
482 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
483 };
484
485 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
486 // this overload is used for non-default-constructible user-defined-types
487 template<typename BasicJsonType, typename T>
488 struct has_non_default_from_json
489 {
490 private:
491 template <
492 typename U,
493 typename = enable_if_t<std::is_same<
494 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
495 static int detect(U&&);
496 static void detect(...);
497
498 public:
499 static constexpr bool value = std::is_integral<decltype(detect(
500 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
501 };
502
503 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
504 template<typename BasicJsonType, typename T>
505 struct has_to_json
506 {
507 private:
508 template<typename U, typename = decltype(uncvref_t<U>::to_json(
509 std::declval<BasicJsonType&>(), std::declval<T>()))>
510 static int detect(U&&);
511 static void detect(...);
512
513 public:
514 static constexpr bool value = std::is_integral<decltype(detect(
515 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
516 };
517
518 template <typename BasicJsonType, typename CompatibleCompleteType>
519 struct is_compatible_complete_type
520 {
521 static constexpr bool value =
522 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
523 not is_basic_json<CompatibleCompleteType>::value and
524 not is_basic_json_nested_type<BasicJsonType, CompatibleCompleteType>::value and
525 has_to_json<BasicJsonType, CompatibleCompleteType>::value;
526 };
527
528 template <typename BasicJsonType, typename CompatibleType>
529 struct is_compatible_type
530 : conjunction<is_complete_type<CompatibleType>,
531 is_compatible_complete_type<BasicJsonType, CompatibleType>>
532 {
533 };
534 }
535 }
536
537 // #include <nlohmann/detail/exceptions.hpp>
538
539
540 #include <exception> // exception
541 #include <stdexcept> // runtime_error
542 #include <string> // to_string
543
544 namespace nlohmann
545 {
546 namespace detail
547 {
548 ////////////////
549 // exceptions //
550 ////////////////
551
552 /*!
553 @brief general exception of the @ref basic_json class
554
555 This class is an extension of `std::exception` objects with a member @a id for
556 exception ids. It is used as the base class for all exceptions thrown by the
557 @ref basic_json class. This class can hence be used as "wildcard" to catch
558 exceptions.
559
560 Subclasses:
561 - @ref parse_error for exceptions indicating a parse error
562 - @ref invalid_iterator for exceptions indicating errors with iterators
563 - @ref type_error for exceptions indicating executing a member function with
564 a wrong type
565 - @ref out_of_range for exceptions indicating access out of the defined range
566 - @ref other_error for exceptions indicating other library errors
567
568 @internal
569 @note To have nothrow-copy-constructible exceptions, we internally use
570 `std::runtime_error` which can cope with arbitrary-length error messages.
571 Intermediate strings are built with static functions and then passed to
572 the actual constructor.
573 @endinternal
574
575 @liveexample{The following code shows how arbitrary library exceptions can be
576 caught.,exception}
577
578 @since version 3.0.0
579 */
580 class exception : public std::exception
581 {
582 public:
583 /// returns the explanatory string
what() const584 const char* what() const noexcept override
585 {
586 return m.what();
587 }
588
589 /// the id of the exception
590 const int id;
591
592 protected:
exception(int id_,const char * what_arg)593 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
594
name(const std::string & ename,int id_)595 static std::string name(const std::string& ename, int id_)
596 {
597 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
598 }
599
600 private:
601 /// an exception object as storage for error messages
602 std::runtime_error m;
603 };
604
605 /*!
606 @brief exception indicating a parse error
607
608 This exception is thrown by the library when a parse error occurs. Parse errors
609 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
610 as when using JSON Patch.
611
612 Member @a byte holds the byte index of the last read character in the input
613 file.
614
615 Exceptions have ids 1xx.
616
617 name / id | example message | description
618 ------------------------------ | --------------- | -------------------------
619 json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
620 json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
621 json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
622 json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
623 json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
624 json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
625 json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
626 json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
627 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
628 json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
629 json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
630 json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
631
632 @note For an input with n bytes, 1 is the index of the first character and n+1
633 is the index of the terminating null byte or the end of file. This also
634 holds true when reading a byte vector (CBOR or MessagePack).
635
636 @liveexample{The following code shows how a `parse_error` exception can be
637 caught.,parse_error}
638
639 @sa @ref exception for the base class of the library exceptions
640 @sa @ref invalid_iterator for exceptions indicating errors with iterators
641 @sa @ref type_error for exceptions indicating executing a member function with
642 a wrong type
643 @sa @ref out_of_range for exceptions indicating access out of the defined range
644 @sa @ref other_error for exceptions indicating other library errors
645
646 @since version 3.0.0
647 */
648 class parse_error : public exception
649 {
650 public:
651 /*!
652 @brief create a parse error exception
653 @param[in] id_ the id of the exception
654 @param[in] byte_ the byte index where the error occurred (or 0 if the
655 position cannot be determined)
656 @param[in] what_arg the explanatory string
657 @return parse_error object
658 */
create(int id_,std::size_t byte_,const std::string & what_arg)659 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
660 {
661 std::string w = exception::name("parse_error", id_) + "parse error" +
662 (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
663 ": " + what_arg;
664 return parse_error(id_, byte_, w.c_str());
665 }
666
667 /*!
668 @brief byte index of the parse error
669
670 The byte index of the last read character in the input file.
671
672 @note For an input with n bytes, 1 is the index of the first character and
673 n+1 is the index of the terminating null byte or the end of file.
674 This also holds true when reading a byte vector (CBOR or MessagePack).
675 */
676 const std::size_t byte;
677
678 private:
parse_error(int id_,std::size_t byte_,const char * what_arg)679 parse_error(int id_, std::size_t byte_, const char* what_arg)
680 : exception(id_, what_arg), byte(byte_) {}
681 };
682
683 /*!
684 @brief exception indicating errors with iterators
685
686 This exception is thrown if iterators passed to a library function do not match
687 the expected semantics.
688
689 Exceptions have ids 2xx.
690
691 name / id | example message | description
692 ----------------------------------- | --------------- | -------------------------
693 json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
694 json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
695 json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
696 json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
697 json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
698 json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
699 json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
700 json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
701 json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
702 json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
703 json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
704 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
705 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
706 json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
707
708 @liveexample{The following code shows how an `invalid_iterator` exception can be
709 caught.,invalid_iterator}
710
711 @sa @ref exception for the base class of the library exceptions
712 @sa @ref parse_error for exceptions indicating a parse error
713 @sa @ref type_error for exceptions indicating executing a member function with
714 a wrong type
715 @sa @ref out_of_range for exceptions indicating access out of the defined range
716 @sa @ref other_error for exceptions indicating other library errors
717
718 @since version 3.0.0
719 */
720 class invalid_iterator : public exception
721 {
722 public:
create(int id_,const std::string & what_arg)723 static invalid_iterator create(int id_, const std::string& what_arg)
724 {
725 std::string w = exception::name("invalid_iterator", id_) + what_arg;
726 return invalid_iterator(id_, w.c_str());
727 }
728
729 private:
invalid_iterator(int id_,const char * what_arg)730 invalid_iterator(int id_, const char* what_arg)
731 : exception(id_, what_arg) {}
732 };
733
734 /*!
735 @brief exception indicating executing a member function with a wrong type
736
737 This exception is thrown in case of a type error; that is, a library function is
738 executed on a JSON value whose type does not match the expected semantics.
739
740 Exceptions have ids 3xx.
741
742 name / id | example message | description
743 ----------------------------- | --------------- | -------------------------
744 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
745 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
746 json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
747 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
748 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
749 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
750 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
751 json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
752 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
753 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
754 json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
755 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
756 json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
757 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
758 json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
759 json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
760
761 @liveexample{The following code shows how a `type_error` exception can be
762 caught.,type_error}
763
764 @sa @ref exception for the base class of the library exceptions
765 @sa @ref parse_error for exceptions indicating a parse error
766 @sa @ref invalid_iterator for exceptions indicating errors with iterators
767 @sa @ref out_of_range for exceptions indicating access out of the defined range
768 @sa @ref other_error for exceptions indicating other library errors
769
770 @since version 3.0.0
771 */
772 class type_error : public exception
773 {
774 public:
create(int id_,const std::string & what_arg)775 static type_error create(int id_, const std::string& what_arg)
776 {
777 std::string w = exception::name("type_error", id_) + what_arg;
778 return type_error(id_, w.c_str());
779 }
780
781 private:
type_error(int id_,const char * what_arg)782 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
783 };
784
785 /*!
786 @brief exception indicating access out of the defined range
787
788 This exception is thrown in case a library function is called on an input
789 parameter that exceeds the expected range, for instance in case of array
790 indices or nonexisting object keys.
791
792 Exceptions have ids 4xx.
793
794 name / id | example message | description
795 ------------------------------- | --------------- | -------------------------
796 json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
797 json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
798 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
799 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
800 json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
801 json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
802 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON only supports integers numbers up to 9223372036854775807. |
803 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
804
805 @liveexample{The following code shows how an `out_of_range` exception can be
806 caught.,out_of_range}
807
808 @sa @ref exception for the base class of the library exceptions
809 @sa @ref parse_error for exceptions indicating a parse error
810 @sa @ref invalid_iterator for exceptions indicating errors with iterators
811 @sa @ref type_error for exceptions indicating executing a member function with
812 a wrong type
813 @sa @ref other_error for exceptions indicating other library errors
814
815 @since version 3.0.0
816 */
817 class out_of_range : public exception
818 {
819 public:
create(int id_,const std::string & what_arg)820 static out_of_range create(int id_, const std::string& what_arg)
821 {
822 std::string w = exception::name("out_of_range", id_) + what_arg;
823 return out_of_range(id_, w.c_str());
824 }
825
826 private:
out_of_range(int id_,const char * what_arg)827 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
828 };
829
830 /*!
831 @brief exception indicating other library errors
832
833 This exception is thrown in case of errors that cannot be classified with the
834 other exception types.
835
836 Exceptions have ids 5xx.
837
838 name / id | example message | description
839 ------------------------------ | --------------- | -------------------------
840 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
841
842 @sa @ref exception for the base class of the library exceptions
843 @sa @ref parse_error for exceptions indicating a parse error
844 @sa @ref invalid_iterator for exceptions indicating errors with iterators
845 @sa @ref type_error for exceptions indicating executing a member function with
846 a wrong type
847 @sa @ref out_of_range for exceptions indicating access out of the defined range
848
849 @liveexample{The following code shows how an `other_error` exception can be
850 caught.,other_error}
851
852 @since version 3.0.0
853 */
854 class other_error : public exception
855 {
856 public:
create(int id_,const std::string & what_arg)857 static other_error create(int id_, const std::string& what_arg)
858 {
859 std::string w = exception::name("other_error", id_) + what_arg;
860 return other_error(id_, w.c_str());
861 }
862
863 private:
other_error(int id_,const char * what_arg)864 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
865 };
866 }
867 }
868
869 // #include <nlohmann/detail/value_t.hpp>
870
871
872 #include <array> // array
873 #include <ciso646> // and
874 #include <cstddef> // size_t
875 #include <cstdint> // uint8_t
876
877 namespace nlohmann
878 {
879 namespace detail
880 {
881 ///////////////////////////
882 // JSON type enumeration //
883 ///////////////////////////
884
885 /*!
886 @brief the JSON type enumeration
887
888 This enumeration collects the different JSON types. It is internally used to
889 distinguish the stored values, and the functions @ref basic_json::is_null(),
890 @ref basic_json::is_object(), @ref basic_json::is_array(),
891 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
892 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
893 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
894 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
895 @ref basic_json::is_structured() rely on it.
896
897 @note There are three enumeration entries (number_integer, number_unsigned, and
898 number_float), because the library distinguishes these three types for numbers:
899 @ref basic_json::number_unsigned_t is used for unsigned integers,
900 @ref basic_json::number_integer_t is used for signed integers, and
901 @ref basic_json::number_float_t is used for floating-point numbers or to
902 approximate integers which do not fit in the limits of their respective type.
903
904 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
905 value with the default value for a given type
906
907 @since version 1.0.0
908 */
909 enum class value_t : std::uint8_t
910 {
911 null, ///< null value
912 object, ///< object (unordered set of name/value pairs)
913 array, ///< array (ordered collection of values)
914 string, ///< string value
915 boolean, ///< boolean value
916 number_integer, ///< number value (signed integer)
917 number_unsigned, ///< number value (unsigned integer)
918 number_float, ///< number value (floating-point)
919 discarded ///< discarded by the the parser callback function
920 };
921
922 /*!
923 @brief comparison operator for JSON types
924
925 Returns an ordering that is similar to Python:
926 - order: null < boolean < number < object < array < string
927 - furthermore, each type is not smaller than itself
928 - discarded values are not comparable
929
930 @since version 1.0.0
931 */
operator <(const value_t lhs,const value_t rhs)932 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
933 {
934 static constexpr std::array<std::uint8_t, 8> order = {{
935 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
936 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
937 }
938 };
939
940 const auto l_index = static_cast<std::size_t>(lhs);
941 const auto r_index = static_cast<std::size_t>(rhs);
942 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
943 }
944 }
945 }
946
947 // #include <nlohmann/detail/conversions/from_json.hpp>
948
949
950 #include <algorithm> // transform
951 #include <array> // array
952 #include <ciso646> // and, not
953 #include <forward_list> // forward_list
954 #include <iterator> // inserter, front_inserter, end
955 #include <map> // map
956 #include <string> // string
957 #include <tuple> // tuple, make_tuple
958 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
959 #include <unordered_map> // unordered_map
960 #include <utility> // pair, declval
961 #include <valarray> // valarray
962
963 // #include <nlohmann/detail/exceptions.hpp>
964
965 // #include <nlohmann/detail/macro_scope.hpp>
966
967 // #include <nlohmann/detail/meta/cpp_future.hpp>
968
969 // #include <nlohmann/detail/meta/type_traits.hpp>
970
971 // #include <nlohmann/detail/value_t.hpp>
972
973
974 namespace nlohmann
975 {
976 namespace detail
977 {
978 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)979 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
980 {
981 if (JSON_UNLIKELY(not j.is_null()))
982 {
983 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
984 }
985 n = nullptr;
986 }
987
988 // overloads for basic_json template parameters
989 template<typename BasicJsonType, typename ArithmeticType,
990 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
991 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
992 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)993 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
994 {
995 switch (static_cast<value_t>(j))
996 {
997 case value_t::number_unsigned:
998 {
999 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1000 break;
1001 }
1002 case value_t::number_integer:
1003 {
1004 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1005 break;
1006 }
1007 case value_t::number_float:
1008 {
1009 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1010 break;
1011 }
1012
1013 default:
1014 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1015 }
1016 }
1017
1018 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1019 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1020 {
1021 if (JSON_UNLIKELY(not j.is_boolean()))
1022 {
1023 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1024 }
1025 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1026 }
1027
1028 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1029 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1030 {
1031 if (JSON_UNLIKELY(not j.is_string()))
1032 {
1033 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1034 }
1035 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1036 }
1037
1038 template <
1039 typename BasicJsonType, typename CompatibleStringType,
1040 enable_if_t <
1041 is_compatible_string_type<BasicJsonType, CompatibleStringType>::value and
1042 not std::is_same<typename BasicJsonType::string_t,
1043 CompatibleStringType>::value,
1044 int > = 0 >
from_json(const BasicJsonType & j,CompatibleStringType & s)1045 void from_json(const BasicJsonType& j, CompatibleStringType& s)
1046 {
1047 if (JSON_UNLIKELY(not j.is_string()))
1048 {
1049 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1050 }
1051
1052 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1053 }
1054
1055 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1056 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1057 {
1058 get_arithmetic_value(j, val);
1059 }
1060
1061 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1062 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1063 {
1064 get_arithmetic_value(j, val);
1065 }
1066
1067 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1068 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1069 {
1070 get_arithmetic_value(j, val);
1071 }
1072
1073 template<typename BasicJsonType, typename EnumType,
1074 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1075 void from_json(const BasicJsonType& j, EnumType& e)
1076 {
1077 typename std::underlying_type<EnumType>::type val;
1078 get_arithmetic_value(j, val);
1079 e = static_cast<EnumType>(val);
1080 }
1081
1082 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::array_t & arr)1083 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1084 {
1085 if (JSON_UNLIKELY(not j.is_array()))
1086 {
1087 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1088 }
1089 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1090 }
1091
1092 // forward_list doesn't have an insert method
1093 template<typename BasicJsonType, typename T, typename Allocator,
1094 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1095 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1096 {
1097 if (JSON_UNLIKELY(not j.is_array()))
1098 {
1099 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1100 }
1101 std::transform(j.rbegin(), j.rend(),
1102 std::front_inserter(l), [](const BasicJsonType & i)
1103 {
1104 return i.template get<T>();
1105 });
1106 }
1107
1108 // valarray doesn't have an insert method
1109 template<typename BasicJsonType, typename T,
1110 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1111 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1112 {
1113 if (JSON_UNLIKELY(not j.is_array()))
1114 {
1115 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1116 }
1117 l.resize(j.size());
1118 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1119 }
1120
1121 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<0>)1122 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1123 {
1124 using std::end;
1125
1126 std::transform(j.begin(), j.end(),
1127 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1128 {
1129 // get<BasicJsonType>() returns *this, this won't call a from_json
1130 // method when value_type is BasicJsonType
1131 return i.template get<typename CompatibleArrayType::value_type>();
1132 });
1133 }
1134
1135 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<1>)1136 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1137 -> decltype(
1138 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1139 void())
1140 {
1141 using std::end;
1142
1143 arr.reserve(j.size());
1144 std::transform(j.begin(), j.end(),
1145 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1146 {
1147 // get<BasicJsonType>() returns *this, this won't call a from_json
1148 // method when value_type is BasicJsonType
1149 return i.template get<typename CompatibleArrayType::value_type>();
1150 });
1151 }
1152
1153 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1154 void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1155 {
1156 for (std::size_t i = 0; i < N; ++i)
1157 {
1158 arr[i] = j.at(i).template get<T>();
1159 }
1160 }
1161
1162 template <
1163 typename BasicJsonType, typename CompatibleArrayType,
1164 enable_if_t <
1165 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1166 not std::is_same<typename BasicJsonType::array_t,
1167 CompatibleArrayType>::value and
1168 std::is_constructible <
1169 BasicJsonType, typename CompatibleArrayType::value_type >::value,
1170 int > = 0 >
from_json(const BasicJsonType & j,CompatibleArrayType & arr)1171 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1172 {
1173 if (JSON_UNLIKELY(not j.is_array()))
1174 {
1175 JSON_THROW(type_error::create(302, "type must be array, but is " +
1176 std::string(j.type_name())));
1177 }
1178
1179 from_json_array_impl(j, arr, priority_tag<2> {});
1180 }
1181
1182 template<typename BasicJsonType, typename CompatibleObjectType,
1183 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleObjectType & obj)1184 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1185 {
1186 if (JSON_UNLIKELY(not j.is_object()))
1187 {
1188 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1189 }
1190
1191 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1192 using value_type = typename CompatibleObjectType::value_type;
1193 std::transform(
1194 inner_object->begin(), inner_object->end(),
1195 std::inserter(obj, obj.begin()),
1196 [](typename BasicJsonType::object_t::value_type const & p)
1197 {
1198 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1199 });
1200 }
1201
1202 // overload for arithmetic types, not chosen for basic_json template arguments
1203 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1204 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1205 // an arithmetic type?
1206 template<typename BasicJsonType, typename ArithmeticType,
1207 enable_if_t <
1208 std::is_arithmetic<ArithmeticType>::value and
1209 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1210 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1211 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1212 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1213 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1214 void from_json(const BasicJsonType& j, ArithmeticType& val)
1215 {
1216 switch (static_cast<value_t>(j))
1217 {
1218 case value_t::number_unsigned:
1219 {
1220 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1221 break;
1222 }
1223 case value_t::number_integer:
1224 {
1225 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1226 break;
1227 }
1228 case value_t::number_float:
1229 {
1230 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1231 break;
1232 }
1233 case value_t::boolean:
1234 {
1235 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1236 break;
1237 }
1238
1239 default:
1240 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1241 }
1242 }
1243
1244 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1245 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1246 {
1247 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1248 }
1249
1250 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1251 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1252 {
1253 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1254 }
1255
1256 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1257 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1258 {
1259 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1260 }
1261
1262 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1263 typename = enable_if_t<not std::is_constructible<
1264 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)1265 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1266 {
1267 if (JSON_UNLIKELY(not j.is_array()))
1268 {
1269 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1270 }
1271 for (const auto& p : j)
1272 {
1273 if (JSON_UNLIKELY(not p.is_array()))
1274 {
1275 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1276 }
1277 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1278 }
1279 }
1280
1281 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1282 typename = enable_if_t<not std::is_constructible<
1283 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)1284 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1285 {
1286 if (JSON_UNLIKELY(not j.is_array()))
1287 {
1288 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1289 }
1290 for (const auto& p : j)
1291 {
1292 if (JSON_UNLIKELY(not p.is_array()))
1293 {
1294 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1295 }
1296 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1297 }
1298 }
1299
1300 struct from_json_fn
1301 {
1302 private:
1303 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1304 auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1305 noexcept(noexcept(from_json(j, val)))
1306 -> decltype(from_json(j, val), void())
1307 {
1308 return from_json(j, val);
1309 }
1310
1311 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1312 void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1313 {
1314 static_assert(sizeof(BasicJsonType) == 0,
1315 "could not find from_json() method in T's namespace");
1316 #ifdef _MSC_VER
1317 // MSVC does not show a stacktrace for the above assert
1318 using decayed = uncvref_t<T>;
1319 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1320 "forcing MSVC stacktrace to show which T we're talking about.");
1321 #endif
1322 }
1323
1324 public:
1325 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1326 void operator()(const BasicJsonType& j, T& val) const
1327 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1328 {
1329 return call(j, val, priority_tag<1> {});
1330 }
1331 };
1332 }
1333
1334 /// namespace to hold default `from_json` function
1335 /// to see why this is required:
1336 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1337 namespace
1338 {
1339 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1340 }
1341 }
1342
1343 // #include <nlohmann/detail/conversions/to_json.hpp>
1344
1345
1346 #include <ciso646> // or, and, not
1347 #include <iterator> // begin, end
1348 #include <tuple> // tuple, get
1349 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1350 #include <utility> // move, forward, declval, pair
1351 #include <valarray> // valarray
1352 #include <vector> // vector
1353
1354 // #include <nlohmann/detail/meta/cpp_future.hpp>
1355
1356 // #include <nlohmann/detail/meta/type_traits.hpp>
1357
1358 // #include <nlohmann/detail/value_t.hpp>
1359
1360 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1361
1362
1363 #include <cstddef> // size_t
1364 #include <string> // string, to_string
1365 #include <iterator> // input_iterator_tag
1366
1367 // #include <nlohmann/detail/value_t.hpp>
1368
1369
1370 namespace nlohmann
1371 {
1372 namespace detail
1373 {
1374 /// proxy class for the items() function
1375 template<typename IteratorType> class iteration_proxy
1376 {
1377 private:
1378 /// helper class for iteration
1379 class iteration_proxy_internal
1380 {
1381 public:
1382 using difference_type = std::ptrdiff_t;
1383 using value_type = iteration_proxy_internal;
1384 using pointer = iteration_proxy_internal*;
1385 using reference = iteration_proxy_internal&;
1386 using iterator_category = std::input_iterator_tag;
1387
1388 private:
1389 /// the iterator
1390 IteratorType anchor;
1391 /// an index for arrays (used to create key names)
1392 std::size_t array_index = 0;
1393 /// last stringified array index
1394 mutable std::size_t array_index_last = 0;
1395 /// a string representation of the array index
1396 mutable std::string array_index_str = "0";
1397 /// an empty string (to return a reference for primitive values)
1398 const std::string empty_str = "";
1399
1400 public:
iteration_proxy_internal(IteratorType it)1401 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
1402
1403 iteration_proxy_internal(const iteration_proxy_internal&) = default;
1404 iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default;
1405
1406 /// dereference operator (needed for range-based for)
operator *()1407 iteration_proxy_internal& operator*()
1408 {
1409 return *this;
1410 }
1411
1412 /// increment operator (needed for range-based for)
operator ++()1413 iteration_proxy_internal& operator++()
1414 {
1415 ++anchor;
1416 ++array_index;
1417
1418 return *this;
1419 }
1420
1421 /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_internal & o) const1422 bool operator==(const iteration_proxy_internal& o) const noexcept
1423 {
1424 return anchor == o.anchor;
1425 }
1426
1427 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const1428 bool operator!=(const iteration_proxy_internal& o) const noexcept
1429 {
1430 return anchor != o.anchor;
1431 }
1432
1433 /// return key of the iterator
key() const1434 const std::string& key() const
1435 {
1436 assert(anchor.m_object != nullptr);
1437
1438 switch (anchor.m_object->type())
1439 {
1440 // use integer array index as key
1441 case value_t::array:
1442 {
1443 if (array_index != array_index_last)
1444 {
1445 array_index_str = std::to_string(array_index);
1446 array_index_last = array_index;
1447 }
1448 return array_index_str;
1449 }
1450
1451 // use key from the object
1452 case value_t::object:
1453 return anchor.key();
1454
1455 // use an empty key for all primitive types
1456 default:
1457 return empty_str;
1458 }
1459 }
1460
1461 /// return value of the iterator
value() const1462 typename IteratorType::reference value() const
1463 {
1464 return anchor.value();
1465 }
1466 };
1467
1468 /// the container to iterate
1469 typename IteratorType::reference container;
1470
1471 public:
1472 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)1473 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1474 : container(cont) {}
1475
1476 /// return iterator begin (needed for range-based for)
begin()1477 iteration_proxy_internal begin() noexcept
1478 {
1479 return iteration_proxy_internal(container.begin());
1480 }
1481
1482 /// return iterator end (needed for range-based for)
end()1483 iteration_proxy_internal end() noexcept
1484 {
1485 return iteration_proxy_internal(container.end());
1486 }
1487 };
1488 }
1489 }
1490
1491
1492 namespace nlohmann
1493 {
1494 namespace detail
1495 {
1496 //////////////////
1497 // constructors //
1498 //////////////////
1499
1500 template<value_t> struct external_constructor;
1501
1502 template<>
1503 struct external_constructor<value_t::boolean>
1504 {
1505 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1506 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1507 {
1508 j.m_type = value_t::boolean;
1509 j.m_value = b;
1510 j.assert_invariant();
1511 }
1512 };
1513
1514 template<>
1515 struct external_constructor<value_t::string>
1516 {
1517 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1518 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1519 {
1520 j.m_type = value_t::string;
1521 j.m_value = s;
1522 j.assert_invariant();
1523 }
1524
1525 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1526 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1527 {
1528 j.m_type = value_t::string;
1529 j.m_value = std::move(s);
1530 j.assert_invariant();
1531 }
1532
1533 template<typename BasicJsonType, typename CompatibleStringType,
1534 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1535 int> = 0>
constructnlohmann::detail::external_constructor1536 static void construct(BasicJsonType& j, const CompatibleStringType& str)
1537 {
1538 j.m_type = value_t::string;
1539 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1540 j.assert_invariant();
1541 }
1542 };
1543
1544 template<>
1545 struct external_constructor<value_t::number_float>
1546 {
1547 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1548 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1549 {
1550 j.m_type = value_t::number_float;
1551 j.m_value = val;
1552 j.assert_invariant();
1553 }
1554 };
1555
1556 template<>
1557 struct external_constructor<value_t::number_unsigned>
1558 {
1559 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1560 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1561 {
1562 j.m_type = value_t::number_unsigned;
1563 j.m_value = val;
1564 j.assert_invariant();
1565 }
1566 };
1567
1568 template<>
1569 struct external_constructor<value_t::number_integer>
1570 {
1571 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1572 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1573 {
1574 j.m_type = value_t::number_integer;
1575 j.m_value = val;
1576 j.assert_invariant();
1577 }
1578 };
1579
1580 template<>
1581 struct external_constructor<value_t::array>
1582 {
1583 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1584 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1585 {
1586 j.m_type = value_t::array;
1587 j.m_value = arr;
1588 j.assert_invariant();
1589 }
1590
1591 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1592 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1593 {
1594 j.m_type = value_t::array;
1595 j.m_value = std::move(arr);
1596 j.assert_invariant();
1597 }
1598
1599 template<typename BasicJsonType, typename CompatibleArrayType,
1600 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1601 int> = 0>
constructnlohmann::detail::external_constructor1602 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1603 {
1604 using std::begin;
1605 using std::end;
1606 j.m_type = value_t::array;
1607 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1608 j.assert_invariant();
1609 }
1610
1611 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1612 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1613 {
1614 j.m_type = value_t::array;
1615 j.m_value = value_t::array;
1616 j.m_value.array->reserve(arr.size());
1617 for (const bool x : arr)
1618 {
1619 j.m_value.array->push_back(x);
1620 }
1621 j.assert_invariant();
1622 }
1623
1624 template<typename BasicJsonType, typename T,
1625 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor1626 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1627 {
1628 j.m_type = value_t::array;
1629 j.m_value = value_t::array;
1630 j.m_value.array->resize(arr.size());
1631 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1632 j.assert_invariant();
1633 }
1634 };
1635
1636 template<>
1637 struct external_constructor<value_t::object>
1638 {
1639 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1640 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1641 {
1642 j.m_type = value_t::object;
1643 j.m_value = obj;
1644 j.assert_invariant();
1645 }
1646
1647 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1648 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1649 {
1650 j.m_type = value_t::object;
1651 j.m_value = std::move(obj);
1652 j.assert_invariant();
1653 }
1654
1655 template<typename BasicJsonType, typename CompatibleObjectType,
1656 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor1657 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1658 {
1659 using std::begin;
1660 using std::end;
1661
1662 j.m_type = value_t::object;
1663 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1664 j.assert_invariant();
1665 }
1666 };
1667
1668 /////////////
1669 // to_json //
1670 /////////////
1671
1672 template<typename BasicJsonType, typename T,
1673 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)1674 void to_json(BasicJsonType& j, T b) noexcept
1675 {
1676 external_constructor<value_t::boolean>::construct(j, b);
1677 }
1678
1679 template<typename BasicJsonType, typename CompatibleString,
1680 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)1681 void to_json(BasicJsonType& j, const CompatibleString& s)
1682 {
1683 external_constructor<value_t::string>::construct(j, s);
1684 }
1685
1686 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)1687 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1688 {
1689 external_constructor<value_t::string>::construct(j, std::move(s));
1690 }
1691
1692 template<typename BasicJsonType, typename FloatType,
1693 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)1694 void to_json(BasicJsonType& j, FloatType val) noexcept
1695 {
1696 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1697 }
1698
1699 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1700 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)1701 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1702 {
1703 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1704 }
1705
1706 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1707 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)1708 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1709 {
1710 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1711 }
1712
1713 template<typename BasicJsonType, typename EnumType,
1714 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)1715 void to_json(BasicJsonType& j, EnumType e) noexcept
1716 {
1717 using underlying_type = typename std::underlying_type<EnumType>::type;
1718 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1719 }
1720
1721 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)1722 void to_json(BasicJsonType& j, const std::vector<bool>& e)
1723 {
1724 external_constructor<value_t::array>::construct(j, e);
1725 }
1726
1727 template<typename BasicJsonType, typename CompatibleArrayType,
1728 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1729 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1730 int> = 0>
to_json(BasicJsonType & j,const CompatibleArrayType & arr)1731 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1732 {
1733 external_constructor<value_t::array>::construct(j, arr);
1734 }
1735
1736 template<typename BasicJsonType, typename T,
1737 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)1738 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
1739 {
1740 external_constructor<value_t::array>::construct(j, std::move(arr));
1741 }
1742
1743 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)1744 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1745 {
1746 external_constructor<value_t::array>::construct(j, std::move(arr));
1747 }
1748
1749 template<typename BasicJsonType, typename CompatibleObjectType,
1750 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleObjectType & obj)1751 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1752 {
1753 external_constructor<value_t::object>::construct(j, obj);
1754 }
1755
1756 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)1757 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1758 {
1759 external_constructor<value_t::object>::construct(j, std::move(obj));
1760 }
1761
1762 template<typename BasicJsonType, typename T, std::size_t N,
1763 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value, int> = 0>
to_json(BasicJsonType & j,T (& arr)[N])1764 void to_json(BasicJsonType& j, T (&arr)[N])
1765 {
1766 external_constructor<value_t::array>::construct(j, arr);
1767 }
1768
1769 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)1770 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1771 {
1772 j = {p.first, p.second};
1773 }
1774
1775 // for https://github.com/nlohmann/json/pull/1134
1776 template<typename BasicJsonType, typename T,
1777 enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
to_json(BasicJsonType & j,T b)1778 void to_json(BasicJsonType& j, T b) noexcept
1779 {
1780 j = {{b.key(), b.value()}};
1781 }
1782
1783 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)1784 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1785 {
1786 j = {std::get<Idx>(t)...};
1787 }
1788
1789 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)1790 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1791 {
1792 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1793 }
1794
1795 struct to_json_fn
1796 {
1797 private:
1798 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1799 auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1800 -> decltype(to_json(j, std::forward<T>(val)), void())
1801 {
1802 return to_json(j, std::forward<T>(val));
1803 }
1804
1805 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1806 void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1807 {
1808 static_assert(sizeof(BasicJsonType) == 0,
1809 "could not find to_json() method in T's namespace");
1810
1811 #ifdef _MSC_VER
1812 // MSVC does not show a stacktrace for the above assert
1813 using decayed = uncvref_t<T>;
1814 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1815 "forcing MSVC stacktrace to show which T we're talking about.");
1816 #endif
1817 }
1818
1819 public:
1820 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn1821 void operator()(BasicJsonType& j, T&& val) const
1822 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1823 {
1824 return call(j, std::forward<T>(val), priority_tag<1> {});
1825 }
1826 };
1827 }
1828
1829 /// namespace to hold default `to_json` function
1830 namespace
1831 {
1832 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1833 }
1834 }
1835
1836 // #include <nlohmann/detail/input/input_adapters.hpp>
1837
1838
1839 #include <cassert> // assert
1840 #include <cstddef> // size_t
1841 #include <cstring> // strlen
1842 #include <istream> // istream
1843 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1844 #include <memory> // shared_ptr, make_shared, addressof
1845 #include <numeric> // accumulate
1846 #include <string> // string, char_traits
1847 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1848 #include <utility> // pair, declval
1849
1850 // #include <nlohmann/detail/macro_scope.hpp>
1851
1852
1853 namespace nlohmann
1854 {
1855 namespace detail
1856 {
1857 /// the supported input formats
1858 enum class input_format_t { json, cbor, msgpack, ubjson };
1859
1860 ////////////////////
1861 // input adapters //
1862 ////////////////////
1863
1864 /*!
1865 @brief abstract input adapter interface
1866
1867 Produces a stream of std::char_traits<char>::int_type characters from a
1868 std::istream, a buffer, or some other input type. Accepts the return of
1869 exactly one non-EOF character for future input. The int_type characters
1870 returned consist of all valid char values as positive values (typically
1871 unsigned char), plus an EOF value outside that range, specified by the value
1872 of the function std::char_traits<char>::eof(). This value is typically -1, but
1873 could be any arbitrary value which is not a valid char value.
1874 */
1875 struct input_adapter_protocol
1876 {
1877 /// get a character [0,255] or std::char_traits<char>::eof().
1878 virtual std::char_traits<char>::int_type get_character() = 0;
1879 virtual ~input_adapter_protocol() = default;
1880 };
1881
1882 /// a type to simplify interfaces
1883 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1884
1885 /*!
1886 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1887 beginning of input. Does not support changing the underlying std::streambuf
1888 in mid-input. Maintains underlying std::istream and std::streambuf to support
1889 subsequent use of standard std::istream operations to process any input
1890 characters following those used in parsing the JSON input. Clears the
1891 std::istream flags; any input errors (e.g., EOF) will be detected by the first
1892 subsequent call for input from the std::istream.
1893 */
1894 class input_stream_adapter : public input_adapter_protocol
1895 {
1896 public:
~input_stream_adapter()1897 ~input_stream_adapter() override
1898 {
1899 // clear stream flags; we use underlying streambuf I/O, do not
1900 // maintain ifstream flags
1901 is.clear();
1902 }
1903
input_stream_adapter(std::istream & i)1904 explicit input_stream_adapter(std::istream& i)
1905 : is(i), sb(*i.rdbuf())
1906 {}
1907
1908 // delete because of pointer members
1909 input_stream_adapter(const input_stream_adapter&) = delete;
1910 input_stream_adapter& operator=(input_stream_adapter&) = delete;
1911
1912 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1913 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
1914 // end up as the same value, eg. 0xFFFFFFFF.
get_character()1915 std::char_traits<char>::int_type get_character() override
1916 {
1917 return sb.sbumpc();
1918 }
1919
1920 private:
1921 /// the associated input stream
1922 std::istream& is;
1923 std::streambuf& sb;
1924 };
1925
1926 /// input adapter for buffer input
1927 class input_buffer_adapter : public input_adapter_protocol
1928 {
1929 public:
input_buffer_adapter(const char * b,const std::size_t l)1930 input_buffer_adapter(const char* b, const std::size_t l)
1931 : cursor(b), limit(b + l)
1932 {}
1933
1934 // delete because of pointer members
1935 input_buffer_adapter(const input_buffer_adapter&) = delete;
1936 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1937
get_character()1938 std::char_traits<char>::int_type get_character() noexcept override
1939 {
1940 if (JSON_LIKELY(cursor < limit))
1941 {
1942 return std::char_traits<char>::to_int_type(*(cursor++));
1943 }
1944
1945 return std::char_traits<char>::eof();
1946 }
1947
1948 private:
1949 /// pointer to the current character
1950 const char* cursor;
1951 /// pointer past the last character
1952 const char* const limit;
1953 };
1954
1955 template<typename WideStringType>
1956 class wide_string_input_adapter : public input_adapter_protocol
1957 {
1958 public:
wide_string_input_adapter(const WideStringType & w)1959 explicit wide_string_input_adapter(const WideStringType& w) : str(w) {}
1960
get_character()1961 std::char_traits<char>::int_type get_character() noexcept override
1962 {
1963 // check if buffer needs to be filled
1964 if (utf8_bytes_index == utf8_bytes_filled)
1965 {
1966 if (sizeof(typename WideStringType::value_type) == 2)
1967 {
1968 fill_buffer_utf16();
1969 }
1970 else
1971 {
1972 fill_buffer_utf32();
1973 }
1974
1975 assert(utf8_bytes_filled > 0);
1976 assert(utf8_bytes_index == 0);
1977 }
1978
1979 // use buffer
1980 assert(utf8_bytes_filled > 0);
1981 assert(utf8_bytes_index < utf8_bytes_filled);
1982 return utf8_bytes[utf8_bytes_index++];
1983 }
1984
1985 private:
fill_buffer_utf16()1986 void fill_buffer_utf16()
1987 {
1988 utf8_bytes_index = 0;
1989
1990 if (current_wchar == str.size())
1991 {
1992 utf8_bytes[0] = std::char_traits<char>::eof();
1993 utf8_bytes_filled = 1;
1994 }
1995 else
1996 {
1997 // get the current character
1998 const int wc = static_cast<int>(str[current_wchar++]);
1999
2000 // UTF-16 to UTF-8 encoding
2001 if (wc < 0x80)
2002 {
2003 utf8_bytes[0] = wc;
2004 utf8_bytes_filled = 1;
2005 }
2006 else if (wc <= 0x7FF)
2007 {
2008 utf8_bytes[0] = 0xC0 | ((wc >> 6));
2009 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2010 utf8_bytes_filled = 2;
2011 }
2012 else if (0xD800 > wc or wc >= 0xE000)
2013 {
2014 utf8_bytes[0] = 0xE0 | ((wc >> 12));
2015 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2016 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2017 utf8_bytes_filled = 3;
2018 }
2019 else
2020 {
2021 if (current_wchar < str.size())
2022 {
2023 const int wc2 = static_cast<int>(str[current_wchar++]);
2024 const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2025 utf8_bytes[0] = 0xf0 | (charcode >> 18);
2026 utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2027 utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2028 utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2029 utf8_bytes_filled = 4;
2030 }
2031 else
2032 {
2033 // unknown character
2034 ++current_wchar;
2035 utf8_bytes[0] = wc;
2036 utf8_bytes_filled = 1;
2037 }
2038 }
2039 }
2040 }
2041
fill_buffer_utf32()2042 void fill_buffer_utf32()
2043 {
2044 utf8_bytes_index = 0;
2045
2046 if (current_wchar == str.size())
2047 {
2048 utf8_bytes[0] = std::char_traits<char>::eof();
2049 utf8_bytes_filled = 1;
2050 }
2051 else
2052 {
2053 // get the current character
2054 const int wc = static_cast<int>(str[current_wchar++]);
2055
2056 // UTF-32 to UTF-8 encoding
2057 if (wc < 0x80)
2058 {
2059 utf8_bytes[0] = wc;
2060 utf8_bytes_filled = 1;
2061 }
2062 else if (wc <= 0x7FF)
2063 {
2064 utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2065 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2066 utf8_bytes_filled = 2;
2067 }
2068 else if (wc <= 0xFFFF)
2069 {
2070 utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2071 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2072 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2073 utf8_bytes_filled = 3;
2074 }
2075 else if (wc <= 0x10FFFF)
2076 {
2077 utf8_bytes[0] = 0xF0 | ((wc >> 18 ) & 0x07);
2078 utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2079 utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2080 utf8_bytes[3] = 0x80 | (wc & 0x3F);
2081 utf8_bytes_filled = 4;
2082 }
2083 else
2084 {
2085 // unknown character
2086 utf8_bytes[0] = wc;
2087 utf8_bytes_filled = 1;
2088 }
2089 }
2090 }
2091
2092 private:
2093 /// the wstring to process
2094 const WideStringType& str;
2095
2096 /// index of the current wchar in str
2097 std::size_t current_wchar = 0;
2098
2099 /// a buffer for UTF-8 bytes
2100 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2101
2102 /// index to the utf8_codes array for the next valid byte
2103 std::size_t utf8_bytes_index = 0;
2104 /// number of valid bytes in the utf8_codes array
2105 std::size_t utf8_bytes_filled = 0;
2106 };
2107
2108 class input_adapter
2109 {
2110 public:
2111 // native support
2112
2113 /// input adapter for input stream
input_adapter(std::istream & i)2114 input_adapter(std::istream& i)
2115 : ia(std::make_shared<input_stream_adapter>(i)) {}
2116
2117 /// input adapter for input stream
input_adapter(std::istream && i)2118 input_adapter(std::istream&& i)
2119 : ia(std::make_shared<input_stream_adapter>(i)) {}
2120
input_adapter(const std::wstring & ws)2121 input_adapter(const std::wstring& ws)
2122 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2123
input_adapter(const std::u16string & ws)2124 input_adapter(const std::u16string& ws)
2125 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2126
input_adapter(const std::u32string & ws)2127 input_adapter(const std::u32string& ws)
2128 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2129
2130 /// input adapter for buffer
2131 template<typename CharT,
2132 typename std::enable_if<
2133 std::is_pointer<CharT>::value and
2134 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2135 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2136 int>::type = 0>
input_adapter(CharT b,std::size_t l)2137 input_adapter(CharT b, std::size_t l)
2138 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2139
2140 // derived support
2141
2142 /// input adapter for string literal
2143 template<typename CharT,
2144 typename std::enable_if<
2145 std::is_pointer<CharT>::value and
2146 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2147 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2148 int>::type = 0>
input_adapter(CharT b)2149 input_adapter(CharT b)
2150 : input_adapter(reinterpret_cast<const char*>(b),
2151 std::strlen(reinterpret_cast<const char*>(b))) {}
2152
2153 /// input adapter for iterator range with contiguous storage
2154 template<class IteratorType,
2155 typename std::enable_if<
2156 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2157 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)2158 input_adapter(IteratorType first, IteratorType last)
2159 {
2160 // assertion to check that the iterator range is indeed contiguous,
2161 // see http://stackoverflow.com/a/35008842/266378 for more discussion
2162 assert(std::accumulate(
2163 first, last, std::pair<bool, int>(true, 0),
2164 [&first](std::pair<bool, int> res, decltype(*first) val)
2165 {
2166 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2167 return res;
2168 }).first);
2169
2170 // assertion to check that each element is 1 byte long
2171 static_assert(
2172 sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
2173 "each element in the iterator range must have the size of 1 byte");
2174
2175 const auto len = static_cast<size_t>(std::distance(first, last));
2176 if (JSON_LIKELY(len > 0))
2177 {
2178 // there is at least one element: use the address of first
2179 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2180 }
2181 else
2182 {
2183 // the address of first cannot be used: use nullptr
2184 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2185 }
2186 }
2187
2188 /// input adapter for array
2189 template<class T, std::size_t N>
input_adapter(T (& array)[N])2190 input_adapter(T (&array)[N])
2191 : input_adapter(std::begin(array), std::end(array)) {}
2192
2193 /// input adapter for contiguous container
2194 template<class ContiguousContainer, typename
2195 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2196 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2197 int>::type = 0>
input_adapter(const ContiguousContainer & c)2198 input_adapter(const ContiguousContainer& c)
2199 : input_adapter(std::begin(c), std::end(c)) {}
2200
operator input_adapter_t()2201 operator input_adapter_t()
2202 {
2203 return ia;
2204 }
2205
2206 private:
2207 /// the actual adapter
2208 input_adapter_t ia = nullptr;
2209 };
2210 }
2211 }
2212
2213 // #include <nlohmann/detail/input/lexer.hpp>
2214
2215
2216 #include <clocale> // localeconv
2217 #include <cstddef> // size_t
2218 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
2219 #include <cstdio> // snprintf
2220 #include <initializer_list> // initializer_list
2221 #include <string> // char_traits, string
2222 #include <vector> // vector
2223
2224 // #include <nlohmann/detail/macro_scope.hpp>
2225
2226 // #include <nlohmann/detail/input/input_adapters.hpp>
2227
2228
2229 namespace nlohmann
2230 {
2231 namespace detail
2232 {
2233 ///////////
2234 // lexer //
2235 ///////////
2236
2237 /*!
2238 @brief lexical analysis
2239
2240 This class organizes the lexical analysis during JSON deserialization.
2241 */
2242 template<typename BasicJsonType>
2243 class lexer
2244 {
2245 using number_integer_t = typename BasicJsonType::number_integer_t;
2246 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2247 using number_float_t = typename BasicJsonType::number_float_t;
2248 using string_t = typename BasicJsonType::string_t;
2249
2250 public:
2251 /// token types for the parser
2252 enum class token_type
2253 {
2254 uninitialized, ///< indicating the scanner is uninitialized
2255 literal_true, ///< the `true` literal
2256 literal_false, ///< the `false` literal
2257 literal_null, ///< the `null` literal
2258 value_string, ///< a string -- use get_string() for actual value
2259 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
2260 value_integer, ///< a signed integer -- use get_number_integer() for actual value
2261 value_float, ///< an floating point number -- use get_number_float() for actual value
2262 begin_array, ///< the character for array begin `[`
2263 begin_object, ///< the character for object begin `{`
2264 end_array, ///< the character for array end `]`
2265 end_object, ///< the character for object end `}`
2266 name_separator, ///< the name separator `:`
2267 value_separator, ///< the value separator `,`
2268 parse_error, ///< indicating a parse error
2269 end_of_input, ///< indicating the end of the input buffer
2270 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
2271 };
2272
2273 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)2274 static const char* token_type_name(const token_type t) noexcept
2275 {
2276 switch (t)
2277 {
2278 case token_type::uninitialized:
2279 return "<uninitialized>";
2280 case token_type::literal_true:
2281 return "true literal";
2282 case token_type::literal_false:
2283 return "false literal";
2284 case token_type::literal_null:
2285 return "null literal";
2286 case token_type::value_string:
2287 return "string literal";
2288 case lexer::token_type::value_unsigned:
2289 case lexer::token_type::value_integer:
2290 case lexer::token_type::value_float:
2291 return "number literal";
2292 case token_type::begin_array:
2293 return "'['";
2294 case token_type::begin_object:
2295 return "'{'";
2296 case token_type::end_array:
2297 return "']'";
2298 case token_type::end_object:
2299 return "'}'";
2300 case token_type::name_separator:
2301 return "':'";
2302 case token_type::value_separator:
2303 return "','";
2304 case token_type::parse_error:
2305 return "<parse error>";
2306 case token_type::end_of_input:
2307 return "end of input";
2308 case token_type::literal_or_value:
2309 return "'[', '{', or a literal";
2310 // LCOV_EXCL_START
2311 default: // catch non-enum values
2312 return "unknown token";
2313 // LCOV_EXCL_STOP
2314 }
2315 }
2316
lexer(detail::input_adapter_t && adapter)2317 explicit lexer(detail::input_adapter_t&& adapter)
2318 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2319
2320 // delete because of pointer members
2321 lexer(const lexer&) = delete;
2322 lexer& operator=(lexer&) = delete;
2323
2324 private:
2325 /////////////////////
2326 // locales
2327 /////////////////////
2328
2329 /// return the locale-dependent decimal point
get_decimal_point()2330 static char get_decimal_point() noexcept
2331 {
2332 const auto loc = localeconv();
2333 assert(loc != nullptr);
2334 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2335 }
2336
2337 /////////////////////
2338 // scan functions
2339 /////////////////////
2340
2341 /*!
2342 @brief get codepoint from 4 hex characters following `\u`
2343
2344 For input "\u c1 c2 c3 c4" the codepoint is:
2345 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
2346 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
2347
2348 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
2349 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
2350 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
2351 between the ASCII value of the character and the desired integer value.
2352
2353 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
2354 non-hex character)
2355 */
get_codepoint()2356 int get_codepoint()
2357 {
2358 // this function only makes sense after reading `\u`
2359 assert(current == 'u');
2360 int codepoint = 0;
2361
2362 const auto factors = { 12, 8, 4, 0 };
2363 for (const auto factor : factors)
2364 {
2365 get();
2366
2367 if (current >= '0' and current <= '9')
2368 {
2369 codepoint += ((current - 0x30) << factor);
2370 }
2371 else if (current >= 'A' and current <= 'F')
2372 {
2373 codepoint += ((current - 0x37) << factor);
2374 }
2375 else if (current >= 'a' and current <= 'f')
2376 {
2377 codepoint += ((current - 0x57) << factor);
2378 }
2379 else
2380 {
2381 return -1;
2382 }
2383 }
2384
2385 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2386 return codepoint;
2387 }
2388
2389 /*!
2390 @brief check if the next byte(s) are inside a given range
2391
2392 Adds the current byte and, for each passed range, reads a new byte and
2393 checks if it is inside the range. If a violation was detected, set up an
2394 error message and return false. Otherwise, return true.
2395
2396 @param[in] ranges list of integers; interpreted as list of pairs of
2397 inclusive lower and upper bound, respectively
2398
2399 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
2400 1, 2, or 3 pairs. This precondition is enforced by an assertion.
2401
2402 @return true if and only if no range violation was detected
2403 */
next_byte_in_range(std::initializer_list<int> ranges)2404 bool next_byte_in_range(std::initializer_list<int> ranges)
2405 {
2406 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2407 add(current);
2408
2409 for (auto range = ranges.begin(); range != ranges.end(); ++range)
2410 {
2411 get();
2412 if (JSON_LIKELY(*range <= current and current <= *(++range)))
2413 {
2414 add(current);
2415 }
2416 else
2417 {
2418 error_message = "invalid string: ill-formed UTF-8 byte";
2419 return false;
2420 }
2421 }
2422
2423 return true;
2424 }
2425
2426 /*!
2427 @brief scan a string literal
2428
2429 This function scans a string according to Sect. 7 of RFC 7159. While
2430 scanning, bytes are escaped and copied into buffer token_buffer. Then the
2431 function returns successfully, token_buffer is *not* null-terminated (as it
2432 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
2433 string.
2434
2435 @return token_type::value_string if string could be successfully scanned,
2436 token_type::parse_error otherwise
2437
2438 @note In case of errors, variable error_message contains a textual
2439 description.
2440 */
scan_string()2441 token_type scan_string()
2442 {
2443 // reset token_buffer (ignore opening quote)
2444 reset();
2445
2446 // we entered the function by reading an open quote
2447 assert(current == '\"');
2448
2449 while (true)
2450 {
2451 // get next character
2452 switch (get())
2453 {
2454 // end of file while parsing string
2455 case std::char_traits<char>::eof():
2456 {
2457 error_message = "invalid string: missing closing quote";
2458 return token_type::parse_error;
2459 }
2460
2461 // closing quote
2462 case '\"':
2463 {
2464 return token_type::value_string;
2465 }
2466
2467 // escapes
2468 case '\\':
2469 {
2470 switch (get())
2471 {
2472 // quotation mark
2473 case '\"':
2474 add('\"');
2475 break;
2476 // reverse solidus
2477 case '\\':
2478 add('\\');
2479 break;
2480 // solidus
2481 case '/':
2482 add('/');
2483 break;
2484 // backspace
2485 case 'b':
2486 add('\b');
2487 break;
2488 // form feed
2489 case 'f':
2490 add('\f');
2491 break;
2492 // line feed
2493 case 'n':
2494 add('\n');
2495 break;
2496 // carriage return
2497 case 'r':
2498 add('\r');
2499 break;
2500 // tab
2501 case 't':
2502 add('\t');
2503 break;
2504
2505 // unicode escapes
2506 case 'u':
2507 {
2508 const int codepoint1 = get_codepoint();
2509 int codepoint = codepoint1; // start with codepoint1
2510
2511 if (JSON_UNLIKELY(codepoint1 == -1))
2512 {
2513 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2514 return token_type::parse_error;
2515 }
2516
2517 // check if code point is a high surrogate
2518 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2519 {
2520 // expect next \uxxxx entry
2521 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2522 {
2523 const int codepoint2 = get_codepoint();
2524
2525 if (JSON_UNLIKELY(codepoint2 == -1))
2526 {
2527 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2528 return token_type::parse_error;
2529 }
2530
2531 // check if codepoint2 is a low surrogate
2532 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2533 {
2534 // overwrite codepoint
2535 codepoint =
2536 // high surrogate occupies the most significant 22 bits
2537 (codepoint1 << 10)
2538 // low surrogate occupies the least significant 15 bits
2539 + codepoint2
2540 // there is still the 0xD800, 0xDC00 and 0x10000 noise
2541 // in the result so we have to subtract with:
2542 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2543 - 0x35FDC00;
2544 }
2545 else
2546 {
2547 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2548 return token_type::parse_error;
2549 }
2550 }
2551 else
2552 {
2553 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2554 return token_type::parse_error;
2555 }
2556 }
2557 else
2558 {
2559 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2560 {
2561 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2562 return token_type::parse_error;
2563 }
2564 }
2565
2566 // result of the above calculation yields a proper codepoint
2567 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2568
2569 // translate codepoint into bytes
2570 if (codepoint < 0x80)
2571 {
2572 // 1-byte characters: 0xxxxxxx (ASCII)
2573 add(codepoint);
2574 }
2575 else if (codepoint <= 0x7FF)
2576 {
2577 // 2-byte characters: 110xxxxx 10xxxxxx
2578 add(0xC0 | (codepoint >> 6));
2579 add(0x80 | (codepoint & 0x3F));
2580 }
2581 else if (codepoint <= 0xFFFF)
2582 {
2583 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2584 add(0xE0 | (codepoint >> 12));
2585 add(0x80 | ((codepoint >> 6) & 0x3F));
2586 add(0x80 | (codepoint & 0x3F));
2587 }
2588 else
2589 {
2590 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2591 add(0xF0 | (codepoint >> 18));
2592 add(0x80 | ((codepoint >> 12) & 0x3F));
2593 add(0x80 | ((codepoint >> 6) & 0x3F));
2594 add(0x80 | (codepoint & 0x3F));
2595 }
2596
2597 break;
2598 }
2599
2600 // other characters after escape
2601 default:
2602 error_message = "invalid string: forbidden character after backslash";
2603 return token_type::parse_error;
2604 }
2605
2606 break;
2607 }
2608
2609 // invalid control characters
2610 case 0x00:
2611 case 0x01:
2612 case 0x02:
2613 case 0x03:
2614 case 0x04:
2615 case 0x05:
2616 case 0x06:
2617 case 0x07:
2618 case 0x08:
2619 case 0x09:
2620 case 0x0A:
2621 case 0x0B:
2622 case 0x0C:
2623 case 0x0D:
2624 case 0x0E:
2625 case 0x0F:
2626 case 0x10:
2627 case 0x11:
2628 case 0x12:
2629 case 0x13:
2630 case 0x14:
2631 case 0x15:
2632 case 0x16:
2633 case 0x17:
2634 case 0x18:
2635 case 0x19:
2636 case 0x1A:
2637 case 0x1B:
2638 case 0x1C:
2639 case 0x1D:
2640 case 0x1E:
2641 case 0x1F:
2642 {
2643 error_message = "invalid string: control character must be escaped";
2644 return token_type::parse_error;
2645 }
2646
2647 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2648 case 0x20:
2649 case 0x21:
2650 case 0x23:
2651 case 0x24:
2652 case 0x25:
2653 case 0x26:
2654 case 0x27:
2655 case 0x28:
2656 case 0x29:
2657 case 0x2A:
2658 case 0x2B:
2659 case 0x2C:
2660 case 0x2D:
2661 case 0x2E:
2662 case 0x2F:
2663 case 0x30:
2664 case 0x31:
2665 case 0x32:
2666 case 0x33:
2667 case 0x34:
2668 case 0x35:
2669 case 0x36:
2670 case 0x37:
2671 case 0x38:
2672 case 0x39:
2673 case 0x3A:
2674 case 0x3B:
2675 case 0x3C:
2676 case 0x3D:
2677 case 0x3E:
2678 case 0x3F:
2679 case 0x40:
2680 case 0x41:
2681 case 0x42:
2682 case 0x43:
2683 case 0x44:
2684 case 0x45:
2685 case 0x46:
2686 case 0x47:
2687 case 0x48:
2688 case 0x49:
2689 case 0x4A:
2690 case 0x4B:
2691 case 0x4C:
2692 case 0x4D:
2693 case 0x4E:
2694 case 0x4F:
2695 case 0x50:
2696 case 0x51:
2697 case 0x52:
2698 case 0x53:
2699 case 0x54:
2700 case 0x55:
2701 case 0x56:
2702 case 0x57:
2703 case 0x58:
2704 case 0x59:
2705 case 0x5A:
2706 case 0x5B:
2707 case 0x5D:
2708 case 0x5E:
2709 case 0x5F:
2710 case 0x60:
2711 case 0x61:
2712 case 0x62:
2713 case 0x63:
2714 case 0x64:
2715 case 0x65:
2716 case 0x66:
2717 case 0x67:
2718 case 0x68:
2719 case 0x69:
2720 case 0x6A:
2721 case 0x6B:
2722 case 0x6C:
2723 case 0x6D:
2724 case 0x6E:
2725 case 0x6F:
2726 case 0x70:
2727 case 0x71:
2728 case 0x72:
2729 case 0x73:
2730 case 0x74:
2731 case 0x75:
2732 case 0x76:
2733 case 0x77:
2734 case 0x78:
2735 case 0x79:
2736 case 0x7A:
2737 case 0x7B:
2738 case 0x7C:
2739 case 0x7D:
2740 case 0x7E:
2741 case 0x7F:
2742 {
2743 add(current);
2744 break;
2745 }
2746
2747 // U+0080..U+07FF: bytes C2..DF 80..BF
2748 case 0xC2:
2749 case 0xC3:
2750 case 0xC4:
2751 case 0xC5:
2752 case 0xC6:
2753 case 0xC7:
2754 case 0xC8:
2755 case 0xC9:
2756 case 0xCA:
2757 case 0xCB:
2758 case 0xCC:
2759 case 0xCD:
2760 case 0xCE:
2761 case 0xCF:
2762 case 0xD0:
2763 case 0xD1:
2764 case 0xD2:
2765 case 0xD3:
2766 case 0xD4:
2767 case 0xD5:
2768 case 0xD6:
2769 case 0xD7:
2770 case 0xD8:
2771 case 0xD9:
2772 case 0xDA:
2773 case 0xDB:
2774 case 0xDC:
2775 case 0xDD:
2776 case 0xDE:
2777 case 0xDF:
2778 {
2779 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2780 {
2781 return token_type::parse_error;
2782 }
2783 break;
2784 }
2785
2786 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2787 case 0xE0:
2788 {
2789 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2790 {
2791 return token_type::parse_error;
2792 }
2793 break;
2794 }
2795
2796 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2797 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2798 case 0xE1:
2799 case 0xE2:
2800 case 0xE3:
2801 case 0xE4:
2802 case 0xE5:
2803 case 0xE6:
2804 case 0xE7:
2805 case 0xE8:
2806 case 0xE9:
2807 case 0xEA:
2808 case 0xEB:
2809 case 0xEC:
2810 case 0xEE:
2811 case 0xEF:
2812 {
2813 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2814 {
2815 return token_type::parse_error;
2816 }
2817 break;
2818 }
2819
2820 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2821 case 0xED:
2822 {
2823 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2824 {
2825 return token_type::parse_error;
2826 }
2827 break;
2828 }
2829
2830 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2831 case 0xF0:
2832 {
2833 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2834 {
2835 return token_type::parse_error;
2836 }
2837 break;
2838 }
2839
2840 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2841 case 0xF1:
2842 case 0xF2:
2843 case 0xF3:
2844 {
2845 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2846 {
2847 return token_type::parse_error;
2848 }
2849 break;
2850 }
2851
2852 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2853 case 0xF4:
2854 {
2855 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2856 {
2857 return token_type::parse_error;
2858 }
2859 break;
2860 }
2861
2862 // remaining bytes (80..C1 and F5..FF) are ill-formed
2863 default:
2864 {
2865 error_message = "invalid string: ill-formed UTF-8 byte";
2866 return token_type::parse_error;
2867 }
2868 }
2869 }
2870 }
2871
strtof(float & f,const char * str,char ** endptr)2872 static void strtof(float& f, const char* str, char** endptr) noexcept
2873 {
2874 f = std::strtof(str, endptr);
2875 }
2876
strtof(double & f,const char * str,char ** endptr)2877 static void strtof(double& f, const char* str, char** endptr) noexcept
2878 {
2879 f = std::strtod(str, endptr);
2880 }
2881
strtof(long double & f,const char * str,char ** endptr)2882 static void strtof(long double& f, const char* str, char** endptr) noexcept
2883 {
2884 f = std::strtold(str, endptr);
2885 }
2886
2887 /*!
2888 @brief scan a number literal
2889
2890 This function scans a string according to Sect. 6 of RFC 7159.
2891
2892 The function is realized with a deterministic finite state machine derived
2893 from the grammar described in RFC 7159. Starting in state "init", the
2894 input is read and used to determined the next state. Only state "done"
2895 accepts the number. State "error" is a trap state to model errors. In the
2896 table below, "anything" means any character but the ones listed before.
2897
2898 state | 0 | 1-9 | e E | + | - | . | anything
2899 ---------|----------|----------|----------|---------|---------|----------|-----------
2900 init | zero | any1 | [error] | [error] | minus | [error] | [error]
2901 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
2902 zero | done | done | exponent | done | done | decimal1 | done
2903 any1 | any1 | any1 | exponent | done | done | decimal1 | done
2904 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
2905 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
2906 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
2907 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
2908 any2 | any2 | any2 | done | done | done | done | done
2909
2910 The state machine is realized with one label per state (prefixed with
2911 "scan_number_") and `goto` statements between them. The state machine
2912 contains cycles, but any cycle can be left when EOF is read. Therefore,
2913 the function is guaranteed to terminate.
2914
2915 During scanning, the read bytes are stored in token_buffer. This string is
2916 then converted to a signed integer, an unsigned integer, or a
2917 floating-point number.
2918
2919 @return token_type::value_unsigned, token_type::value_integer, or
2920 token_type::value_float if number could be successfully scanned,
2921 token_type::parse_error otherwise
2922
2923 @note The scanner is independent of the current locale. Internally, the
2924 locale's decimal point is used instead of `.` to work with the
2925 locale-dependent converters.
2926 */
scan_number()2927 token_type scan_number()
2928 {
2929 // reset token_buffer to store the number's bytes
2930 reset();
2931
2932 // the type of the parsed number; initially set to unsigned; will be
2933 // changed if minus sign, decimal point or exponent is read
2934 token_type number_type = token_type::value_unsigned;
2935
2936 // state (init): we just found out we need to scan a number
2937 switch (current)
2938 {
2939 case '-':
2940 {
2941 add(current);
2942 goto scan_number_minus;
2943 }
2944
2945 case '0':
2946 {
2947 add(current);
2948 goto scan_number_zero;
2949 }
2950
2951 case '1':
2952 case '2':
2953 case '3':
2954 case '4':
2955 case '5':
2956 case '6':
2957 case '7':
2958 case '8':
2959 case '9':
2960 {
2961 add(current);
2962 goto scan_number_any1;
2963 }
2964
2965 // LCOV_EXCL_START
2966 default:
2967 {
2968 // all other characters are rejected outside scan_number()
2969 assert(false);
2970 }
2971 // LCOV_EXCL_STOP
2972 }
2973
2974 scan_number_minus:
2975 // state: we just parsed a leading minus sign
2976 number_type = token_type::value_integer;
2977 switch (get())
2978 {
2979 case '0':
2980 {
2981 add(current);
2982 goto scan_number_zero;
2983 }
2984
2985 case '1':
2986 case '2':
2987 case '3':
2988 case '4':
2989 case '5':
2990 case '6':
2991 case '7':
2992 case '8':
2993 case '9':
2994 {
2995 add(current);
2996 goto scan_number_any1;
2997 }
2998
2999 default:
3000 {
3001 error_message = "invalid number; expected digit after '-'";
3002 return token_type::parse_error;
3003 }
3004 }
3005
3006 scan_number_zero:
3007 // state: we just parse a zero (maybe with a leading minus sign)
3008 switch (get())
3009 {
3010 case '.':
3011 {
3012 add(decimal_point_char);
3013 goto scan_number_decimal1;
3014 }
3015
3016 case 'e':
3017 case 'E':
3018 {
3019 add(current);
3020 goto scan_number_exponent;
3021 }
3022
3023 default:
3024 goto scan_number_done;
3025 }
3026
3027 scan_number_any1:
3028 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
3029 switch (get())
3030 {
3031 case '0':
3032 case '1':
3033 case '2':
3034 case '3':
3035 case '4':
3036 case '5':
3037 case '6':
3038 case '7':
3039 case '8':
3040 case '9':
3041 {
3042 add(current);
3043 goto scan_number_any1;
3044 }
3045
3046 case '.':
3047 {
3048 add(decimal_point_char);
3049 goto scan_number_decimal1;
3050 }
3051
3052 case 'e':
3053 case 'E':
3054 {
3055 add(current);
3056 goto scan_number_exponent;
3057 }
3058
3059 default:
3060 goto scan_number_done;
3061 }
3062
3063 scan_number_decimal1:
3064 // state: we just parsed a decimal point
3065 number_type = token_type::value_float;
3066 switch (get())
3067 {
3068 case '0':
3069 case '1':
3070 case '2':
3071 case '3':
3072 case '4':
3073 case '5':
3074 case '6':
3075 case '7':
3076 case '8':
3077 case '9':
3078 {
3079 add(current);
3080 goto scan_number_decimal2;
3081 }
3082
3083 default:
3084 {
3085 error_message = "invalid number; expected digit after '.'";
3086 return token_type::parse_error;
3087 }
3088 }
3089
3090 scan_number_decimal2:
3091 // we just parsed at least one number after a decimal point
3092 switch (get())
3093 {
3094 case '0':
3095 case '1':
3096 case '2':
3097 case '3':
3098 case '4':
3099 case '5':
3100 case '6':
3101 case '7':
3102 case '8':
3103 case '9':
3104 {
3105 add(current);
3106 goto scan_number_decimal2;
3107 }
3108
3109 case 'e':
3110 case 'E':
3111 {
3112 add(current);
3113 goto scan_number_exponent;
3114 }
3115
3116 default:
3117 goto scan_number_done;
3118 }
3119
3120 scan_number_exponent:
3121 // we just parsed an exponent
3122 number_type = token_type::value_float;
3123 switch (get())
3124 {
3125 case '+':
3126 case '-':
3127 {
3128 add(current);
3129 goto scan_number_sign;
3130 }
3131
3132 case '0':
3133 case '1':
3134 case '2':
3135 case '3':
3136 case '4':
3137 case '5':
3138 case '6':
3139 case '7':
3140 case '8':
3141 case '9':
3142 {
3143 add(current);
3144 goto scan_number_any2;
3145 }
3146
3147 default:
3148 {
3149 error_message =
3150 "invalid number; expected '+', '-', or digit after exponent";
3151 return token_type::parse_error;
3152 }
3153 }
3154
3155 scan_number_sign:
3156 // we just parsed an exponent sign
3157 switch (get())
3158 {
3159 case '0':
3160 case '1':
3161 case '2':
3162 case '3':
3163 case '4':
3164 case '5':
3165 case '6':
3166 case '7':
3167 case '8':
3168 case '9':
3169 {
3170 add(current);
3171 goto scan_number_any2;
3172 }
3173
3174 default:
3175 {
3176 error_message = "invalid number; expected digit after exponent sign";
3177 return token_type::parse_error;
3178 }
3179 }
3180
3181 scan_number_any2:
3182 // we just parsed a number after the exponent or exponent sign
3183 switch (get())
3184 {
3185 case '0':
3186 case '1':
3187 case '2':
3188 case '3':
3189 case '4':
3190 case '5':
3191 case '6':
3192 case '7':
3193 case '8':
3194 case '9':
3195 {
3196 add(current);
3197 goto scan_number_any2;
3198 }
3199
3200 default:
3201 goto scan_number_done;
3202 }
3203
3204 scan_number_done:
3205 // unget the character after the number (we only read it to know that
3206 // we are done scanning a number)
3207 unget();
3208
3209 char* endptr = nullptr;
3210 errno = 0;
3211
3212 // try to parse integers first and fall back to floats
3213 if (number_type == token_type::value_unsigned)
3214 {
3215 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3216
3217 // we checked the number format before
3218 assert(endptr == token_buffer.data() + token_buffer.size());
3219
3220 if (errno == 0)
3221 {
3222 value_unsigned = static_cast<number_unsigned_t>(x);
3223 if (value_unsigned == x)
3224 {
3225 return token_type::value_unsigned;
3226 }
3227 }
3228 }
3229 else if (number_type == token_type::value_integer)
3230 {
3231 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3232
3233 // we checked the number format before
3234 assert(endptr == token_buffer.data() + token_buffer.size());
3235
3236 if (errno == 0)
3237 {
3238 value_integer = static_cast<number_integer_t>(x);
3239 if (value_integer == x)
3240 {
3241 return token_type::value_integer;
3242 }
3243 }
3244 }
3245
3246 // this code is reached if we parse a floating-point number or if an
3247 // integer conversion above failed
3248 strtof(value_float, token_buffer.data(), &endptr);
3249
3250 // we checked the number format before
3251 assert(endptr == token_buffer.data() + token_buffer.size());
3252
3253 return token_type::value_float;
3254 }
3255
3256 /*!
3257 @param[in] literal_text the literal text to expect
3258 @param[in] length the length of the passed literal text
3259 @param[in] return_type the token type to return on success
3260 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)3261 token_type scan_literal(const char* literal_text, const std::size_t length,
3262 token_type return_type)
3263 {
3264 assert(current == literal_text[0]);
3265 for (std::size_t i = 1; i < length; ++i)
3266 {
3267 if (JSON_UNLIKELY(get() != literal_text[i]))
3268 {
3269 error_message = "invalid literal";
3270 return token_type::parse_error;
3271 }
3272 }
3273 return return_type;
3274 }
3275
3276 /////////////////////
3277 // input management
3278 /////////////////////
3279
3280 /// reset token_buffer; current character is beginning of token
reset()3281 void reset() noexcept
3282 {
3283 token_buffer.clear();
3284 token_string.clear();
3285 token_string.push_back(std::char_traits<char>::to_char_type(current));
3286 }
3287
3288 /*
3289 @brief get next character from the input
3290
3291 This function provides the interface to the used input adapter. It does
3292 not throw in case the input reached EOF, but returns a
3293 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
3294 for use in error messages.
3295
3296 @return character read from the input
3297 */
get()3298 std::char_traits<char>::int_type get()
3299 {
3300 ++chars_read;
3301 if (next_unget)
3302 {
3303 // just reset the next_unget variable and work with current
3304 next_unget = false;
3305 }
3306 else
3307 {
3308 current = ia->get_character();
3309 }
3310
3311 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3312 {
3313 token_string.push_back(std::char_traits<char>::to_char_type(current));
3314 }
3315 return current;
3316 }
3317
3318 /*!
3319 @brief unget current character (read it again on next get)
3320
3321 We implement unget by setting variable next_unget to true. The input is not
3322 changed - we just simulate ungetting by modifying chars_read and
3323 token_string. The next call to get() will behave as if the unget character
3324 is read again.
3325 */
unget()3326 void unget()
3327 {
3328 next_unget = true;
3329 --chars_read;
3330 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3331 {
3332 assert(token_string.size() != 0);
3333 token_string.pop_back();
3334 }
3335 }
3336
3337 /// add a character to token_buffer
add(int c)3338 void add(int c)
3339 {
3340 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3341 }
3342
3343 public:
3344 /////////////////////
3345 // value getters
3346 /////////////////////
3347
3348 /// return integer value
get_number_integer() const3349 constexpr number_integer_t get_number_integer() const noexcept
3350 {
3351 return value_integer;
3352 }
3353
3354 /// return unsigned integer value
get_number_unsigned() const3355 constexpr number_unsigned_t get_number_unsigned() const noexcept
3356 {
3357 return value_unsigned;
3358 }
3359
3360 /// return floating-point value
get_number_float() const3361 constexpr number_float_t get_number_float() const noexcept
3362 {
3363 return value_float;
3364 }
3365
3366 /// return current string value (implicitly resets the token; useful only once)
get_string()3367 string_t& get_string()
3368 {
3369 return token_buffer;
3370 }
3371
3372 /////////////////////
3373 // diagnostics
3374 /////////////////////
3375
3376 /// return position of last read token
get_position() const3377 constexpr std::size_t get_position() const noexcept
3378 {
3379 return chars_read;
3380 }
3381
3382 /// return the last read token (for errors only). Will never contain EOF
3383 /// (an arbitrary value that is not a valid char value, often -1), because
3384 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const3385 std::string get_token_string() const
3386 {
3387 // escape control characters
3388 std::string result;
3389 for (const auto c : token_string)
3390 {
3391 if ('\x00' <= c and c <= '\x1F')
3392 {
3393 // escape control characters
3394 char cs[9];
3395 snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
3396 result += cs;
3397 }
3398 else
3399 {
3400 // add character as is
3401 result.push_back(c);
3402 }
3403 }
3404
3405 return result;
3406 }
3407
3408 /// return syntax error message
get_error_message() const3409 constexpr const char* get_error_message() const noexcept
3410 {
3411 return error_message;
3412 }
3413
3414 /////////////////////
3415 // actual scanner
3416 /////////////////////
3417
3418 /*!
3419 @brief skip the UTF-8 byte order mark
3420 @return true iff there is no BOM or the correct BOM has been skipped
3421 */
skip_bom()3422 bool skip_bom()
3423 {
3424 if (get() == 0xEF)
3425 {
3426 if (get() == 0xBB and get() == 0xBF)
3427 {
3428 // we completely parsed the BOM
3429 return true;
3430 }
3431 else
3432 {
3433 // after reading 0xEF, an unexpected character followed
3434 return false;
3435 }
3436 }
3437 else
3438 {
3439 // the first character is not the beginning of the BOM; unget it to
3440 // process is later
3441 unget();
3442 return true;
3443 }
3444 }
3445
scan()3446 token_type scan()
3447 {
3448 // initially, skip the BOM
3449 if (chars_read == 0 and not skip_bom())
3450 {
3451 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
3452 return token_type::parse_error;
3453 }
3454
3455 // read next character and ignore whitespace
3456 do
3457 {
3458 get();
3459 }
3460 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3461
3462 switch (current)
3463 {
3464 // structural characters
3465 case '[':
3466 return token_type::begin_array;
3467 case ']':
3468 return token_type::end_array;
3469 case '{':
3470 return token_type::begin_object;
3471 case '}':
3472 return token_type::end_object;
3473 case ':':
3474 return token_type::name_separator;
3475 case ',':
3476 return token_type::value_separator;
3477
3478 // literals
3479 case 't':
3480 return scan_literal("true", 4, token_type::literal_true);
3481 case 'f':
3482 return scan_literal("false", 5, token_type::literal_false);
3483 case 'n':
3484 return scan_literal("null", 4, token_type::literal_null);
3485
3486 // string
3487 case '\"':
3488 return scan_string();
3489
3490 // number
3491 case '-':
3492 case '0':
3493 case '1':
3494 case '2':
3495 case '3':
3496 case '4':
3497 case '5':
3498 case '6':
3499 case '7':
3500 case '8':
3501 case '9':
3502 return scan_number();
3503
3504 // end of input (the null byte is needed when parsing from
3505 // string literals)
3506 case '\0':
3507 case std::char_traits<char>::eof():
3508 return token_type::end_of_input;
3509
3510 // error
3511 default:
3512 error_message = "invalid literal";
3513 return token_type::parse_error;
3514 }
3515 }
3516
3517 private:
3518 /// input adapter
3519 detail::input_adapter_t ia = nullptr;
3520
3521 /// the current character
3522 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3523
3524 /// whether the next get() call should just return current
3525 bool next_unget = false;
3526
3527 /// the number of characters read
3528 std::size_t chars_read = 0;
3529
3530 /// raw input token string (for error messages)
3531 std::vector<char> token_string {};
3532
3533 /// buffer for variable-length tokens (numbers, strings)
3534 string_t token_buffer {};
3535
3536 /// a description of occurred lexer errors
3537 const char* error_message = "";
3538
3539 // number values
3540 number_integer_t value_integer = 0;
3541 number_unsigned_t value_unsigned = 0;
3542 number_float_t value_float = 0;
3543
3544 /// the decimal point
3545 const char decimal_point_char = '.';
3546 };
3547 }
3548 }
3549
3550 // #include <nlohmann/detail/input/parser.hpp>
3551
3552
3553 #include <cassert> // assert
3554 #include <cmath> // isfinite
3555 #include <cstdint> // uint8_t
3556 #include <functional> // function
3557 #include <string> // string
3558 #include <utility> // move
3559
3560 // #include <nlohmann/detail/exceptions.hpp>
3561
3562 // #include <nlohmann/detail/macro_scope.hpp>
3563
3564 // #include <nlohmann/detail/meta/is_sax.hpp>
3565
3566
3567 #include <cstdint> // size_t
3568 #include <utility> // declval
3569
3570 // #include <nlohmann/detail/meta/detected.hpp>
3571
3572
3573 #include <type_traits>
3574
3575 // #include <nlohmann/detail/meta/void_t.hpp>
3576
3577
3578 namespace nlohmann
3579 {
3580 namespace detail
3581 {
3582 template <typename...>
3583 using void_t = void;
3584 }
3585 }
3586
3587
3588 // http://en.cppreference.com/w/cpp/experimental/is_detected
3589 namespace nlohmann
3590 {
3591 namespace detail
3592 {
3593 struct nonesuch
3594 {
3595 nonesuch() = delete;
3596 ~nonesuch() = delete;
3597 nonesuch(nonesuch const&) = delete;
3598 void operator=(nonesuch const&) = delete;
3599 };
3600
3601 template <class Default,
3602 class AlwaysVoid,
3603 template <class...> class Op,
3604 class... Args>
3605 struct detector
3606 {
3607 using value_t = std::false_type;
3608 using type = Default;
3609 };
3610
3611 template <class Default, template <class...> class Op, class... Args>
3612 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3613 {
3614 using value_t = std::true_type;
3615 using type = Op<Args...>;
3616 };
3617
3618 template <template <class...> class Op, class... Args>
3619 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3620
3621 template <template <class...> class Op, class... Args>
3622 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3623
3624 template <class Default, template <class...> class Op, class... Args>
3625 using detected_or = detector<Default, void, Op, Args...>;
3626
3627 template <class Default, template <class...> class Op, class... Args>
3628 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3629
3630 template <class Expected, template <class...> class Op, class... Args>
3631 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3632
3633 template <class To, template <class...> class Op, class... Args>
3634 using is_detected_convertible =
3635 std::is_convertible<detected_t<Op, Args...>, To>;
3636 }
3637 }
3638
3639 // #include <nlohmann/detail/meta/type_traits.hpp>
3640
3641
3642 namespace nlohmann
3643 {
3644 namespace detail
3645 {
3646 template <typename T>
3647 using null_function_t = decltype(std::declval<T&>().null());
3648
3649 template <typename T>
3650 using boolean_function_t =
3651 decltype(std::declval<T&>().boolean(std::declval<bool>()));
3652
3653 template <typename T, typename Integer>
3654 using number_integer_function_t =
3655 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3656
3657 template <typename T, typename Unsigned>
3658 using number_unsigned_function_t =
3659 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3660
3661 template <typename T, typename Float, typename String>
3662 using number_float_function_t = decltype(std::declval<T&>().number_float(
3663 std::declval<Float>(), std::declval<const String&>()));
3664
3665 template <typename T, typename String>
3666 using string_function_t =
3667 decltype(std::declval<T&>().string(std::declval<String&>()));
3668
3669 template <typename T>
3670 using start_object_function_t =
3671 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3672
3673 template <typename T, typename String>
3674 using key_function_t =
3675 decltype(std::declval<T&>().key(std::declval<String&>()));
3676
3677 template <typename T>
3678 using end_object_function_t = decltype(std::declval<T&>().end_object());
3679
3680 template <typename T>
3681 using start_array_function_t =
3682 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3683
3684 template <typename T>
3685 using end_array_function_t = decltype(std::declval<T&>().end_array());
3686
3687 template <typename T, typename Exception>
3688 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3689 std::declval<std::size_t>(), std::declval<const std::string&>(),
3690 std::declval<const Exception&>()));
3691
3692 template <typename SAX, typename BasicJsonType>
3693 struct is_sax
3694 {
3695 private:
3696 static_assert(is_basic_json<BasicJsonType>::value,
3697 "BasicJsonType must be of type basic_json<...>");
3698
3699 using number_integer_t = typename BasicJsonType::number_integer_t;
3700 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3701 using number_float_t = typename BasicJsonType::number_float_t;
3702 using string_t = typename BasicJsonType::string_t;
3703 using exception_t = typename BasicJsonType::exception;
3704
3705 public:
3706 static constexpr bool value =
3707 is_detected_exact<bool, null_function_t, SAX>::value &&
3708 is_detected_exact<bool, boolean_function_t, SAX>::value &&
3709 is_detected_exact<bool, number_integer_function_t, SAX,
3710 number_integer_t>::value &&
3711 is_detected_exact<bool, number_unsigned_function_t, SAX,
3712 number_unsigned_t>::value &&
3713 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3714 string_t>::value &&
3715 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3716 is_detected_exact<bool, start_object_function_t, SAX>::value &&
3717 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3718 is_detected_exact<bool, end_object_function_t, SAX>::value &&
3719 is_detected_exact<bool, start_array_function_t, SAX>::value &&
3720 is_detected_exact<bool, end_array_function_t, SAX>::value &&
3721 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3722 };
3723
3724 template <typename SAX, typename BasicJsonType>
3725 struct is_sax_static_asserts
3726 {
3727 private:
3728 static_assert(is_basic_json<BasicJsonType>::value,
3729 "BasicJsonType must be of type basic_json<...>");
3730
3731 using number_integer_t = typename BasicJsonType::number_integer_t;
3732 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3733 using number_float_t = typename BasicJsonType::number_float_t;
3734 using string_t = typename BasicJsonType::string_t;
3735 using exception_t = typename BasicJsonType::exception;
3736
3737 public:
3738 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3739 "Missing/invalid function: bool null()");
3740 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3741 "Missing/invalid function: bool boolean(bool)");
3742 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3743 "Missing/invalid function: bool boolean(bool)");
3744 static_assert(
3745 is_detected_exact<bool, number_integer_function_t, SAX,
3746 number_integer_t>::value,
3747 "Missing/invalid function: bool number_integer(number_integer_t)");
3748 static_assert(
3749 is_detected_exact<bool, number_unsigned_function_t, SAX,
3750 number_unsigned_t>::value,
3751 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3752 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3753 number_float_t, string_t>::value,
3754 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3755 static_assert(
3756 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3757 "Missing/invalid function: bool string(string_t&)");
3758 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3759 "Missing/invalid function: bool start_object(std::size_t)");
3760 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3761 "Missing/invalid function: bool key(string_t&)");
3762 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3763 "Missing/invalid function: bool end_object()");
3764 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3765 "Missing/invalid function: bool start_array(std::size_t)");
3766 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3767 "Missing/invalid function: bool end_array()");
3768 static_assert(
3769 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3770 "Missing/invalid function: bool parse_error(std::size_t, const "
3771 "std::string&, const exception&)");
3772 };
3773 }
3774 }
3775
3776 // #include <nlohmann/detail/input/input_adapters.hpp>
3777
3778 // #include <nlohmann/detail/input/json_sax.hpp>
3779
3780
3781 #include <cstddef>
3782 #include <string>
3783 #include <vector>
3784
3785 // #include <nlohmann/detail/input/parser.hpp>
3786
3787 // #include <nlohmann/detail/exceptions.hpp>
3788
3789
3790 namespace nlohmann
3791 {
3792
3793 /*!
3794 @brief SAX interface
3795
3796 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
3797 Each function is called in different situations while the input is parsed. The
3798 boolean return value informs the parser whether to continue processing the
3799 input.
3800 */
3801 template<typename BasicJsonType>
3802 struct json_sax
3803 {
3804 /// type for (signed) integers
3805 using number_integer_t = typename BasicJsonType::number_integer_t;
3806 /// type for unsigned integers
3807 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3808 /// type for floating-point numbers
3809 using number_float_t = typename BasicJsonType::number_float_t;
3810 /// type for strings
3811 using string_t = typename BasicJsonType::string_t;
3812
3813 /*!
3814 @brief a null value was read
3815 @return whether parsing should proceed
3816 */
3817 virtual bool null() = 0;
3818
3819 /*!
3820 @brief a boolean value was read
3821 @param[in] val boolean value
3822 @return whether parsing should proceed
3823 */
3824 virtual bool boolean(bool val) = 0;
3825
3826 /*!
3827 @brief an integer number was read
3828 @param[in] val integer value
3829 @return whether parsing should proceed
3830 */
3831 virtual bool number_integer(number_integer_t val) = 0;
3832
3833 /*!
3834 @brief an unsigned integer number was read
3835 @param[in] val unsigned integer value
3836 @return whether parsing should proceed
3837 */
3838 virtual bool number_unsigned(number_unsigned_t val) = 0;
3839
3840 /*!
3841 @brief an floating-point number was read
3842 @param[in] val floating-point value
3843 @param[in] s raw token value
3844 @return whether parsing should proceed
3845 */
3846 virtual bool number_float(number_float_t val, const string_t& s) = 0;
3847
3848 /*!
3849 @brief a string was read
3850 @param[in] val string value
3851 @return whether parsing should proceed
3852 @note It is safe to move the passed string.
3853 */
3854 virtual bool string(string_t& val) = 0;
3855
3856 /*!
3857 @brief the beginning of an object was read
3858 @param[in] elements number of object elements or -1 if unknown
3859 @return whether parsing should proceed
3860 @note binary formats may report the number of elements
3861 */
3862 virtual bool start_object(std::size_t elements) = 0;
3863
3864 /*!
3865 @brief an object key was read
3866 @param[in] val object key
3867 @return whether parsing should proceed
3868 @note It is safe to move the passed string.
3869 */
3870 virtual bool key(string_t& val) = 0;
3871
3872 /*!
3873 @brief the end of an object was read
3874 @return whether parsing should proceed
3875 */
3876 virtual bool end_object() = 0;
3877
3878 /*!
3879 @brief the beginning of an array was read
3880 @param[in] elements number of array elements or -1 if unknown
3881 @return whether parsing should proceed
3882 @note binary formats may report the number of elements
3883 */
3884 virtual bool start_array(std::size_t elements) = 0;
3885
3886 /*!
3887 @brief the end of an array was read
3888 @return whether parsing should proceed
3889 */
3890 virtual bool end_array() = 0;
3891
3892 /*!
3893 @brief a parse error occurred
3894 @param[in] position the position in the input where the error occurs
3895 @param[in] last_token the last read token
3896 @param[in] error_msg a detailed error message
3897 @return whether parsing should proceed (must return false)
3898 */
3899 virtual bool parse_error(std::size_t position,
3900 const std::string& last_token,
3901 const detail::exception& ex) = 0;
3902
3903 virtual ~json_sax() = default;
3904 };
3905
3906
3907 namespace detail
3908 {
3909 /*!
3910 @brief SAX implementation to create a JSON value from SAX events
3911
3912 This class implements the @ref json_sax interface and processes the SAX events
3913 to create a JSON value which makes it basically a DOM parser. The structure or
3914 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
3915 a pointer to the respective array or object for each recursion depth.
3916
3917 After successful parsing, the value that is passed by reference to the
3918 constructor contains the parsed value.
3919
3920 @tparam BasicJsonType the JSON type
3921 */
3922 template<typename BasicJsonType>
3923 class json_sax_dom_parser
3924 {
3925 public:
3926 using number_integer_t = typename BasicJsonType::number_integer_t;
3927 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3928 using number_float_t = typename BasicJsonType::number_float_t;
3929 using string_t = typename BasicJsonType::string_t;
3930
3931 /*!
3932 @param[in, out] r reference to a JSON value that is manipulated while
3933 parsing
3934 @param[in] allow_exceptions_ whether parse errors yield exceptions
3935 */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)3936 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
3937 : root(r), allow_exceptions(allow_exceptions_)
3938 {}
3939
null()3940 bool null()
3941 {
3942 handle_value(nullptr);
3943 return true;
3944 }
3945
boolean(bool val)3946 bool boolean(bool val)
3947 {
3948 handle_value(val);
3949 return true;
3950 }
3951
number_integer(number_integer_t val)3952 bool number_integer(number_integer_t val)
3953 {
3954 handle_value(val);
3955 return true;
3956 }
3957
number_unsigned(number_unsigned_t val)3958 bool number_unsigned(number_unsigned_t val)
3959 {
3960 handle_value(val);
3961 return true;
3962 }
3963
number_float(number_float_t val,const string_t &)3964 bool number_float(number_float_t val, const string_t&)
3965 {
3966 handle_value(val);
3967 return true;
3968 }
3969
string(string_t & val)3970 bool string(string_t& val)
3971 {
3972 handle_value(val);
3973 return true;
3974 }
3975
start_object(std::size_t len)3976 bool start_object(std::size_t len)
3977 {
3978 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
3979
3980 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3981 {
3982 JSON_THROW(out_of_range::create(408,
3983 "excessive object size: " + std::to_string(len)));
3984 }
3985
3986 return true;
3987 }
3988
key(string_t & val)3989 bool key(string_t& val)
3990 {
3991 // add null at given key and store the reference for later
3992 object_element = &(ref_stack.back()->m_value.object->operator[](val));
3993 return true;
3994 }
3995
end_object()3996 bool end_object()
3997 {
3998 ref_stack.pop_back();
3999 return true;
4000 }
4001
start_array(std::size_t len)4002 bool start_array(std::size_t len)
4003 {
4004 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4005
4006 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4007 {
4008 JSON_THROW(out_of_range::create(408,
4009 "excessive array size: " + std::to_string(len)));
4010 }
4011
4012 return true;
4013 }
4014
end_array()4015 bool end_array()
4016 {
4017 ref_stack.pop_back();
4018 return true;
4019 }
4020
parse_error(std::size_t,const std::string &,const detail::exception & ex)4021 bool parse_error(std::size_t, const std::string&,
4022 const detail::exception& ex)
4023 {
4024 errored = true;
4025 if (allow_exceptions)
4026 {
4027 // determine the proper exception type from the id
4028 switch ((ex.id / 100) % 100)
4029 {
4030 case 1:
4031 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4032 case 4:
4033 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4034 // LCOV_EXCL_START
4035 case 2:
4036 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4037 case 3:
4038 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4039 case 5:
4040 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4041 default:
4042 assert(false);
4043 // LCOV_EXCL_STOP
4044 }
4045 }
4046 return false;
4047 }
4048
is_errored() const4049 constexpr bool is_errored() const
4050 {
4051 return errored;
4052 }
4053
4054 private:
4055 /*!
4056 @invariant If the ref stack is empty, then the passed value will be the new
4057 root.
4058 @invariant If the ref stack contains a value, then it is an array or an
4059 object to which we can add elements
4060 */
4061 template<typename Value>
handle_value(Value && v)4062 BasicJsonType* handle_value(Value&& v)
4063 {
4064 if (ref_stack.empty())
4065 {
4066 root = BasicJsonType(std::forward<Value>(v));
4067 return &root;
4068 }
4069 else
4070 {
4071 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4072 if (ref_stack.back()->is_array())
4073 {
4074 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4075 return &(ref_stack.back()->m_value.array->back());
4076 }
4077 else
4078 {
4079 assert(object_element);
4080 *object_element = BasicJsonType(std::forward<Value>(v));
4081 return object_element;
4082 }
4083 }
4084 }
4085
4086 /// the parsed JSON value
4087 BasicJsonType& root;
4088 /// stack to model hierarchy of values
4089 std::vector<BasicJsonType*> ref_stack;
4090 /// helper to hold the reference for the next object element
4091 BasicJsonType* object_element = nullptr;
4092 /// whether a syntax error occurred
4093 bool errored = false;
4094 /// whether to throw exceptions in case of errors
4095 const bool allow_exceptions = true;
4096 };
4097
4098 template<typename BasicJsonType>
4099 class json_sax_dom_callback_parser
4100 {
4101 public:
4102 using number_integer_t = typename BasicJsonType::number_integer_t;
4103 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4104 using number_float_t = typename BasicJsonType::number_float_t;
4105 using string_t = typename BasicJsonType::string_t;
4106 using parser_callback_t = typename BasicJsonType::parser_callback_t;
4107 using parse_event_t = typename BasicJsonType::parse_event_t;
4108
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)4109 json_sax_dom_callback_parser(BasicJsonType& r,
4110 const parser_callback_t cb,
4111 const bool allow_exceptions_ = true)
4112 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4113 {
4114 keep_stack.push_back(true);
4115 }
4116
null()4117 bool null()
4118 {
4119 handle_value(nullptr);
4120 return true;
4121 }
4122
boolean(bool val)4123 bool boolean(bool val)
4124 {
4125 handle_value(val);
4126 return true;
4127 }
4128
number_integer(number_integer_t val)4129 bool number_integer(number_integer_t val)
4130 {
4131 handle_value(val);
4132 return true;
4133 }
4134
number_unsigned(number_unsigned_t val)4135 bool number_unsigned(number_unsigned_t val)
4136 {
4137 handle_value(val);
4138 return true;
4139 }
4140
number_float(number_float_t val,const string_t &)4141 bool number_float(number_float_t val, const string_t&)
4142 {
4143 handle_value(val);
4144 return true;
4145 }
4146
string(string_t & val)4147 bool string(string_t& val)
4148 {
4149 handle_value(val);
4150 return true;
4151 }
4152
start_object(std::size_t len)4153 bool start_object(std::size_t len)
4154 {
4155 // check callback for object start
4156 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4157 keep_stack.push_back(keep);
4158
4159 auto val = handle_value(BasicJsonType::value_t::object, true);
4160 ref_stack.push_back(val.second);
4161
4162 // check object limit
4163 if (ref_stack.back())
4164 {
4165 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4166 {
4167 JSON_THROW(out_of_range::create(408,
4168 "excessive object size: " + std::to_string(len)));
4169 }
4170 }
4171
4172 return true;
4173 }
4174
key(string_t & val)4175 bool key(string_t& val)
4176 {
4177 BasicJsonType k = BasicJsonType(val);
4178
4179 // check callback for key
4180 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4181 key_keep_stack.push_back(keep);
4182
4183 // add discarded value at given key and store the reference for later
4184 if (keep and ref_stack.back())
4185 {
4186 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4187 }
4188
4189 return true;
4190 }
4191
end_object()4192 bool end_object()
4193 {
4194 if (ref_stack.back())
4195 {
4196 if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4197 {
4198 // discard object
4199 *ref_stack.back() = discarded;
4200 }
4201 }
4202
4203 assert(not ref_stack.empty());
4204 assert(not keep_stack.empty());
4205 ref_stack.pop_back();
4206 keep_stack.pop_back();
4207
4208 if (not ref_stack.empty() and ref_stack.back())
4209 {
4210 // remove discarded value
4211 if (ref_stack.back()->is_object())
4212 {
4213 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4214 {
4215 if (it->is_discarded())
4216 {
4217 ref_stack.back()->erase(it);
4218 break;
4219 }
4220 }
4221 }
4222 }
4223
4224 return true;
4225 }
4226
start_array(std::size_t len)4227 bool start_array(std::size_t len)
4228 {
4229 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4230 keep_stack.push_back(keep);
4231
4232 auto val = handle_value(BasicJsonType::value_t::array, true);
4233 ref_stack.push_back(val.second);
4234
4235 // check array limit
4236 if (ref_stack.back())
4237 {
4238 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4239 {
4240 JSON_THROW(out_of_range::create(408,
4241 "excessive array size: " + std::to_string(len)));
4242 }
4243 }
4244
4245 return true;
4246 }
4247
end_array()4248 bool end_array()
4249 {
4250 bool keep = true;
4251
4252 if (ref_stack.back())
4253 {
4254 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4255 if (not keep)
4256 {
4257 // discard array
4258 *ref_stack.back() = discarded;
4259 }
4260 }
4261
4262 assert(not ref_stack.empty());
4263 assert(not keep_stack.empty());
4264 ref_stack.pop_back();
4265 keep_stack.pop_back();
4266
4267 // remove discarded value
4268 if (not keep and not ref_stack.empty())
4269 {
4270 if (ref_stack.back()->is_array())
4271 {
4272 ref_stack.back()->m_value.array->pop_back();
4273 }
4274 }
4275
4276 return true;
4277 }
4278
parse_error(std::size_t,const std::string &,const detail::exception & ex)4279 bool parse_error(std::size_t, const std::string&,
4280 const detail::exception& ex)
4281 {
4282 errored = true;
4283 if (allow_exceptions)
4284 {
4285 // determine the proper exception type from the id
4286 switch ((ex.id / 100) % 100)
4287 {
4288 case 1:
4289 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4290 case 4:
4291 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4292 // LCOV_EXCL_START
4293 case 2:
4294 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4295 case 3:
4296 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4297 case 5:
4298 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4299 default:
4300 assert(false);
4301 // LCOV_EXCL_STOP
4302 }
4303 }
4304 return false;
4305 }
4306
is_errored() const4307 constexpr bool is_errored() const
4308 {
4309 return errored;
4310 }
4311
4312 private:
4313 /*!
4314 @param[in] v value to add to the JSON value we build during parsing
4315 @param[in] skip_callback whether we should skip calling the callback
4316 function; this is required after start_array() and
4317 start_object() SAX events, because otherwise we would call the
4318 callback function with an empty array or object, respectively.
4319
4320 @invariant If the ref stack is empty, then the passed value will be the new
4321 root.
4322 @invariant If the ref stack contains a value, then it is an array or an
4323 object to which we can add elements
4324
4325 @return pair of boolean (whether value should be kept) and pointer (to the
4326 passed value in the ref_stack hierarchy; nullptr if not kept)
4327 */
4328 template<typename Value>
handle_value(Value && v,const bool skip_callback=false)4329 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4330 {
4331 assert(not keep_stack.empty());
4332
4333 // do not handle this value if we know it would be added to a discarded
4334 // container
4335 if (not keep_stack.back())
4336 {
4337 return {false, nullptr};
4338 }
4339
4340 // create value
4341 auto value = BasicJsonType(std::forward<Value>(v));
4342
4343 // check callback
4344 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4345
4346 // do not handle this value if we just learnt it shall be discarded
4347 if (not keep)
4348 {
4349 return {false, nullptr};
4350 }
4351
4352 if (ref_stack.empty())
4353 {
4354 root = std::move(value);
4355 return {true, &root};
4356 }
4357 else
4358 {
4359 // skip this value if we already decided to skip the parent
4360 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4361 if (not ref_stack.back())
4362 {
4363 return {false, nullptr};
4364 }
4365
4366 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4367 if (ref_stack.back()->is_array())
4368 {
4369 ref_stack.back()->m_value.array->push_back(std::move(value));
4370 return {true, &(ref_stack.back()->m_value.array->back())};
4371 }
4372 else
4373 {
4374 // check if we should store an element for the current key
4375 assert(not key_keep_stack.empty());
4376 const bool store_element = key_keep_stack.back();
4377 key_keep_stack.pop_back();
4378
4379 if (not store_element)
4380 {
4381 return {false, nullptr};
4382 }
4383
4384 assert(object_element);
4385 *object_element = std::move(value);
4386 return {true, object_element};
4387 }
4388 }
4389 }
4390
4391 /// the parsed JSON value
4392 BasicJsonType& root;
4393 /// stack to model hierarchy of values
4394 std::vector<BasicJsonType*> ref_stack;
4395 /// stack to manage which values to keep
4396 std::vector<bool> keep_stack;
4397 /// stack to manage which object keys to keep
4398 std::vector<bool> key_keep_stack;
4399 /// helper to hold the reference for the next object element
4400 BasicJsonType* object_element = nullptr;
4401 /// whether a syntax error occurred
4402 bool errored = false;
4403 /// callback function
4404 const parser_callback_t callback = nullptr;
4405 /// whether to throw exceptions in case of errors
4406 const bool allow_exceptions = true;
4407 /// a discarded value for the callback
4408 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4409 };
4410
4411 template<typename BasicJsonType>
4412 class json_sax_acceptor
4413 {
4414 public:
4415 using number_integer_t = typename BasicJsonType::number_integer_t;
4416 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4417 using number_float_t = typename BasicJsonType::number_float_t;
4418 using string_t = typename BasicJsonType::string_t;
4419
null()4420 bool null()
4421 {
4422 return true;
4423 }
4424
boolean(bool)4425 bool boolean(bool)
4426 {
4427 return true;
4428 }
4429
number_integer(number_integer_t)4430 bool number_integer(number_integer_t)
4431 {
4432 return true;
4433 }
4434
number_unsigned(number_unsigned_t)4435 bool number_unsigned(number_unsigned_t)
4436 {
4437 return true;
4438 }
4439
number_float(number_float_t,const string_t &)4440 bool number_float(number_float_t, const string_t&)
4441 {
4442 return true;
4443 }
4444
string(string_t &)4445 bool string(string_t&)
4446 {
4447 return true;
4448 }
4449
start_object(std::size_t=std::size_t (-1))4450 bool start_object(std::size_t = std::size_t(-1))
4451 {
4452 return true;
4453 }
4454
key(string_t &)4455 bool key(string_t&)
4456 {
4457 return true;
4458 }
4459
end_object()4460 bool end_object()
4461 {
4462 return true;
4463 }
4464
start_array(std::size_t=std::size_t (-1))4465 bool start_array(std::size_t = std::size_t(-1))
4466 {
4467 return true;
4468 }
4469
end_array()4470 bool end_array()
4471 {
4472 return true;
4473 }
4474
parse_error(std::size_t,const std::string &,const detail::exception &)4475 bool parse_error(std::size_t, const std::string&, const detail::exception&)
4476 {
4477 return false;
4478 }
4479 };
4480 }
4481
4482 }
4483
4484 // #include <nlohmann/detail/input/lexer.hpp>
4485
4486 // #include <nlohmann/detail/value_t.hpp>
4487
4488
4489 namespace nlohmann
4490 {
4491 namespace detail
4492 {
4493 ////////////
4494 // parser //
4495 ////////////
4496
4497 /*!
4498 @brief syntax analysis
4499
4500 This class implements a recursive decent parser.
4501 */
4502 template<typename BasicJsonType>
4503 class parser
4504 {
4505 using number_integer_t = typename BasicJsonType::number_integer_t;
4506 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4507 using number_float_t = typename BasicJsonType::number_float_t;
4508 using string_t = typename BasicJsonType::string_t;
4509 using lexer_t = lexer<BasicJsonType>;
4510 using token_type = typename lexer_t::token_type;
4511
4512 public:
4513 enum class parse_event_t : uint8_t
4514 {
4515 /// the parser read `{` and started to process a JSON object
4516 object_start,
4517 /// the parser read `}` and finished processing a JSON object
4518 object_end,
4519 /// the parser read `[` and started to process a JSON array
4520 array_start,
4521 /// the parser read `]` and finished processing a JSON array
4522 array_end,
4523 /// the parser read a key of a value in an object
4524 key,
4525 /// the parser finished reading a JSON value
4526 value
4527 };
4528
4529 using parser_callback_t =
4530 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4531
4532 /// a parser reading from an input adapter
parser(detail::input_adapter_t && adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)4533 explicit parser(detail::input_adapter_t&& adapter,
4534 const parser_callback_t cb = nullptr,
4535 const bool allow_exceptions_ = true)
4536 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
4537 {
4538 // read first token
4539 get_token();
4540 }
4541
4542 /*!
4543 @brief public parser interface
4544
4545 @param[in] strict whether to expect the last token to be EOF
4546 @param[in,out] result parsed JSON value
4547
4548 @throw parse_error.101 in case of an unexpected token
4549 @throw parse_error.102 if to_unicode fails or surrogate error
4550 @throw parse_error.103 if to_unicode fails
4551 */
parse(const bool strict,BasicJsonType & result)4552 void parse(const bool strict, BasicJsonType& result)
4553 {
4554 if (callback)
4555 {
4556 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
4557 sax_parse_internal(&sdp);
4558 result.assert_invariant();
4559
4560 // in strict mode, input must be completely read
4561 if (strict and (get_token() != token_type::end_of_input))
4562 {
4563 sdp.parse_error(m_lexer.get_position(),
4564 m_lexer.get_token_string(),
4565 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4566 }
4567
4568 // in case of an error, return discarded value
4569 if (sdp.is_errored())
4570 {
4571 result = value_t::discarded;
4572 return;
4573 }
4574
4575 // set top-level value to null if it was discarded by the callback
4576 // function
4577 if (result.is_discarded())
4578 {
4579 result = nullptr;
4580 }
4581 }
4582 else
4583 {
4584 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
4585 sax_parse_internal(&sdp);
4586 result.assert_invariant();
4587
4588 // in strict mode, input must be completely read
4589 if (strict and (get_token() != token_type::end_of_input))
4590 {
4591 sdp.parse_error(m_lexer.get_position(),
4592 m_lexer.get_token_string(),
4593 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4594 }
4595
4596 // in case of an error, return discarded value
4597 if (sdp.is_errored())
4598 {
4599 result = value_t::discarded;
4600 return;
4601 }
4602 }
4603 }
4604
4605 /*!
4606 @brief public accept interface
4607
4608 @param[in] strict whether to expect the last token to be EOF
4609 @return whether the input is a proper JSON text
4610 */
accept(const bool strict=true)4611 bool accept(const bool strict = true)
4612 {
4613 json_sax_acceptor<BasicJsonType> sax_acceptor;
4614 return sax_parse(&sax_acceptor, strict);
4615 }
4616
4617 template <typename SAX>
sax_parse(SAX * sax,const bool strict=true)4618 bool sax_parse(SAX* sax, const bool strict = true)
4619 {
4620 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
4621 const bool result = sax_parse_internal(sax);
4622
4623 // strict mode: next byte must be EOF
4624 if (result and strict and (get_token() != token_type::end_of_input))
4625 {
4626 return sax->parse_error(m_lexer.get_position(),
4627 m_lexer.get_token_string(),
4628 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4629 }
4630
4631 return result;
4632 }
4633
4634 private:
4635 template <typename SAX>
sax_parse_internal(SAX * sax)4636 bool sax_parse_internal(SAX* sax)
4637 {
4638 // stack to remember the hieararchy of structured values we are parsing
4639 // true = array; false = object
4640 std::vector<bool> states;
4641 // value to avoid a goto (see comment where set to true)
4642 bool skip_to_state_evaluation = false;
4643
4644 while (true)
4645 {
4646 if (not skip_to_state_evaluation)
4647 {
4648 // invariant: get_token() was called before each iteration
4649 switch (last_token)
4650 {
4651 case token_type::begin_object:
4652 {
4653 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
4654 {
4655 return false;
4656 }
4657
4658 // closing } -> we are done
4659 if (get_token() == token_type::end_object)
4660 {
4661 if (JSON_UNLIKELY(not sax->end_object()))
4662 {
4663 return false;
4664 }
4665 break;
4666 }
4667
4668 // parse key
4669 if (JSON_UNLIKELY(last_token != token_type::value_string))
4670 {
4671 return sax->parse_error(m_lexer.get_position(),
4672 m_lexer.get_token_string(),
4673 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4674 }
4675 else
4676 {
4677 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4678 {
4679 return false;
4680 }
4681 }
4682
4683 // parse separator (:)
4684 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
4685 {
4686 return sax->parse_error(m_lexer.get_position(),
4687 m_lexer.get_token_string(),
4688 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator)));
4689 }
4690
4691 // remember we are now inside an object
4692 states.push_back(false);
4693
4694 // parse values
4695 get_token();
4696 continue;
4697 }
4698
4699 case token_type::begin_array:
4700 {
4701 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
4702 {
4703 return false;
4704 }
4705
4706 // closing ] -> we are done
4707 if (get_token() == token_type::end_array)
4708 {
4709 if (JSON_UNLIKELY(not sax->end_array()))
4710 {
4711 return false;
4712 }
4713 break;
4714 }
4715
4716 // remember we are now inside an array
4717 states.push_back(true);
4718
4719 // parse values (no need to call get_token)
4720 continue;
4721 }
4722
4723 case token_type::value_float:
4724 {
4725 const auto res = m_lexer.get_number_float();
4726
4727 if (JSON_UNLIKELY(not std::isfinite(res)))
4728 {
4729 return sax->parse_error(m_lexer.get_position(),
4730 m_lexer.get_token_string(),
4731 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
4732 }
4733 else
4734 {
4735 if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
4736 {
4737 return false;
4738 }
4739 break;
4740 }
4741 }
4742
4743 case token_type::literal_false:
4744 {
4745 if (JSON_UNLIKELY(not sax->boolean(false)))
4746 {
4747 return false;
4748 }
4749 break;
4750 }
4751
4752 case token_type::literal_null:
4753 {
4754 if (JSON_UNLIKELY(not sax->null()))
4755 {
4756 return false;
4757 }
4758 break;
4759 }
4760
4761 case token_type::literal_true:
4762 {
4763 if (JSON_UNLIKELY(not sax->boolean(true)))
4764 {
4765 return false;
4766 }
4767 break;
4768 }
4769
4770 case token_type::value_integer:
4771 {
4772 if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
4773 {
4774 return false;
4775 }
4776 break;
4777 }
4778
4779 case token_type::value_string:
4780 {
4781 if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
4782 {
4783 return false;
4784 }
4785 break;
4786 }
4787
4788 case token_type::value_unsigned:
4789 {
4790 if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
4791 {
4792 return false;
4793 }
4794 break;
4795 }
4796
4797 case token_type::parse_error:
4798 {
4799 // using "uninitialized" to avoid "expected" message
4800 return sax->parse_error(m_lexer.get_position(),
4801 m_lexer.get_token_string(),
4802 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized)));
4803 }
4804
4805 default: // the last token was unexpected
4806 {
4807 return sax->parse_error(m_lexer.get_position(),
4808 m_lexer.get_token_string(),
4809 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value)));
4810 }
4811 }
4812 }
4813 else
4814 {
4815 skip_to_state_evaluation = false;
4816 }
4817
4818 // we reached this line after we successfully parsed a value
4819 if (states.empty())
4820 {
4821 // empty stack: we reached the end of the hieararchy: done
4822 return true;
4823 }
4824 else
4825 {
4826 if (states.back()) // array
4827 {
4828 // comma -> next value
4829 if (get_token() == token_type::value_separator)
4830 {
4831 // parse a new value
4832 get_token();
4833 continue;
4834 }
4835
4836 // closing ]
4837 if (JSON_LIKELY(last_token == token_type::end_array))
4838 {
4839 if (JSON_UNLIKELY(not sax->end_array()))
4840 {
4841 return false;
4842 }
4843
4844 // We are done with this array. Before we can parse a
4845 // new value, we need to evaluate the new state first.
4846 // By setting skip_to_state_evaluation to false, we
4847 // are effectively jumping to the beginning of this if.
4848 assert(not states.empty());
4849 states.pop_back();
4850 skip_to_state_evaluation = true;
4851 continue;
4852 }
4853 else
4854 {
4855 return sax->parse_error(m_lexer.get_position(),
4856 m_lexer.get_token_string(),
4857 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array)));
4858 }
4859 }
4860 else // object
4861 {
4862 // comma -> next value
4863 if (get_token() == token_type::value_separator)
4864 {
4865 // parse key
4866 if (JSON_UNLIKELY(get_token() != token_type::value_string))
4867 {
4868 return sax->parse_error(m_lexer.get_position(),
4869 m_lexer.get_token_string(),
4870 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4871 }
4872 else
4873 {
4874 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4875 {
4876 return false;
4877 }
4878 }
4879
4880 // parse separator (:)
4881 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
4882 {
4883 return sax->parse_error(m_lexer.get_position(),
4884 m_lexer.get_token_string(),
4885 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator)));
4886 }
4887
4888 // parse values
4889 get_token();
4890 continue;
4891 }
4892
4893 // closing }
4894 if (JSON_LIKELY(last_token == token_type::end_object))
4895 {
4896 if (JSON_UNLIKELY(not sax->end_object()))
4897 {
4898 return false;
4899 }
4900
4901 // We are done with this object. Before we can parse a
4902 // new value, we need to evaluate the new state first.
4903 // By setting skip_to_state_evaluation to false, we
4904 // are effectively jumping to the beginning of this if.
4905 assert(not states.empty());
4906 states.pop_back();
4907 skip_to_state_evaluation = true;
4908 continue;
4909 }
4910 else
4911 {
4912 return sax->parse_error(m_lexer.get_position(),
4913 m_lexer.get_token_string(),
4914 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object)));
4915 }
4916 }
4917 }
4918 }
4919 }
4920
4921 /// get next token from lexer
get_token()4922 token_type get_token()
4923 {
4924 return (last_token = m_lexer.scan());
4925 }
4926
exception_message(const token_type expected)4927 std::string exception_message(const token_type expected)
4928 {
4929 std::string error_msg = "syntax error - ";
4930 if (last_token == token_type::parse_error)
4931 {
4932 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
4933 m_lexer.get_token_string() + "'";
4934 }
4935 else
4936 {
4937 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
4938 }
4939
4940 if (expected != token_type::uninitialized)
4941 {
4942 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
4943 }
4944
4945 return error_msg;
4946 }
4947
4948 private:
4949 /// callback function
4950 const parser_callback_t callback = nullptr;
4951 /// the type of the last read token
4952 token_type last_token = token_type::uninitialized;
4953 /// the lexer
4954 lexer_t m_lexer;
4955 /// whether to throw exceptions in case of errors
4956 const bool allow_exceptions = true;
4957 };
4958 }
4959 }
4960
4961 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
4962
4963
4964 #include <cstddef> // ptrdiff_t
4965 #include <limits> // numeric_limits
4966
4967 namespace nlohmann
4968 {
4969 namespace detail
4970 {
4971 /*
4972 @brief an iterator for primitive JSON types
4973
4974 This class models an iterator for primitive JSON types (boolean, number,
4975 string). It's only purpose is to allow the iterator/const_iterator classes
4976 to "iterate" over primitive values. Internally, the iterator is modeled by
4977 a `difference_type` variable. Value begin_value (`0`) models the begin,
4978 end_value (`1`) models past the end.
4979 */
4980 class primitive_iterator_t
4981 {
4982 private:
4983 using difference_type = std::ptrdiff_t;
4984 static constexpr difference_type begin_value = 0;
4985 static constexpr difference_type end_value = begin_value + 1;
4986
4987 /// iterator as signed integer type
4988 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
4989
4990 public:
get_value() const4991 constexpr difference_type get_value() const noexcept
4992 {
4993 return m_it;
4994 }
4995
4996 /// set iterator to a defined beginning
set_begin()4997 void set_begin() noexcept
4998 {
4999 m_it = begin_value;
5000 }
5001
5002 /// set iterator to a defined past the end
set_end()5003 void set_end() noexcept
5004 {
5005 m_it = end_value;
5006 }
5007
5008 /// return whether the iterator can be dereferenced
is_begin() const5009 constexpr bool is_begin() const noexcept
5010 {
5011 return m_it == begin_value;
5012 }
5013
5014 /// return whether the iterator is at end
is_end() const5015 constexpr bool is_end() const noexcept
5016 {
5017 return m_it == end_value;
5018 }
5019
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)5020 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5021 {
5022 return lhs.m_it == rhs.m_it;
5023 }
5024
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)5025 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5026 {
5027 return lhs.m_it < rhs.m_it;
5028 }
5029
operator +(difference_type n)5030 primitive_iterator_t operator+(difference_type n) noexcept
5031 {
5032 auto result = *this;
5033 result += n;
5034 return result;
5035 }
5036
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)5037 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5038 {
5039 return lhs.m_it - rhs.m_it;
5040 }
5041
operator ++()5042 primitive_iterator_t& operator++() noexcept
5043 {
5044 ++m_it;
5045 return *this;
5046 }
5047
operator ++(int)5048 primitive_iterator_t const operator++(int) noexcept
5049 {
5050 auto result = *this;
5051 ++m_it;
5052 return result;
5053 }
5054
operator --()5055 primitive_iterator_t& operator--() noexcept
5056 {
5057 --m_it;
5058 return *this;
5059 }
5060
operator --(int)5061 primitive_iterator_t const operator--(int) noexcept
5062 {
5063 auto result = *this;
5064 --m_it;
5065 return result;
5066 }
5067
operator +=(difference_type n)5068 primitive_iterator_t& operator+=(difference_type n) noexcept
5069 {
5070 m_it += n;
5071 return *this;
5072 }
5073
operator -=(difference_type n)5074 primitive_iterator_t& operator-=(difference_type n) noexcept
5075 {
5076 m_it -= n;
5077 return *this;
5078 }
5079 };
5080 }
5081 }
5082
5083 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5084
5085
5086 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5087
5088
5089 namespace nlohmann
5090 {
5091 namespace detail
5092 {
5093 /*!
5094 @brief an iterator value
5095
5096 @note This structure could easily be a union, but MSVC currently does not allow
5097 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
5098 */
5099 template<typename BasicJsonType> struct internal_iterator
5100 {
5101 /// iterator for JSON objects
5102 typename BasicJsonType::object_t::iterator object_iterator {};
5103 /// iterator for JSON arrays
5104 typename BasicJsonType::array_t::iterator array_iterator {};
5105 /// generic iterator for all other types
5106 primitive_iterator_t primitive_iterator {};
5107 };
5108 }
5109 }
5110
5111 // #include <nlohmann/detail/iterators/iter_impl.hpp>
5112
5113
5114 #include <ciso646> // not
5115 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
5116 #include <type_traits> // conditional, is_const, remove_const
5117
5118 // #include <nlohmann/detail/exceptions.hpp>
5119
5120 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5121
5122 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5123
5124 // #include <nlohmann/detail/macro_scope.hpp>
5125
5126 // #include <nlohmann/detail/meta/cpp_future.hpp>
5127
5128 // #include <nlohmann/detail/value_t.hpp>
5129
5130
5131 namespace nlohmann
5132 {
5133 namespace detail
5134 {
5135 // forward declare, to be able to friend it later on
5136 template<typename IteratorType> class iteration_proxy;
5137
5138 /*!
5139 @brief a template for a bidirectional iterator for the @ref basic_json class
5140
5141 This class implements a both iterators (iterator and const_iterator) for the
5142 @ref basic_json class.
5143
5144 @note An iterator is called *initialized* when a pointer to a JSON value has
5145 been set (e.g., by a constructor or a copy assignment). If the iterator is
5146 default-constructed, it is *uninitialized* and most methods are undefined.
5147 **The library uses assertions to detect calls on uninitialized iterators.**
5148
5149 @requirement The class satisfies the following concept requirements:
5150 -
5151 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5152 The iterator that can be moved can be moved in both directions (i.e.
5153 incremented and decremented).
5154
5155 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
5156 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
5157 */
5158 template<typename BasicJsonType>
5159 class iter_impl
5160 {
5161 /// allow basic_json to access private members
5162 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
5163 friend BasicJsonType;
5164 friend iteration_proxy<iter_impl>;
5165
5166 using object_t = typename BasicJsonType::object_t;
5167 using array_t = typename BasicJsonType::array_t;
5168 // make sure BasicJsonType is basic_json or const basic_json
5169 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
5170 "iter_impl only accepts (const) basic_json");
5171
5172 public:
5173
5174 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
5175 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
5176 /// A user-defined iterator should provide publicly accessible typedefs named
5177 /// iterator_category, value_type, difference_type, pointer, and reference.
5178 /// Note that value_type is required to be non-const, even for constant iterators.
5179 using iterator_category = std::bidirectional_iterator_tag;
5180
5181 /// the type of the values when the iterator is dereferenced
5182 using value_type = typename BasicJsonType::value_type;
5183 /// a type to represent differences between iterators
5184 using difference_type = typename BasicJsonType::difference_type;
5185 /// defines a pointer to the type iterated over (value_type)
5186 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
5187 typename BasicJsonType::const_pointer,
5188 typename BasicJsonType::pointer>::type;
5189 /// defines a reference to the type iterated over (value_type)
5190 using reference =
5191 typename std::conditional<std::is_const<BasicJsonType>::value,
5192 typename BasicJsonType::const_reference,
5193 typename BasicJsonType::reference>::type;
5194
5195 /// default constructor
5196 iter_impl() = default;
5197
5198 /*!
5199 @brief constructor for a given JSON instance
5200 @param[in] object pointer to a JSON object for this iterator
5201 @pre object != nullptr
5202 @post The iterator is initialized; i.e. `m_object != nullptr`.
5203 */
iter_impl(pointer object)5204 explicit iter_impl(pointer object) noexcept : m_object(object)
5205 {
5206 assert(m_object != nullptr);
5207
5208 switch (m_object->m_type)
5209 {
5210 case value_t::object:
5211 {
5212 m_it.object_iterator = typename object_t::iterator();
5213 break;
5214 }
5215
5216 case value_t::array:
5217 {
5218 m_it.array_iterator = typename array_t::iterator();
5219 break;
5220 }
5221
5222 default:
5223 {
5224 m_it.primitive_iterator = primitive_iterator_t();
5225 break;
5226 }
5227 }
5228 }
5229
5230 /*!
5231 @note The conventional copy constructor and copy assignment are implicitly
5232 defined. Combined with the following converting constructor and
5233 assignment, they support: (1) copy from iterator to iterator, (2)
5234 copy from const iterator to const iterator, and (3) conversion from
5235 iterator to const iterator. However conversion from const iterator
5236 to iterator is not defined.
5237 */
5238
5239 /*!
5240 @brief converting constructor
5241 @param[in] other non-const iterator to copy from
5242 @note It is not checked whether @a other is initialized.
5243 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)5244 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5245 : m_object(other.m_object), m_it(other.m_it) {}
5246
5247 /*!
5248 @brief converting assignment
5249 @param[in,out] other non-const iterator to copy from
5250 @return const/non-const iterator
5251 @note It is not checked whether @a other is initialized.
5252 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)5253 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5254 {
5255 m_object = other.m_object;
5256 m_it = other.m_it;
5257 return *this;
5258 }
5259
5260 private:
5261 /*!
5262 @brief set the iterator to the first value
5263 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5264 */
set_begin()5265 void set_begin() noexcept
5266 {
5267 assert(m_object != nullptr);
5268
5269 switch (m_object->m_type)
5270 {
5271 case value_t::object:
5272 {
5273 m_it.object_iterator = m_object->m_value.object->begin();
5274 break;
5275 }
5276
5277 case value_t::array:
5278 {
5279 m_it.array_iterator = m_object->m_value.array->begin();
5280 break;
5281 }
5282
5283 case value_t::null:
5284 {
5285 // set to end so begin()==end() is true: null is empty
5286 m_it.primitive_iterator.set_end();
5287 break;
5288 }
5289
5290 default:
5291 {
5292 m_it.primitive_iterator.set_begin();
5293 break;
5294 }
5295 }
5296 }
5297
5298 /*!
5299 @brief set the iterator past the last value
5300 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5301 */
set_end()5302 void set_end() noexcept
5303 {
5304 assert(m_object != nullptr);
5305
5306 switch (m_object->m_type)
5307 {
5308 case value_t::object:
5309 {
5310 m_it.object_iterator = m_object->m_value.object->end();
5311 break;
5312 }
5313
5314 case value_t::array:
5315 {
5316 m_it.array_iterator = m_object->m_value.array->end();
5317 break;
5318 }
5319
5320 default:
5321 {
5322 m_it.primitive_iterator.set_end();
5323 break;
5324 }
5325 }
5326 }
5327
5328 public:
5329 /*!
5330 @brief return a reference to the value pointed to by the iterator
5331 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5332 */
operator *() const5333 reference operator*() const
5334 {
5335 assert(m_object != nullptr);
5336
5337 switch (m_object->m_type)
5338 {
5339 case value_t::object:
5340 {
5341 assert(m_it.object_iterator != m_object->m_value.object->end());
5342 return m_it.object_iterator->second;
5343 }
5344
5345 case value_t::array:
5346 {
5347 assert(m_it.array_iterator != m_object->m_value.array->end());
5348 return *m_it.array_iterator;
5349 }
5350
5351 case value_t::null:
5352 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5353
5354 default:
5355 {
5356 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5357 {
5358 return *m_object;
5359 }
5360
5361 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5362 }
5363 }
5364 }
5365
5366 /*!
5367 @brief dereference the iterator
5368 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5369 */
operator ->() const5370 pointer operator->() const
5371 {
5372 assert(m_object != nullptr);
5373
5374 switch (m_object->m_type)
5375 {
5376 case value_t::object:
5377 {
5378 assert(m_it.object_iterator != m_object->m_value.object->end());
5379 return &(m_it.object_iterator->second);
5380 }
5381
5382 case value_t::array:
5383 {
5384 assert(m_it.array_iterator != m_object->m_value.array->end());
5385 return &*m_it.array_iterator;
5386 }
5387
5388 default:
5389 {
5390 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5391 {
5392 return m_object;
5393 }
5394
5395 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5396 }
5397 }
5398 }
5399
5400 /*!
5401 @brief post-increment (it++)
5402 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5403 */
operator ++(int)5404 iter_impl const operator++(int)
5405 {
5406 auto result = *this;
5407 ++(*this);
5408 return result;
5409 }
5410
5411 /*!
5412 @brief pre-increment (++it)
5413 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5414 */
operator ++()5415 iter_impl& operator++()
5416 {
5417 assert(m_object != nullptr);
5418
5419 switch (m_object->m_type)
5420 {
5421 case value_t::object:
5422 {
5423 std::advance(m_it.object_iterator, 1);
5424 break;
5425 }
5426
5427 case value_t::array:
5428 {
5429 std::advance(m_it.array_iterator, 1);
5430 break;
5431 }
5432
5433 default:
5434 {
5435 ++m_it.primitive_iterator;
5436 break;
5437 }
5438 }
5439
5440 return *this;
5441 }
5442
5443 /*!
5444 @brief post-decrement (it--)
5445 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5446 */
operator --(int)5447 iter_impl const operator--(int)
5448 {
5449 auto result = *this;
5450 --(*this);
5451 return result;
5452 }
5453
5454 /*!
5455 @brief pre-decrement (--it)
5456 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5457 */
operator --()5458 iter_impl& operator--()
5459 {
5460 assert(m_object != nullptr);
5461
5462 switch (m_object->m_type)
5463 {
5464 case value_t::object:
5465 {
5466 std::advance(m_it.object_iterator, -1);
5467 break;
5468 }
5469
5470 case value_t::array:
5471 {
5472 std::advance(m_it.array_iterator, -1);
5473 break;
5474 }
5475
5476 default:
5477 {
5478 --m_it.primitive_iterator;
5479 break;
5480 }
5481 }
5482
5483 return *this;
5484 }
5485
5486 /*!
5487 @brief comparison: equal
5488 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5489 */
operator ==(const iter_impl & other) const5490 bool operator==(const iter_impl& other) const
5491 {
5492 // if objects are not the same, the comparison is undefined
5493 if (JSON_UNLIKELY(m_object != other.m_object))
5494 {
5495 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5496 }
5497
5498 assert(m_object != nullptr);
5499
5500 switch (m_object->m_type)
5501 {
5502 case value_t::object:
5503 return (m_it.object_iterator == other.m_it.object_iterator);
5504
5505 case value_t::array:
5506 return (m_it.array_iterator == other.m_it.array_iterator);
5507
5508 default:
5509 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5510 }
5511 }
5512
5513 /*!
5514 @brief comparison: not equal
5515 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5516 */
operator !=(const iter_impl & other) const5517 bool operator!=(const iter_impl& other) const
5518 {
5519 return not operator==(other);
5520 }
5521
5522 /*!
5523 @brief comparison: smaller
5524 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5525 */
operator <(const iter_impl & other) const5526 bool operator<(const iter_impl& other) const
5527 {
5528 // if objects are not the same, the comparison is undefined
5529 if (JSON_UNLIKELY(m_object != other.m_object))
5530 {
5531 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5532 }
5533
5534 assert(m_object != nullptr);
5535
5536 switch (m_object->m_type)
5537 {
5538 case value_t::object:
5539 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
5540
5541 case value_t::array:
5542 return (m_it.array_iterator < other.m_it.array_iterator);
5543
5544 default:
5545 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
5546 }
5547 }
5548
5549 /*!
5550 @brief comparison: less than or equal
5551 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5552 */
operator <=(const iter_impl & other) const5553 bool operator<=(const iter_impl& other) const
5554 {
5555 return not other.operator < (*this);
5556 }
5557
5558 /*!
5559 @brief comparison: greater than
5560 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5561 */
operator >(const iter_impl & other) const5562 bool operator>(const iter_impl& other) const
5563 {
5564 return not operator<=(other);
5565 }
5566
5567 /*!
5568 @brief comparison: greater than or equal
5569 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5570 */
operator >=(const iter_impl & other) const5571 bool operator>=(const iter_impl& other) const
5572 {
5573 return not operator<(other);
5574 }
5575
5576 /*!
5577 @brief add to iterator
5578 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5579 */
operator +=(difference_type i)5580 iter_impl& operator+=(difference_type i)
5581 {
5582 assert(m_object != nullptr);
5583
5584 switch (m_object->m_type)
5585 {
5586 case value_t::object:
5587 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5588
5589 case value_t::array:
5590 {
5591 std::advance(m_it.array_iterator, i);
5592 break;
5593 }
5594
5595 default:
5596 {
5597 m_it.primitive_iterator += i;
5598 break;
5599 }
5600 }
5601
5602 return *this;
5603 }
5604
5605 /*!
5606 @brief subtract from iterator
5607 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5608 */
operator -=(difference_type i)5609 iter_impl& operator-=(difference_type i)
5610 {
5611 return operator+=(-i);
5612 }
5613
5614 /*!
5615 @brief add to iterator
5616 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5617 */
operator +(difference_type i) const5618 iter_impl operator+(difference_type i) const
5619 {
5620 auto result = *this;
5621 result += i;
5622 return result;
5623 }
5624
5625 /*!
5626 @brief addition of distance and iterator
5627 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5628 */
operator +(difference_type i,const iter_impl & it)5629 friend iter_impl operator+(difference_type i, const iter_impl& it)
5630 {
5631 auto result = it;
5632 result += i;
5633 return result;
5634 }
5635
5636 /*!
5637 @brief subtract from iterator
5638 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5639 */
operator -(difference_type i) const5640 iter_impl operator-(difference_type i) const
5641 {
5642 auto result = *this;
5643 result -= i;
5644 return result;
5645 }
5646
5647 /*!
5648 @brief return difference
5649 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5650 */
operator -(const iter_impl & other) const5651 difference_type operator-(const iter_impl& other) const
5652 {
5653 assert(m_object != nullptr);
5654
5655 switch (m_object->m_type)
5656 {
5657 case value_t::object:
5658 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5659
5660 case value_t::array:
5661 return m_it.array_iterator - other.m_it.array_iterator;
5662
5663 default:
5664 return m_it.primitive_iterator - other.m_it.primitive_iterator;
5665 }
5666 }
5667
5668 /*!
5669 @brief access to successor
5670 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5671 */
operator [](difference_type n) const5672 reference operator[](difference_type n) const
5673 {
5674 assert(m_object != nullptr);
5675
5676 switch (m_object->m_type)
5677 {
5678 case value_t::object:
5679 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
5680
5681 case value_t::array:
5682 return *std::next(m_it.array_iterator, n);
5683
5684 case value_t::null:
5685 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5686
5687 default:
5688 {
5689 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
5690 {
5691 return *m_object;
5692 }
5693
5694 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5695 }
5696 }
5697 }
5698
5699 /*!
5700 @brief return the key of an object iterator
5701 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5702 */
key() const5703 const typename object_t::key_type& key() const
5704 {
5705 assert(m_object != nullptr);
5706
5707 if (JSON_LIKELY(m_object->is_object()))
5708 {
5709 return m_it.object_iterator->first;
5710 }
5711
5712 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
5713 }
5714
5715 /*!
5716 @brief return the value of an iterator
5717 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5718 */
value() const5719 reference value() const
5720 {
5721 return operator*();
5722 }
5723
5724 private:
5725 /// associated JSON instance
5726 pointer m_object = nullptr;
5727 /// the actual iterator of the associated instance
5728 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
5729 };
5730 }
5731 }
5732
5733 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5734
5735 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
5736
5737
5738 #include <cstddef> // ptrdiff_t
5739 #include <iterator> // reverse_iterator
5740 #include <utility> // declval
5741
5742 namespace nlohmann
5743 {
5744 namespace detail
5745 {
5746 //////////////////////
5747 // reverse_iterator //
5748 //////////////////////
5749
5750 /*!
5751 @brief a template for a reverse iterator class
5752
5753 @tparam Base the base iterator type to reverse. Valid types are @ref
5754 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
5755 create @ref const_reverse_iterator).
5756
5757 @requirement The class satisfies the following concept requirements:
5758 -
5759 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5760 The iterator that can be moved can be moved in both directions (i.e.
5761 incremented and decremented).
5762 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
5763 It is possible to write to the pointed-to element (only if @a Base is
5764 @ref iterator).
5765
5766 @since version 1.0.0
5767 */
5768 template<typename Base>
5769 class json_reverse_iterator : public std::reverse_iterator<Base>
5770 {
5771 public:
5772 using difference_type = std::ptrdiff_t;
5773 /// shortcut to the reverse iterator adapter
5774 using base_iterator = std::reverse_iterator<Base>;
5775 /// the reference type for the pointed-to element
5776 using reference = typename Base::reference;
5777
5778 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)5779 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
5780 : base_iterator(it) {}
5781
5782 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)5783 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
5784
5785 /// post-increment (it++)
operator ++(int)5786 json_reverse_iterator const operator++(int)
5787 {
5788 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
5789 }
5790
5791 /// pre-increment (++it)
operator ++()5792 json_reverse_iterator& operator++()
5793 {
5794 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
5795 }
5796
5797 /// post-decrement (it--)
operator --(int)5798 json_reverse_iterator const operator--(int)
5799 {
5800 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
5801 }
5802
5803 /// pre-decrement (--it)
operator --()5804 json_reverse_iterator& operator--()
5805 {
5806 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
5807 }
5808
5809 /// add to iterator
operator +=(difference_type i)5810 json_reverse_iterator& operator+=(difference_type i)
5811 {
5812 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
5813 }
5814
5815 /// add to iterator
operator +(difference_type i) const5816 json_reverse_iterator operator+(difference_type i) const
5817 {
5818 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
5819 }
5820
5821 /// subtract from iterator
operator -(difference_type i) const5822 json_reverse_iterator operator-(difference_type i) const
5823 {
5824 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
5825 }
5826
5827 /// return difference
operator -(const json_reverse_iterator & other) const5828 difference_type operator-(const json_reverse_iterator& other) const
5829 {
5830 return base_iterator(*this) - base_iterator(other);
5831 }
5832
5833 /// access to successor
operator [](difference_type n) const5834 reference operator[](difference_type n) const
5835 {
5836 return *(this->operator+(n));
5837 }
5838
5839 /// return the key of an object iterator
key() const5840 auto key() const -> decltype(std::declval<Base>().key())
5841 {
5842 auto it = --this->base();
5843 return it.key();
5844 }
5845
5846 /// return the value of an iterator
value() const5847 reference value() const
5848 {
5849 auto it = --this->base();
5850 return it.operator * ();
5851 }
5852 };
5853 }
5854 }
5855
5856 // #include <nlohmann/detail/output/output_adapters.hpp>
5857
5858
5859 #include <algorithm> // copy
5860 #include <cstddef> // size_t
5861 #include <ios> // streamsize
5862 #include <iterator> // back_inserter
5863 #include <memory> // shared_ptr, make_shared
5864 #include <ostream> // basic_ostream
5865 #include <string> // basic_string
5866 #include <vector> // vector
5867
5868 namespace nlohmann
5869 {
5870 namespace detail
5871 {
5872 /// abstract output adapter interface
5873 template<typename CharType> struct output_adapter_protocol
5874 {
5875 virtual void write_character(CharType c) = 0;
5876 virtual void write_characters(const CharType* s, std::size_t length) = 0;
5877 virtual ~output_adapter_protocol() = default;
5878 };
5879
5880 /// a type to simplify interfaces
5881 template<typename CharType>
5882 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
5883
5884 /// output adapter for byte vectors
5885 template<typename CharType>
5886 class output_vector_adapter : public output_adapter_protocol<CharType>
5887 {
5888 public:
output_vector_adapter(std::vector<CharType> & vec)5889 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
5890
write_character(CharType c)5891 void write_character(CharType c) override
5892 {
5893 v.push_back(c);
5894 }
5895
write_characters(const CharType * s,std::size_t length)5896 void write_characters(const CharType* s, std::size_t length) override
5897 {
5898 std::copy(s, s + length, std::back_inserter(v));
5899 }
5900
5901 private:
5902 std::vector<CharType>& v;
5903 };
5904
5905 /// output adapter for output streams
5906 template<typename CharType>
5907 class output_stream_adapter : public output_adapter_protocol<CharType>
5908 {
5909 public:
output_stream_adapter(std::basic_ostream<CharType> & s)5910 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
5911
write_character(CharType c)5912 void write_character(CharType c) override
5913 {
5914 stream.put(c);
5915 }
5916
write_characters(const CharType * s,std::size_t length)5917 void write_characters(const CharType* s, std::size_t length) override
5918 {
5919 stream.write(s, static_cast<std::streamsize>(length));
5920 }
5921
5922 private:
5923 std::basic_ostream<CharType>& stream;
5924 };
5925
5926 /// output adapter for basic_string
5927 template<typename CharType, typename StringType = std::basic_string<CharType>>
5928 class output_string_adapter : public output_adapter_protocol<CharType>
5929 {
5930 public:
output_string_adapter(StringType & s)5931 explicit output_string_adapter(StringType& s) : str(s) {}
5932
write_character(CharType c)5933 void write_character(CharType c) override
5934 {
5935 str.push_back(c);
5936 }
5937
write_characters(const CharType * s,std::size_t length)5938 void write_characters(const CharType* s, std::size_t length) override
5939 {
5940 str.append(s, length);
5941 }
5942
5943 private:
5944 StringType& str;
5945 };
5946
5947 template<typename CharType, typename StringType = std::basic_string<CharType>>
5948 class output_adapter
5949 {
5950 public:
output_adapter(std::vector<CharType> & vec)5951 output_adapter(std::vector<CharType>& vec)
5952 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
5953
output_adapter(std::basic_ostream<CharType> & s)5954 output_adapter(std::basic_ostream<CharType>& s)
5955 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
5956
output_adapter(StringType & s)5957 output_adapter(StringType& s)
5958 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
5959
operator output_adapter_t<CharType>()5960 operator output_adapter_t<CharType>()
5961 {
5962 return oa;
5963 }
5964
5965 private:
5966 output_adapter_t<CharType> oa = nullptr;
5967 };
5968 }
5969 }
5970
5971 // #include <nlohmann/detail/input/binary_reader.hpp>
5972
5973
5974 #include <algorithm> // generate_n
5975 #include <array> // array
5976 #include <cassert> // assert
5977 #include <cmath> // ldexp
5978 #include <cstddef> // size_t
5979 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5980 #include <cstdio> // snprintf
5981 #include <cstring> // memcpy
5982 #include <iterator> // back_inserter
5983 #include <limits> // numeric_limits
5984 #include <string> // char_traits, string
5985 #include <utility> // make_pair, move
5986
5987 // #include <nlohmann/detail/input/input_adapters.hpp>
5988
5989 // #include <nlohmann/detail/input/json_sax.hpp>
5990
5991 // #include <nlohmann/detail/exceptions.hpp>
5992
5993 // #include <nlohmann/detail/macro_scope.hpp>
5994
5995 // #include <nlohmann/detail/meta/is_sax.hpp>
5996
5997 // #include <nlohmann/detail/value_t.hpp>
5998
5999
6000 namespace nlohmann
6001 {
6002 namespace detail
6003 {
6004 ///////////////////
6005 // binary reader //
6006 ///////////////////
6007
6008 /*!
6009 @brief deserialization of CBOR, MessagePack, and UBJSON values
6010 */
6011 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
6012 class binary_reader
6013 {
6014 using number_integer_t = typename BasicJsonType::number_integer_t;
6015 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6016 using number_float_t = typename BasicJsonType::number_float_t;
6017 using string_t = typename BasicJsonType::string_t;
6018 using json_sax_t = SAX;
6019
6020 public:
6021 /*!
6022 @brief create a binary reader
6023
6024 @param[in] adapter input adapter to read from
6025 */
binary_reader(input_adapter_t adapter)6026 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
6027 {
6028 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
6029 assert(ia);
6030 }
6031
6032 /*!
6033 @param[in] format the binary format to parse
6034 @param[in] sax_ a SAX event processor
6035 @param[in] strict whether to expect the input to be consumed completed
6036
6037 @return
6038 */
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true)6039 bool sax_parse(const input_format_t format,
6040 json_sax_t* sax_,
6041 const bool strict = true)
6042 {
6043 sax = sax_;
6044 bool result = false;
6045
6046 switch (format)
6047 {
6048 case input_format_t::cbor:
6049 result = parse_cbor_internal();
6050 break;
6051
6052 case input_format_t::msgpack:
6053 result = parse_msgpack_internal();
6054 break;
6055
6056 case input_format_t::ubjson:
6057 result = parse_ubjson_internal();
6058 break;
6059
6060 // LCOV_EXCL_START
6061 default:
6062 assert(false);
6063 // LCOV_EXCL_STOP
6064 }
6065
6066 // strict mode: next byte must be EOF
6067 if (result and strict)
6068 {
6069 if (format == input_format_t::ubjson)
6070 {
6071 get_ignore_noop();
6072 }
6073 else
6074 {
6075 get();
6076 }
6077
6078 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6079 {
6080 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input"));
6081 }
6082 }
6083
6084 return result;
6085 }
6086
6087 /*!
6088 @brief determine system byte order
6089
6090 @return true if and only if system's byte order is little endian
6091
6092 @note from http://stackoverflow.com/a/1001328/266378
6093 */
little_endianess(int num=1)6094 static constexpr bool little_endianess(int num = 1) noexcept
6095 {
6096 return (*reinterpret_cast<char*>(&num) == 1);
6097 }
6098
6099 private:
6100 /*!
6101 @param[in] get_char whether a new character should be retrieved from the
6102 input (true, default) or whether the last read
6103 character should be considered instead
6104
6105 @return whether a valid CBOR value was passed to the SAX parser
6106 */
parse_cbor_internal(const bool get_char=true)6107 bool parse_cbor_internal(const bool get_char = true)
6108 {
6109 switch (get_char ? get() : current)
6110 {
6111 // EOF
6112 case std::char_traits<char>::eof():
6113 return unexpect_eof();
6114
6115 // Integer 0x00..0x17 (0..23)
6116 case 0x00:
6117 case 0x01:
6118 case 0x02:
6119 case 0x03:
6120 case 0x04:
6121 case 0x05:
6122 case 0x06:
6123 case 0x07:
6124 case 0x08:
6125 case 0x09:
6126 case 0x0A:
6127 case 0x0B:
6128 case 0x0C:
6129 case 0x0D:
6130 case 0x0E:
6131 case 0x0F:
6132 case 0x10:
6133 case 0x11:
6134 case 0x12:
6135 case 0x13:
6136 case 0x14:
6137 case 0x15:
6138 case 0x16:
6139 case 0x17:
6140 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6141
6142 case 0x18: // Unsigned integer (one-byte uint8_t follows)
6143 {
6144 uint8_t number;
6145 return get_number(number) and sax->number_unsigned(number);
6146 }
6147
6148 case 0x19: // Unsigned integer (two-byte uint16_t follows)
6149 {
6150 uint16_t number;
6151 return get_number(number) and sax->number_unsigned(number);
6152 }
6153
6154 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6155 {
6156 uint32_t number;
6157 return get_number(number) and sax->number_unsigned(number);
6158 }
6159
6160 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6161 {
6162 uint64_t number;
6163 return get_number(number) and sax->number_unsigned(number);
6164 }
6165
6166 // Negative integer -1-0x00..-1-0x17 (-1..-24)
6167 case 0x20:
6168 case 0x21:
6169 case 0x22:
6170 case 0x23:
6171 case 0x24:
6172 case 0x25:
6173 case 0x26:
6174 case 0x27:
6175 case 0x28:
6176 case 0x29:
6177 case 0x2A:
6178 case 0x2B:
6179 case 0x2C:
6180 case 0x2D:
6181 case 0x2E:
6182 case 0x2F:
6183 case 0x30:
6184 case 0x31:
6185 case 0x32:
6186 case 0x33:
6187 case 0x34:
6188 case 0x35:
6189 case 0x36:
6190 case 0x37:
6191 return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6192
6193 case 0x38: // Negative integer (one-byte uint8_t follows)
6194 {
6195 uint8_t number;
6196 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6197 }
6198
6199 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6200 {
6201 uint16_t number;
6202 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6203 }
6204
6205 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6206 {
6207 uint32_t number;
6208 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6209 }
6210
6211 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6212 {
6213 uint64_t number;
6214 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1)
6215 - static_cast<number_integer_t>(number));
6216 }
6217
6218 // UTF-8 string (0x00..0x17 bytes follow)
6219 case 0x60:
6220 case 0x61:
6221 case 0x62:
6222 case 0x63:
6223 case 0x64:
6224 case 0x65:
6225 case 0x66:
6226 case 0x67:
6227 case 0x68:
6228 case 0x69:
6229 case 0x6A:
6230 case 0x6B:
6231 case 0x6C:
6232 case 0x6D:
6233 case 0x6E:
6234 case 0x6F:
6235 case 0x70:
6236 case 0x71:
6237 case 0x72:
6238 case 0x73:
6239 case 0x74:
6240 case 0x75:
6241 case 0x76:
6242 case 0x77:
6243 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6244 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6245 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6246 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6247 case 0x7F: // UTF-8 string (indefinite length)
6248 {
6249 string_t s;
6250 return get_cbor_string(s) and sax->string(s);
6251 }
6252
6253 // array (0x00..0x17 data items follow)
6254 case 0x80:
6255 case 0x81:
6256 case 0x82:
6257 case 0x83:
6258 case 0x84:
6259 case 0x85:
6260 case 0x86:
6261 case 0x87:
6262 case 0x88:
6263 case 0x89:
6264 case 0x8A:
6265 case 0x8B:
6266 case 0x8C:
6267 case 0x8D:
6268 case 0x8E:
6269 case 0x8F:
6270 case 0x90:
6271 case 0x91:
6272 case 0x92:
6273 case 0x93:
6274 case 0x94:
6275 case 0x95:
6276 case 0x96:
6277 case 0x97:
6278 return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6279
6280 case 0x98: // array (one-byte uint8_t for n follows)
6281 {
6282 uint8_t len;
6283 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6284 }
6285
6286 case 0x99: // array (two-byte uint16_t for n follow)
6287 {
6288 uint16_t len;
6289 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6290 }
6291
6292 case 0x9A: // array (four-byte uint32_t for n follow)
6293 {
6294 uint32_t len;
6295 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6296 }
6297
6298 case 0x9B: // array (eight-byte uint64_t for n follow)
6299 {
6300 uint64_t len;
6301 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6302 }
6303
6304 case 0x9F: // array (indefinite length)
6305 return get_cbor_array(std::size_t(-1));
6306
6307 // map (0x00..0x17 pairs of data items follow)
6308 case 0xA0:
6309 case 0xA1:
6310 case 0xA2:
6311 case 0xA3:
6312 case 0xA4:
6313 case 0xA5:
6314 case 0xA6:
6315 case 0xA7:
6316 case 0xA8:
6317 case 0xA9:
6318 case 0xAA:
6319 case 0xAB:
6320 case 0xAC:
6321 case 0xAD:
6322 case 0xAE:
6323 case 0xAF:
6324 case 0xB0:
6325 case 0xB1:
6326 case 0xB2:
6327 case 0xB3:
6328 case 0xB4:
6329 case 0xB5:
6330 case 0xB6:
6331 case 0xB7:
6332 return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
6333
6334 case 0xB8: // map (one-byte uint8_t for n follows)
6335 {
6336 uint8_t len;
6337 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6338 }
6339
6340 case 0xB9: // map (two-byte uint16_t for n follow)
6341 {
6342 uint16_t len;
6343 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6344 }
6345
6346 case 0xBA: // map (four-byte uint32_t for n follow)
6347 {
6348 uint32_t len;
6349 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6350 }
6351
6352 case 0xBB: // map (eight-byte uint64_t for n follow)
6353 {
6354 uint64_t len;
6355 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6356 }
6357
6358 case 0xBF: // map (indefinite length)
6359 return get_cbor_object(std::size_t(-1));
6360
6361 case 0xF4: // false
6362 return sax->boolean(false);
6363
6364 case 0xF5: // true
6365 return sax->boolean(true);
6366
6367 case 0xF6: // null
6368 return sax->null();
6369
6370 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6371 {
6372 const int byte1 = get();
6373 if (JSON_UNLIKELY(not unexpect_eof()))
6374 {
6375 return false;
6376 }
6377 const int byte2 = get();
6378 if (JSON_UNLIKELY(not unexpect_eof()))
6379 {
6380 return false;
6381 }
6382
6383 // code from RFC 7049, Appendix D, Figure 3:
6384 // As half-precision floating-point numbers were only added
6385 // to IEEE 754 in 2008, today's programming platforms often
6386 // still only have limited support for them. It is very
6387 // easy to include at least decoding support for them even
6388 // without such support. An example of a small decoder for
6389 // half-precision floating-point numbers in the C language
6390 // is shown in Fig. 3.
6391 const int half = (byte1 << 8) + byte2;
6392 const double val = [&half]
6393 {
6394 const int exp = (half >> 10) & 0x1F;
6395 const int mant = half & 0x3FF;
6396 assert(0 <= exp and exp <= 32);
6397 assert(0 <= mant and mant <= 1024);
6398 switch (exp)
6399 {
6400 case 0:
6401 return std::ldexp(mant, -24);
6402 case 31:
6403 return (mant == 0)
6404 ? std::numeric_limits<double>::infinity()
6405 : std::numeric_limits<double>::quiet_NaN();
6406 default:
6407 return std::ldexp(mant + 1024, exp - 25);
6408 }
6409 }();
6410 return sax->number_float((half & 0x8000) != 0
6411 ? static_cast<number_float_t>(-val)
6412 : static_cast<number_float_t>(val), "");
6413 }
6414
6415 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6416 {
6417 float number;
6418 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6419 }
6420
6421 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6422 {
6423 double number;
6424 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6425 }
6426
6427 default: // anything else (0xFF is handled inside the other types)
6428 {
6429 auto last_token = get_token_string();
6430 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token));
6431 }
6432 }
6433 }
6434
6435 /*!
6436 @return whether a valid MessagePack value was passed to the SAX parser
6437 */
parse_msgpack_internal()6438 bool parse_msgpack_internal()
6439 {
6440 switch (get())
6441 {
6442 // EOF
6443 case std::char_traits<char>::eof():
6444 return unexpect_eof();
6445
6446 // positive fixint
6447 case 0x00:
6448 case 0x01:
6449 case 0x02:
6450 case 0x03:
6451 case 0x04:
6452 case 0x05:
6453 case 0x06:
6454 case 0x07:
6455 case 0x08:
6456 case 0x09:
6457 case 0x0A:
6458 case 0x0B:
6459 case 0x0C:
6460 case 0x0D:
6461 case 0x0E:
6462 case 0x0F:
6463 case 0x10:
6464 case 0x11:
6465 case 0x12:
6466 case 0x13:
6467 case 0x14:
6468 case 0x15:
6469 case 0x16:
6470 case 0x17:
6471 case 0x18:
6472 case 0x19:
6473 case 0x1A:
6474 case 0x1B:
6475 case 0x1C:
6476 case 0x1D:
6477 case 0x1E:
6478 case 0x1F:
6479 case 0x20:
6480 case 0x21:
6481 case 0x22:
6482 case 0x23:
6483 case 0x24:
6484 case 0x25:
6485 case 0x26:
6486 case 0x27:
6487 case 0x28:
6488 case 0x29:
6489 case 0x2A:
6490 case 0x2B:
6491 case 0x2C:
6492 case 0x2D:
6493 case 0x2E:
6494 case 0x2F:
6495 case 0x30:
6496 case 0x31:
6497 case 0x32:
6498 case 0x33:
6499 case 0x34:
6500 case 0x35:
6501 case 0x36:
6502 case 0x37:
6503 case 0x38:
6504 case 0x39:
6505 case 0x3A:
6506 case 0x3B:
6507 case 0x3C:
6508 case 0x3D:
6509 case 0x3E:
6510 case 0x3F:
6511 case 0x40:
6512 case 0x41:
6513 case 0x42:
6514 case 0x43:
6515 case 0x44:
6516 case 0x45:
6517 case 0x46:
6518 case 0x47:
6519 case 0x48:
6520 case 0x49:
6521 case 0x4A:
6522 case 0x4B:
6523 case 0x4C:
6524 case 0x4D:
6525 case 0x4E:
6526 case 0x4F:
6527 case 0x50:
6528 case 0x51:
6529 case 0x52:
6530 case 0x53:
6531 case 0x54:
6532 case 0x55:
6533 case 0x56:
6534 case 0x57:
6535 case 0x58:
6536 case 0x59:
6537 case 0x5A:
6538 case 0x5B:
6539 case 0x5C:
6540 case 0x5D:
6541 case 0x5E:
6542 case 0x5F:
6543 case 0x60:
6544 case 0x61:
6545 case 0x62:
6546 case 0x63:
6547 case 0x64:
6548 case 0x65:
6549 case 0x66:
6550 case 0x67:
6551 case 0x68:
6552 case 0x69:
6553 case 0x6A:
6554 case 0x6B:
6555 case 0x6C:
6556 case 0x6D:
6557 case 0x6E:
6558 case 0x6F:
6559 case 0x70:
6560 case 0x71:
6561 case 0x72:
6562 case 0x73:
6563 case 0x74:
6564 case 0x75:
6565 case 0x76:
6566 case 0x77:
6567 case 0x78:
6568 case 0x79:
6569 case 0x7A:
6570 case 0x7B:
6571 case 0x7C:
6572 case 0x7D:
6573 case 0x7E:
6574 case 0x7F:
6575 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6576
6577 // fixmap
6578 case 0x80:
6579 case 0x81:
6580 case 0x82:
6581 case 0x83:
6582 case 0x84:
6583 case 0x85:
6584 case 0x86:
6585 case 0x87:
6586 case 0x88:
6587 case 0x89:
6588 case 0x8A:
6589 case 0x8B:
6590 case 0x8C:
6591 case 0x8D:
6592 case 0x8E:
6593 case 0x8F:
6594 return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
6595
6596 // fixarray
6597 case 0x90:
6598 case 0x91:
6599 case 0x92:
6600 case 0x93:
6601 case 0x94:
6602 case 0x95:
6603 case 0x96:
6604 case 0x97:
6605 case 0x98:
6606 case 0x99:
6607 case 0x9A:
6608 case 0x9B:
6609 case 0x9C:
6610 case 0x9D:
6611 case 0x9E:
6612 case 0x9F:
6613 return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
6614
6615 // fixstr
6616 case 0xA0:
6617 case 0xA1:
6618 case 0xA2:
6619 case 0xA3:
6620 case 0xA4:
6621 case 0xA5:
6622 case 0xA6:
6623 case 0xA7:
6624 case 0xA8:
6625 case 0xA9:
6626 case 0xAA:
6627 case 0xAB:
6628 case 0xAC:
6629 case 0xAD:
6630 case 0xAE:
6631 case 0xAF:
6632 case 0xB0:
6633 case 0xB1:
6634 case 0xB2:
6635 case 0xB3:
6636 case 0xB4:
6637 case 0xB5:
6638 case 0xB6:
6639 case 0xB7:
6640 case 0xB8:
6641 case 0xB9:
6642 case 0xBA:
6643 case 0xBB:
6644 case 0xBC:
6645 case 0xBD:
6646 case 0xBE:
6647 case 0xBF:
6648 {
6649 string_t s;
6650 return get_msgpack_string(s) and sax->string(s);
6651 }
6652
6653 case 0xC0: // nil
6654 return sax->null();
6655
6656 case 0xC2: // false
6657 return sax->boolean(false);
6658
6659 case 0xC3: // true
6660 return sax->boolean(true);
6661
6662 case 0xCA: // float 32
6663 {
6664 float number;
6665 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6666 }
6667
6668 case 0xCB: // float 64
6669 {
6670 double number;
6671 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6672 }
6673
6674 case 0xCC: // uint 8
6675 {
6676 uint8_t number;
6677 return get_number(number) and sax->number_unsigned(number);
6678 }
6679
6680 case 0xCD: // uint 16
6681 {
6682 uint16_t number;
6683 return get_number(number) and sax->number_unsigned(number);
6684 }
6685
6686 case 0xCE: // uint 32
6687 {
6688 uint32_t number;
6689 return get_number(number) and sax->number_unsigned(number);
6690 }
6691
6692 case 0xCF: // uint 64
6693 {
6694 uint64_t number;
6695 return get_number(number) and sax->number_unsigned(number);
6696 }
6697
6698 case 0xD0: // int 8
6699 {
6700 int8_t number;
6701 return get_number(number) and sax->number_integer(number);
6702 }
6703
6704 case 0xD1: // int 16
6705 {
6706 int16_t number;
6707 return get_number(number) and sax->number_integer(number);
6708 }
6709
6710 case 0xD2: // int 32
6711 {
6712 int32_t number;
6713 return get_number(number) and sax->number_integer(number);
6714 }
6715
6716 case 0xD3: // int 64
6717 {
6718 int64_t number;
6719 return get_number(number) and sax->number_integer(number);
6720 }
6721
6722 case 0xD9: // str 8
6723 case 0xDA: // str 16
6724 case 0xDB: // str 32
6725 {
6726 string_t s;
6727 return get_msgpack_string(s) and sax->string(s);
6728 }
6729
6730 case 0xDC: // array 16
6731 {
6732 uint16_t len;
6733 return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6734 }
6735
6736 case 0xDD: // array 32
6737 {
6738 uint32_t len;
6739 return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6740 }
6741
6742 case 0xDE: // map 16
6743 {
6744 uint16_t len;
6745 return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6746 }
6747
6748 case 0xDF: // map 32
6749 {
6750 uint32_t len;
6751 return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6752 }
6753
6754 // negative fixint
6755 case 0xE0:
6756 case 0xE1:
6757 case 0xE2:
6758 case 0xE3:
6759 case 0xE4:
6760 case 0xE5:
6761 case 0xE6:
6762 case 0xE7:
6763 case 0xE8:
6764 case 0xE9:
6765 case 0xEA:
6766 case 0xEB:
6767 case 0xEC:
6768 case 0xED:
6769 case 0xEE:
6770 case 0xEF:
6771 case 0xF0:
6772 case 0xF1:
6773 case 0xF2:
6774 case 0xF3:
6775 case 0xF4:
6776 case 0xF5:
6777 case 0xF6:
6778 case 0xF7:
6779 case 0xF8:
6780 case 0xF9:
6781 case 0xFA:
6782 case 0xFB:
6783 case 0xFC:
6784 case 0xFD:
6785 case 0xFE:
6786 case 0xFF:
6787 return sax->number_integer(static_cast<int8_t>(current));
6788
6789 default: // anything else
6790 {
6791 auto last_token = get_token_string();
6792 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token));
6793 }
6794 }
6795 }
6796
6797 /*!
6798 @param[in] get_char whether a new character should be retrieved from the
6799 input (true, default) or whether the last read
6800 character should be considered instead
6801
6802 @return whether a valid UBJSON value was passed to the SAX parser
6803 */
parse_ubjson_internal(const bool get_char=true)6804 bool parse_ubjson_internal(const bool get_char = true)
6805 {
6806 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6807 }
6808
6809 /*!
6810 @brief get next character from the input
6811
6812 This function provides the interface to the used input adapter. It does
6813 not throw in case the input reached EOF, but returns a -'ve valued
6814 `std::char_traits<char>::eof()` in that case.
6815
6816 @return character read from the input
6817 */
get()6818 int get()
6819 {
6820 ++chars_read;
6821 return (current = ia->get_character());
6822 }
6823
6824 /*!
6825 @return character read from the input after ignoring all 'N' entries
6826 */
get_ignore_noop()6827 int get_ignore_noop()
6828 {
6829 do
6830 {
6831 get();
6832 }
6833 while (current == 'N');
6834
6835 return current;
6836 }
6837
6838 /*
6839 @brief read a number from the input
6840
6841 @tparam NumberType the type of the number
6842 @param[out] result number of type @a NumberType
6843
6844 @return whether conversion completed
6845
6846 @note This function needs to respect the system's endianess, because
6847 bytes in CBOR, MessagePack, and UBJSON are stored in network order
6848 (big endian) and therefore need reordering on little endian systems.
6849 */
6850 template<typename NumberType>
get_number(NumberType & result)6851 bool get_number(NumberType& result)
6852 {
6853 // step 1: read input into array with system's byte order
6854 std::array<uint8_t, sizeof(NumberType)> vec;
6855 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
6856 {
6857 get();
6858 if (JSON_UNLIKELY(not unexpect_eof()))
6859 {
6860 return false;
6861 }
6862
6863 // reverse byte order prior to conversion if necessary
6864 if (is_little_endian)
6865 {
6866 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
6867 }
6868 else
6869 {
6870 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
6871 }
6872 }
6873
6874 // step 2: convert array into number of type T and return
6875 std::memcpy(&result, vec.data(), sizeof(NumberType));
6876 return true;
6877 }
6878
6879 /*!
6880 @brief create a string by reading characters from the input
6881
6882 @tparam NumberType the type of the number
6883 @param[in] len number of characters to read
6884 @param[out] string created by reading @a len bytes
6885
6886 @return whether string creation completed
6887
6888 @note We can not reserve @a len bytes for the result, because @a len
6889 may be too large. Usually, @ref unexpect_eof() detects the end of
6890 the input before we run out of string memory.
6891 */
6892 template<typename NumberType>
get_string(const NumberType len,string_t & result)6893 bool get_string(const NumberType len, string_t& result)
6894 {
6895 bool success = true;
6896 std::generate_n(std::back_inserter(result), len, [this, &success]()
6897 {
6898 get();
6899 if (JSON_UNLIKELY(not unexpect_eof()))
6900 {
6901 success = false;
6902 }
6903 return static_cast<char>(current);
6904 });
6905 return success;
6906 }
6907
6908 /*!
6909 @brief reads a CBOR string
6910
6911 This function first reads starting bytes to determine the expected
6912 string length and then copies this number of bytes into a string.
6913 Additionally, CBOR's strings with indefinite lengths are supported.
6914
6915 @param[out] result created string
6916
6917 @return whether string creation completed
6918 */
get_cbor_string(string_t & result)6919 bool get_cbor_string(string_t& result)
6920 {
6921 if (JSON_UNLIKELY(not unexpect_eof()))
6922 {
6923 return false;
6924 }
6925
6926 switch (current)
6927 {
6928 // UTF-8 string (0x00..0x17 bytes follow)
6929 case 0x60:
6930 case 0x61:
6931 case 0x62:
6932 case 0x63:
6933 case 0x64:
6934 case 0x65:
6935 case 0x66:
6936 case 0x67:
6937 case 0x68:
6938 case 0x69:
6939 case 0x6A:
6940 case 0x6B:
6941 case 0x6C:
6942 case 0x6D:
6943 case 0x6E:
6944 case 0x6F:
6945 case 0x70:
6946 case 0x71:
6947 case 0x72:
6948 case 0x73:
6949 case 0x74:
6950 case 0x75:
6951 case 0x76:
6952 case 0x77:
6953 {
6954 return get_string(current & 0x1F, result);
6955 }
6956
6957 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6958 {
6959 uint8_t len;
6960 return get_number(len) and get_string(len, result);
6961 }
6962
6963 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6964 {
6965 uint16_t len;
6966 return get_number(len) and get_string(len, result);
6967 }
6968
6969 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6970 {
6971 uint32_t len;
6972 return get_number(len) and get_string(len, result);
6973 }
6974
6975 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6976 {
6977 uint64_t len;
6978 return get_number(len) and get_string(len, result);
6979 }
6980
6981 case 0x7F: // UTF-8 string (indefinite length)
6982 {
6983 while (get() != 0xFF)
6984 {
6985 string_t chunk;
6986 if (not get_cbor_string(chunk))
6987 {
6988 return false;
6989 }
6990 result.append(chunk);
6991 }
6992 return true;
6993 }
6994
6995 default:
6996 {
6997 auto last_token = get_token_string();
6998 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token));
6999 }
7000 }
7001 }
7002
7003 /*!
7004 @param[in] len the length of the array or std::size_t(-1) for an
7005 array of indefinite size
7006 @return whether array creation completed
7007 */
get_cbor_array(const std::size_t len)7008 bool get_cbor_array(const std::size_t len)
7009 {
7010 if (JSON_UNLIKELY(not sax->start_array(len)))
7011 {
7012 return false;
7013 }
7014
7015 if (len != std::size_t(-1))
7016 for (std::size_t i = 0; i < len; ++i)
7017 {
7018 if (JSON_UNLIKELY(not parse_cbor_internal()))
7019 {
7020 return false;
7021 }
7022 }
7023 else
7024 {
7025 while (get() != 0xFF)
7026 {
7027 if (JSON_UNLIKELY(not parse_cbor_internal(false)))
7028 {
7029 return false;
7030 }
7031 }
7032 }
7033
7034 return sax->end_array();
7035 }
7036
7037 /*!
7038 @param[in] len the length of the object or std::size_t(-1) for an
7039 object of indefinite size
7040 @return whether object creation completed
7041 */
get_cbor_object(const std::size_t len)7042 bool get_cbor_object(const std::size_t len)
7043 {
7044 if (not JSON_UNLIKELY(sax->start_object(len)))
7045 {
7046 return false;
7047 }
7048
7049 string_t key;
7050 if (len != std::size_t(-1))
7051 {
7052 for (std::size_t i = 0; i < len; ++i)
7053 {
7054 get();
7055 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7056 {
7057 return false;
7058 }
7059
7060 if (JSON_UNLIKELY(not parse_cbor_internal()))
7061 {
7062 return false;
7063 }
7064 key.clear();
7065 }
7066 }
7067 else
7068 {
7069 while (get() != 0xFF)
7070 {
7071 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7072 {
7073 return false;
7074 }
7075
7076 if (JSON_UNLIKELY(not parse_cbor_internal()))
7077 {
7078 return false;
7079 }
7080 key.clear();
7081 }
7082 }
7083
7084 return sax->end_object();
7085 }
7086
7087 /*!
7088 @brief reads a MessagePack string
7089
7090 This function first reads starting bytes to determine the expected
7091 string length and then copies this number of bytes into a string.
7092
7093 @param[out] result created string
7094
7095 @return whether string creation completed
7096 */
get_msgpack_string(string_t & result)7097 bool get_msgpack_string(string_t& result)
7098 {
7099 if (JSON_UNLIKELY(not unexpect_eof()))
7100 {
7101 return false;
7102 }
7103
7104 switch (current)
7105 {
7106 // fixstr
7107 case 0xA0:
7108 case 0xA1:
7109 case 0xA2:
7110 case 0xA3:
7111 case 0xA4:
7112 case 0xA5:
7113 case 0xA6:
7114 case 0xA7:
7115 case 0xA8:
7116 case 0xA9:
7117 case 0xAA:
7118 case 0xAB:
7119 case 0xAC:
7120 case 0xAD:
7121 case 0xAE:
7122 case 0xAF:
7123 case 0xB0:
7124 case 0xB1:
7125 case 0xB2:
7126 case 0xB3:
7127 case 0xB4:
7128 case 0xB5:
7129 case 0xB6:
7130 case 0xB7:
7131 case 0xB8:
7132 case 0xB9:
7133 case 0xBA:
7134 case 0xBB:
7135 case 0xBC:
7136 case 0xBD:
7137 case 0xBE:
7138 case 0xBF:
7139 {
7140 return get_string(current & 0x1F, result);
7141 }
7142
7143 case 0xD9: // str 8
7144 {
7145 uint8_t len;
7146 return get_number(len) and get_string(len, result);
7147 }
7148
7149 case 0xDA: // str 16
7150 {
7151 uint16_t len;
7152 return get_number(len) and get_string(len, result);
7153 }
7154
7155 case 0xDB: // str 32
7156 {
7157 uint32_t len;
7158 return get_number(len) and get_string(len, result);
7159 }
7160
7161 default:
7162 {
7163 auto last_token = get_token_string();
7164 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token));
7165 }
7166 }
7167 }
7168
7169 /*!
7170 @param[in] len the length of the array
7171 @return whether array creation completed
7172 */
get_msgpack_array(const std::size_t len)7173 bool get_msgpack_array(const std::size_t len)
7174 {
7175 if (JSON_UNLIKELY(not sax->start_array(len)))
7176 {
7177 return false;
7178 }
7179
7180 for (std::size_t i = 0; i < len; ++i)
7181 {
7182 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7183 {
7184 return false;
7185 }
7186 }
7187
7188 return sax->end_array();
7189 }
7190
7191 /*!
7192 @param[in] len the length of the object
7193 @return whether object creation completed
7194 */
get_msgpack_object(const std::size_t len)7195 bool get_msgpack_object(const std::size_t len)
7196 {
7197 if (JSON_UNLIKELY(not sax->start_object(len)))
7198 {
7199 return false;
7200 }
7201
7202 string_t key;
7203 for (std::size_t i = 0; i < len; ++i)
7204 {
7205 get();
7206 if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7207 {
7208 return false;
7209 }
7210
7211 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7212 {
7213 return false;
7214 }
7215 key.clear();
7216 }
7217
7218 return sax->end_object();
7219 }
7220
7221 /*!
7222 @brief reads a UBJSON string
7223
7224 This function is either called after reading the 'S' byte explicitly
7225 indicating a string, or in case of an object key where the 'S' byte can be
7226 left out.
7227
7228 @param[out] result created string
7229 @param[in] get_char whether a new character should be retrieved from the
7230 input (true, default) or whether the last read
7231 character should be considered instead
7232
7233 @return whether string creation completed
7234 */
get_ubjson_string(string_t & result,const bool get_char=true)7235 bool get_ubjson_string(string_t& result, const bool get_char = true)
7236 {
7237 if (get_char)
7238 {
7239 get(); // TODO: may we ignore N here?
7240 }
7241
7242 if (JSON_UNLIKELY(not unexpect_eof()))
7243 {
7244 return false;
7245 }
7246
7247 switch (current)
7248 {
7249 case 'U':
7250 {
7251 uint8_t len;
7252 return get_number(len) and get_string(len, result);
7253 }
7254
7255 case 'i':
7256 {
7257 int8_t len;
7258 return get_number(len) and get_string(len, result);
7259 }
7260
7261 case 'I':
7262 {
7263 int16_t len;
7264 return get_number(len) and get_string(len, result);
7265 }
7266
7267 case 'l':
7268 {
7269 int32_t len;
7270 return get_number(len) and get_string(len, result);
7271 }
7272
7273 case 'L':
7274 {
7275 int64_t len;
7276 return get_number(len) and get_string(len, result);
7277 }
7278
7279 default:
7280 auto last_token = get_token_string();
7281 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token));
7282 }
7283 }
7284
7285 /*!
7286 @param[out] result determined size
7287 @return whether size determination completed
7288 */
get_ubjson_size_value(std::size_t & result)7289 bool get_ubjson_size_value(std::size_t& result)
7290 {
7291 switch (get_ignore_noop())
7292 {
7293 case 'U':
7294 {
7295 uint8_t number;
7296 if (JSON_UNLIKELY(not get_number(number)))
7297 {
7298 return false;
7299 }
7300 result = static_cast<std::size_t>(number);
7301 return true;
7302 }
7303
7304 case 'i':
7305 {
7306 int8_t number;
7307 if (JSON_UNLIKELY(not get_number(number)))
7308 {
7309 return false;
7310 }
7311 result = static_cast<std::size_t>(number);
7312 return true;
7313 }
7314
7315 case 'I':
7316 {
7317 int16_t number;
7318 if (JSON_UNLIKELY(not get_number(number)))
7319 {
7320 return false;
7321 }
7322 result = static_cast<std::size_t>(number);
7323 return true;
7324 }
7325
7326 case 'l':
7327 {
7328 int32_t number;
7329 if (JSON_UNLIKELY(not get_number(number)))
7330 {
7331 return false;
7332 }
7333 result = static_cast<std::size_t>(number);
7334 return true;
7335 }
7336
7337 case 'L':
7338 {
7339 int64_t number;
7340 if (JSON_UNLIKELY(not get_number(number)))
7341 {
7342 return false;
7343 }
7344 result = static_cast<std::size_t>(number);
7345 return true;
7346 }
7347
7348 default:
7349 {
7350 auto last_token = get_token_string();
7351 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after '#' must denote a number type; last byte: 0x" + last_token));
7352 }
7353 }
7354 }
7355
7356 /*!
7357 @brief determine the type and size for a container
7358
7359 In the optimized UBJSON format, a type and a size can be provided to allow
7360 for a more compact representation.
7361
7362 @param[out] result pair of the size and the type
7363
7364 @return whether pair creation completed
7365 */
get_ubjson_size_type(std::pair<std::size_t,int> & result)7366 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7367 {
7368 result.first = string_t::npos; // size
7369 result.second = 0; // type
7370
7371 get_ignore_noop();
7372
7373 if (current == '$')
7374 {
7375 result.second = get(); // must not ignore 'N', because 'N' maybe the type
7376 if (JSON_UNLIKELY(not unexpect_eof()))
7377 {
7378 return false;
7379 }
7380
7381 get_ignore_noop();
7382 if (JSON_UNLIKELY(current != '#'))
7383 {
7384 if (JSON_UNLIKELY(not unexpect_eof()))
7385 {
7386 return false;
7387 }
7388 auto last_token = get_token_string();
7389 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token));
7390 }
7391
7392 return get_ubjson_size_value(result.first);
7393 }
7394 else if (current == '#')
7395 {
7396 return get_ubjson_size_value(result.first);
7397 }
7398 return true;
7399 }
7400
7401 /*!
7402 @param prefix the previously read or set type prefix
7403 @return whether value creation completed
7404 */
get_ubjson_value(const int prefix)7405 bool get_ubjson_value(const int prefix)
7406 {
7407 switch (prefix)
7408 {
7409 case std::char_traits<char>::eof(): // EOF
7410 return unexpect_eof();
7411
7412 case 'T': // true
7413 return sax->boolean(true);
7414 case 'F': // false
7415 return sax->boolean(false);
7416
7417 case 'Z': // null
7418 return sax->null();
7419
7420 case 'U':
7421 {
7422 uint8_t number;
7423 return get_number(number) and sax->number_unsigned(number);
7424 }
7425
7426 case 'i':
7427 {
7428 int8_t number;
7429 return get_number(number) and sax->number_integer(number);
7430 }
7431
7432 case 'I':
7433 {
7434 int16_t number;
7435 return get_number(number) and sax->number_integer(number);
7436 }
7437
7438 case 'l':
7439 {
7440 int32_t number;
7441 return get_number(number) and sax->number_integer(number);
7442 }
7443
7444 case 'L':
7445 {
7446 int64_t number;
7447 return get_number(number) and sax->number_integer(number);
7448 }
7449
7450 case 'd':
7451 {
7452 float number;
7453 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7454 }
7455
7456 case 'D':
7457 {
7458 double number;
7459 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7460 }
7461
7462 case 'C': // char
7463 {
7464 get();
7465 if (JSON_UNLIKELY(not unexpect_eof()))
7466 {
7467 return false;
7468 }
7469 if (JSON_UNLIKELY(current > 127))
7470 {
7471 auto last_token = get_token_string();
7472 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token));
7473 }
7474 string_t s(1, static_cast<char>(current));
7475 return sax->string(s);
7476 }
7477
7478 case 'S': // string
7479 {
7480 string_t s;
7481 return get_ubjson_string(s) and sax->string(s);
7482 }
7483
7484 case '[': // array
7485 return get_ubjson_array();
7486
7487 case '{': // object
7488 return get_ubjson_object();
7489
7490 default: // anything else
7491 {
7492 auto last_token = get_token_string();
7493 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token));
7494 }
7495 }
7496 }
7497
7498 /*!
7499 @return whether array creation completed
7500 */
get_ubjson_array()7501 bool get_ubjson_array()
7502 {
7503 std::pair<std::size_t, int> size_and_type;
7504 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7505 {
7506 return false;
7507 }
7508
7509 if (size_and_type.first != string_t::npos)
7510 {
7511 if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
7512 {
7513 return false;
7514 }
7515
7516 if (size_and_type.second != 0)
7517 {
7518 if (size_and_type.second != 'N')
7519 {
7520 for (std::size_t i = 0; i < size_and_type.first; ++i)
7521 {
7522 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7523 {
7524 return false;
7525 }
7526 }
7527 }
7528 }
7529 else
7530 {
7531 for (std::size_t i = 0; i < size_and_type.first; ++i)
7532 {
7533 if (JSON_UNLIKELY(not parse_ubjson_internal()))
7534 {
7535 return false;
7536 }
7537 }
7538 }
7539 }
7540 else
7541 {
7542 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7543 {
7544 return false;
7545 }
7546
7547 while (current != ']')
7548 {
7549 if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
7550 {
7551 return false;
7552 }
7553 get_ignore_noop();
7554 }
7555 }
7556
7557 return sax->end_array();
7558 }
7559
7560 /*!
7561 @return whether object creation completed
7562 */
get_ubjson_object()7563 bool get_ubjson_object()
7564 {
7565 std::pair<std::size_t, int> size_and_type;
7566 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7567 {
7568 return false;
7569 }
7570
7571 string_t key;
7572 if (size_and_type.first != string_t::npos)
7573 {
7574 if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
7575 {
7576 return false;
7577 }
7578
7579 if (size_and_type.second != 0)
7580 {
7581 for (std::size_t i = 0; i < size_and_type.first; ++i)
7582 {
7583 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7584 {
7585 return false;
7586 }
7587 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7588 {
7589 return false;
7590 }
7591 key.clear();
7592 }
7593 }
7594 else
7595 {
7596 for (std::size_t i = 0; i < size_and_type.first; ++i)
7597 {
7598 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7599 {
7600 return false;
7601 }
7602 if (JSON_UNLIKELY(not parse_ubjson_internal()))
7603 {
7604 return false;
7605 }
7606 key.clear();
7607 }
7608 }
7609 }
7610 else
7611 {
7612 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7613 {
7614 return false;
7615 }
7616
7617 while (current != '}')
7618 {
7619 if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7620 {
7621 return false;
7622 }
7623 if (JSON_UNLIKELY(not parse_ubjson_internal()))
7624 {
7625 return false;
7626 }
7627 get_ignore_noop();
7628 key.clear();
7629 }
7630 }
7631
7632 return sax->end_object();
7633 }
7634
7635 /*!
7636 @return whether the last read character is not EOF
7637 */
unexpect_eof() const7638 bool unexpect_eof() const
7639 {
7640 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
7641 {
7642 return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input"));
7643 }
7644 return true;
7645 }
7646
7647 /*!
7648 @return a string representation of the last read byte
7649 */
get_token_string() const7650 std::string get_token_string() const
7651 {
7652 char cr[3];
7653 snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
7654 return std::string{cr};
7655 }
7656
7657 private:
7658 /// input adapter
7659 input_adapter_t ia = nullptr;
7660
7661 /// the current character
7662 int current = std::char_traits<char>::eof();
7663
7664 /// the number of characters read
7665 std::size_t chars_read = 0;
7666
7667 /// whether we can assume little endianess
7668 const bool is_little_endian = little_endianess();
7669
7670 /// the SAX parser
7671 json_sax_t* sax = nullptr;
7672 };
7673 }
7674 }
7675
7676 // #include <nlohmann/detail/output/binary_writer.hpp>
7677
7678
7679 #include <algorithm> // reverse
7680 #include <array> // array
7681 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
7682 #include <cstring> // memcpy
7683 #include <limits> // numeric_limits
7684
7685 // #include <nlohmann/detail/input/binary_reader.hpp>
7686
7687 // #include <nlohmann/detail/output/output_adapters.hpp>
7688
7689
7690 namespace nlohmann
7691 {
7692 namespace detail
7693 {
7694 ///////////////////
7695 // binary writer //
7696 ///////////////////
7697
7698 /*!
7699 @brief serialization to CBOR and MessagePack values
7700 */
7701 template<typename BasicJsonType, typename CharType>
7702 class binary_writer
7703 {
7704 public:
7705 /*!
7706 @brief create a binary writer
7707
7708 @param[in] adapter output adapter to write to
7709 */
binary_writer(output_adapter_t<CharType> adapter)7710 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
7711 {
7712 assert(oa);
7713 }
7714
7715 /*!
7716 @brief[in] j JSON value to serialize
7717 */
write_cbor(const BasicJsonType & j)7718 void write_cbor(const BasicJsonType& j)
7719 {
7720 switch (j.type())
7721 {
7722 case value_t::null:
7723 {
7724 oa->write_character(static_cast<CharType>(0xF6));
7725 break;
7726 }
7727
7728 case value_t::boolean:
7729 {
7730 oa->write_character(j.m_value.boolean
7731 ? static_cast<CharType>(0xF5)
7732 : static_cast<CharType>(0xF4));
7733 break;
7734 }
7735
7736 case value_t::number_integer:
7737 {
7738 if (j.m_value.number_integer >= 0)
7739 {
7740 // CBOR does not differentiate between positive signed
7741 // integers and unsigned integers. Therefore, we used the
7742 // code from the value_t::number_unsigned case here.
7743 if (j.m_value.number_integer <= 0x17)
7744 {
7745 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7746 }
7747 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7748 {
7749 oa->write_character(static_cast<CharType>(0x18));
7750 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7751 }
7752 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
7753 {
7754 oa->write_character(static_cast<CharType>(0x19));
7755 write_number(static_cast<uint16_t>(j.m_value.number_integer));
7756 }
7757 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
7758 {
7759 oa->write_character(static_cast<CharType>(0x1A));
7760 write_number(static_cast<uint32_t>(j.m_value.number_integer));
7761 }
7762 else
7763 {
7764 oa->write_character(static_cast<CharType>(0x1B));
7765 write_number(static_cast<uint64_t>(j.m_value.number_integer));
7766 }
7767 }
7768 else
7769 {
7770 // The conversions below encode the sign in the first
7771 // byte, and the value is converted to a positive number.
7772 const auto positive_number = -1 - j.m_value.number_integer;
7773 if (j.m_value.number_integer >= -24)
7774 {
7775 write_number(static_cast<uint8_t>(0x20 + positive_number));
7776 }
7777 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
7778 {
7779 oa->write_character(static_cast<CharType>(0x38));
7780 write_number(static_cast<uint8_t>(positive_number));
7781 }
7782 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
7783 {
7784 oa->write_character(static_cast<CharType>(0x39));
7785 write_number(static_cast<uint16_t>(positive_number));
7786 }
7787 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
7788 {
7789 oa->write_character(static_cast<CharType>(0x3A));
7790 write_number(static_cast<uint32_t>(positive_number));
7791 }
7792 else
7793 {
7794 oa->write_character(static_cast<CharType>(0x3B));
7795 write_number(static_cast<uint64_t>(positive_number));
7796 }
7797 }
7798 break;
7799 }
7800
7801 case value_t::number_unsigned:
7802 {
7803 if (j.m_value.number_unsigned <= 0x17)
7804 {
7805 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7806 }
7807 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7808 {
7809 oa->write_character(static_cast<CharType>(0x18));
7810 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7811 }
7812 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7813 {
7814 oa->write_character(static_cast<CharType>(0x19));
7815 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
7816 }
7817 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7818 {
7819 oa->write_character(static_cast<CharType>(0x1A));
7820 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
7821 }
7822 else
7823 {
7824 oa->write_character(static_cast<CharType>(0x1B));
7825 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
7826 }
7827 break;
7828 }
7829
7830 case value_t::number_float:
7831 {
7832 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
7833 write_number(j.m_value.number_float);
7834 break;
7835 }
7836
7837 case value_t::string:
7838 {
7839 // step 1: write control byte and the string length
7840 const auto N = j.m_value.string->size();
7841 if (N <= 0x17)
7842 {
7843 write_number(static_cast<uint8_t>(0x60 + N));
7844 }
7845 else if (N <= (std::numeric_limits<uint8_t>::max)())
7846 {
7847 oa->write_character(static_cast<CharType>(0x78));
7848 write_number(static_cast<uint8_t>(N));
7849 }
7850 else if (N <= (std::numeric_limits<uint16_t>::max)())
7851 {
7852 oa->write_character(static_cast<CharType>(0x79));
7853 write_number(static_cast<uint16_t>(N));
7854 }
7855 else if (N <= (std::numeric_limits<uint32_t>::max)())
7856 {
7857 oa->write_character(static_cast<CharType>(0x7A));
7858 write_number(static_cast<uint32_t>(N));
7859 }
7860 // LCOV_EXCL_START
7861 else if (N <= (std::numeric_limits<uint64_t>::max)())
7862 {
7863 oa->write_character(static_cast<CharType>(0x7B));
7864 write_number(static_cast<uint64_t>(N));
7865 }
7866 // LCOV_EXCL_STOP
7867
7868 // step 2: write the string
7869 oa->write_characters(
7870 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
7871 j.m_value.string->size());
7872 break;
7873 }
7874
7875 case value_t::array:
7876 {
7877 // step 1: write control byte and the array size
7878 const auto N = j.m_value.array->size();
7879 if (N <= 0x17)
7880 {
7881 write_number(static_cast<uint8_t>(0x80 + N));
7882 }
7883 else if (N <= (std::numeric_limits<uint8_t>::max)())
7884 {
7885 oa->write_character(static_cast<CharType>(0x98));
7886 write_number(static_cast<uint8_t>(N));
7887 }
7888 else if (N <= (std::numeric_limits<uint16_t>::max)())
7889 {
7890 oa->write_character(static_cast<CharType>(0x99));
7891 write_number(static_cast<uint16_t>(N));
7892 }
7893 else if (N <= (std::numeric_limits<uint32_t>::max)())
7894 {
7895 oa->write_character(static_cast<CharType>(0x9A));
7896 write_number(static_cast<uint32_t>(N));
7897 }
7898 // LCOV_EXCL_START
7899 else if (N <= (std::numeric_limits<uint64_t>::max)())
7900 {
7901 oa->write_character(static_cast<CharType>(0x9B));
7902 write_number(static_cast<uint64_t>(N));
7903 }
7904 // LCOV_EXCL_STOP
7905
7906 // step 2: write each element
7907 for (const auto& el : *j.m_value.array)
7908 {
7909 write_cbor(el);
7910 }
7911 break;
7912 }
7913
7914 case value_t::object:
7915 {
7916 // step 1: write control byte and the object size
7917 const auto N = j.m_value.object->size();
7918 if (N <= 0x17)
7919 {
7920 write_number(static_cast<uint8_t>(0xA0 + N));
7921 }
7922 else if (N <= (std::numeric_limits<uint8_t>::max)())
7923 {
7924 oa->write_character(static_cast<CharType>(0xB8));
7925 write_number(static_cast<uint8_t>(N));
7926 }
7927 else if (N <= (std::numeric_limits<uint16_t>::max)())
7928 {
7929 oa->write_character(static_cast<CharType>(0xB9));
7930 write_number(static_cast<uint16_t>(N));
7931 }
7932 else if (N <= (std::numeric_limits<uint32_t>::max)())
7933 {
7934 oa->write_character(static_cast<CharType>(0xBA));
7935 write_number(static_cast<uint32_t>(N));
7936 }
7937 // LCOV_EXCL_START
7938 else if (N <= (std::numeric_limits<uint64_t>::max)())
7939 {
7940 oa->write_character(static_cast<CharType>(0xBB));
7941 write_number(static_cast<uint64_t>(N));
7942 }
7943 // LCOV_EXCL_STOP
7944
7945 // step 2: write each element
7946 for (const auto& el : *j.m_value.object)
7947 {
7948 write_cbor(el.first);
7949 write_cbor(el.second);
7950 }
7951 break;
7952 }
7953
7954 default:
7955 break;
7956 }
7957 }
7958
7959 /*!
7960 @brief[in] j JSON value to serialize
7961 */
write_msgpack(const BasicJsonType & j)7962 void write_msgpack(const BasicJsonType& j)
7963 {
7964 switch (j.type())
7965 {
7966 case value_t::null: // nil
7967 {
7968 oa->write_character(static_cast<CharType>(0xC0));
7969 break;
7970 }
7971
7972 case value_t::boolean: // true and false
7973 {
7974 oa->write_character(j.m_value.boolean
7975 ? static_cast<CharType>(0xC3)
7976 : static_cast<CharType>(0xC2));
7977 break;
7978 }
7979
7980 case value_t::number_integer:
7981 {
7982 if (j.m_value.number_integer >= 0)
7983 {
7984 // MessagePack does not differentiate between positive
7985 // signed integers and unsigned integers. Therefore, we used
7986 // the code from the value_t::number_unsigned case here.
7987 if (j.m_value.number_unsigned < 128)
7988 {
7989 // positive fixnum
7990 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7991 }
7992 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7993 {
7994 // uint 8
7995 oa->write_character(static_cast<CharType>(0xCC));
7996 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7997 }
7998 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7999 {
8000 // uint 16
8001 oa->write_character(static_cast<CharType>(0xCD));
8002 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8003 }
8004 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8005 {
8006 // uint 32
8007 oa->write_character(static_cast<CharType>(0xCE));
8008 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8009 }
8010 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8011 {
8012 // uint 64
8013 oa->write_character(static_cast<CharType>(0xCF));
8014 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8015 }
8016 }
8017 else
8018 {
8019 if (j.m_value.number_integer >= -32)
8020 {
8021 // negative fixnum
8022 write_number(static_cast<int8_t>(j.m_value.number_integer));
8023 }
8024 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
8025 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8026 {
8027 // int 8
8028 oa->write_character(static_cast<CharType>(0xD0));
8029 write_number(static_cast<int8_t>(j.m_value.number_integer));
8030 }
8031 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
8032 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8033 {
8034 // int 16
8035 oa->write_character(static_cast<CharType>(0xD1));
8036 write_number(static_cast<int16_t>(j.m_value.number_integer));
8037 }
8038 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
8039 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8040 {
8041 // int 32
8042 oa->write_character(static_cast<CharType>(0xD2));
8043 write_number(static_cast<int32_t>(j.m_value.number_integer));
8044 }
8045 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
8046 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
8047 {
8048 // int 64
8049 oa->write_character(static_cast<CharType>(0xD3));
8050 write_number(static_cast<int64_t>(j.m_value.number_integer));
8051 }
8052 }
8053 break;
8054 }
8055
8056 case value_t::number_unsigned:
8057 {
8058 if (j.m_value.number_unsigned < 128)
8059 {
8060 // positive fixnum
8061 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8062 }
8063 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8064 {
8065 // uint 8
8066 oa->write_character(static_cast<CharType>(0xCC));
8067 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8068 }
8069 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8070 {
8071 // uint 16
8072 oa->write_character(static_cast<CharType>(0xCD));
8073 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8074 }
8075 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8076 {
8077 // uint 32
8078 oa->write_character(static_cast<CharType>(0xCE));
8079 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8080 }
8081 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8082 {
8083 // uint 64
8084 oa->write_character(static_cast<CharType>(0xCF));
8085 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8086 }
8087 break;
8088 }
8089
8090 case value_t::number_float:
8091 {
8092 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8093 write_number(j.m_value.number_float);
8094 break;
8095 }
8096
8097 case value_t::string:
8098 {
8099 // step 1: write control byte and the string length
8100 const auto N = j.m_value.string->size();
8101 if (N <= 31)
8102 {
8103 // fixstr
8104 write_number(static_cast<uint8_t>(0xA0 | N));
8105 }
8106 else if (N <= (std::numeric_limits<uint8_t>::max)())
8107 {
8108 // str 8
8109 oa->write_character(static_cast<CharType>(0xD9));
8110 write_number(static_cast<uint8_t>(N));
8111 }
8112 else if (N <= (std::numeric_limits<uint16_t>::max)())
8113 {
8114 // str 16
8115 oa->write_character(static_cast<CharType>(0xDA));
8116 write_number(static_cast<uint16_t>(N));
8117 }
8118 else if (N <= (std::numeric_limits<uint32_t>::max)())
8119 {
8120 // str 32
8121 oa->write_character(static_cast<CharType>(0xDB));
8122 write_number(static_cast<uint32_t>(N));
8123 }
8124
8125 // step 2: write the string
8126 oa->write_characters(
8127 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8128 j.m_value.string->size());
8129 break;
8130 }
8131
8132 case value_t::array:
8133 {
8134 // step 1: write control byte and the array size
8135 const auto N = j.m_value.array->size();
8136 if (N <= 15)
8137 {
8138 // fixarray
8139 write_number(static_cast<uint8_t>(0x90 | N));
8140 }
8141 else if (N <= (std::numeric_limits<uint16_t>::max)())
8142 {
8143 // array 16
8144 oa->write_character(static_cast<CharType>(0xDC));
8145 write_number(static_cast<uint16_t>(N));
8146 }
8147 else if (N <= (std::numeric_limits<uint32_t>::max)())
8148 {
8149 // array 32
8150 oa->write_character(static_cast<CharType>(0xDD));
8151 write_number(static_cast<uint32_t>(N));
8152 }
8153
8154 // step 2: write each element
8155 for (const auto& el : *j.m_value.array)
8156 {
8157 write_msgpack(el);
8158 }
8159 break;
8160 }
8161
8162 case value_t::object:
8163 {
8164 // step 1: write control byte and the object size
8165 const auto N = j.m_value.object->size();
8166 if (N <= 15)
8167 {
8168 // fixmap
8169 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8170 }
8171 else if (N <= (std::numeric_limits<uint16_t>::max)())
8172 {
8173 // map 16
8174 oa->write_character(static_cast<CharType>(0xDE));
8175 write_number(static_cast<uint16_t>(N));
8176 }
8177 else if (N <= (std::numeric_limits<uint32_t>::max)())
8178 {
8179 // map 32
8180 oa->write_character(static_cast<CharType>(0xDF));
8181 write_number(static_cast<uint32_t>(N));
8182 }
8183
8184 // step 2: write each element
8185 for (const auto& el : *j.m_value.object)
8186 {
8187 write_msgpack(el.first);
8188 write_msgpack(el.second);
8189 }
8190 break;
8191 }
8192
8193 default:
8194 break;
8195 }
8196 }
8197
8198 /*!
8199 @param[in] j JSON value to serialize
8200 @param[in] use_count whether to use '#' prefixes (optimized format)
8201 @param[in] use_type whether to use '$' prefixes (optimized format)
8202 @param[in] add_prefix whether prefixes need to be used for this value
8203 */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)8204 void write_ubjson(const BasicJsonType& j, const bool use_count,
8205 const bool use_type, const bool add_prefix = true)
8206 {
8207 switch (j.type())
8208 {
8209 case value_t::null:
8210 {
8211 if (add_prefix)
8212 {
8213 oa->write_character(static_cast<CharType>('Z'));
8214 }
8215 break;
8216 }
8217
8218 case value_t::boolean:
8219 {
8220 if (add_prefix)
8221 oa->write_character(j.m_value.boolean
8222 ? static_cast<CharType>('T')
8223 : static_cast<CharType>('F'));
8224 break;
8225 }
8226
8227 case value_t::number_integer:
8228 {
8229 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
8230 break;
8231 }
8232
8233 case value_t::number_unsigned:
8234 {
8235 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
8236 break;
8237 }
8238
8239 case value_t::number_float:
8240 {
8241 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
8242 break;
8243 }
8244
8245 case value_t::string:
8246 {
8247 if (add_prefix)
8248 {
8249 oa->write_character(static_cast<CharType>('S'));
8250 }
8251 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
8252 oa->write_characters(
8253 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8254 j.m_value.string->size());
8255 break;
8256 }
8257
8258 case value_t::array:
8259 {
8260 if (add_prefix)
8261 {
8262 oa->write_character(static_cast<CharType>('['));
8263 }
8264
8265 bool prefix_required = true;
8266 if (use_type and not j.m_value.array->empty())
8267 {
8268 assert(use_count);
8269 const CharType first_prefix = ubjson_prefix(j.front());
8270 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
8271 [this, first_prefix](const BasicJsonType & v)
8272 {
8273 return ubjson_prefix(v) == first_prefix;
8274 });
8275
8276 if (same_prefix)
8277 {
8278 prefix_required = false;
8279 oa->write_character(static_cast<CharType>('$'));
8280 oa->write_character(first_prefix);
8281 }
8282 }
8283
8284 if (use_count)
8285 {
8286 oa->write_character(static_cast<CharType>('#'));
8287 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
8288 }
8289
8290 for (const auto& el : *j.m_value.array)
8291 {
8292 write_ubjson(el, use_count, use_type, prefix_required);
8293 }
8294
8295 if (not use_count)
8296 {
8297 oa->write_character(static_cast<CharType>(']'));
8298 }
8299
8300 break;
8301 }
8302
8303 case value_t::object:
8304 {
8305 if (add_prefix)
8306 {
8307 oa->write_character(static_cast<CharType>('{'));
8308 }
8309
8310 bool prefix_required = true;
8311 if (use_type and not j.m_value.object->empty())
8312 {
8313 assert(use_count);
8314 const CharType first_prefix = ubjson_prefix(j.front());
8315 const bool same_prefix = std::all_of(j.begin(), j.end(),
8316 [this, first_prefix](const BasicJsonType & v)
8317 {
8318 return ubjson_prefix(v) == first_prefix;
8319 });
8320
8321 if (same_prefix)
8322 {
8323 prefix_required = false;
8324 oa->write_character(static_cast<CharType>('$'));
8325 oa->write_character(first_prefix);
8326 }
8327 }
8328
8329 if (use_count)
8330 {
8331 oa->write_character(static_cast<CharType>('#'));
8332 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
8333 }
8334
8335 for (const auto& el : *j.m_value.object)
8336 {
8337 write_number_with_ubjson_prefix(el.first.size(), true);
8338 oa->write_characters(
8339 reinterpret_cast<const CharType*>(el.first.c_str()),
8340 el.first.size());
8341 write_ubjson(el.second, use_count, use_type, prefix_required);
8342 }
8343
8344 if (not use_count)
8345 {
8346 oa->write_character(static_cast<CharType>('}'));
8347 }
8348
8349 break;
8350 }
8351
8352 default:
8353 break;
8354 }
8355 }
8356
8357 private:
8358 /*
8359 @brief write a number to output input
8360
8361 @param[in] n number of type @a NumberType
8362 @tparam NumberType the type of the number
8363
8364 @note This function needs to respect the system's endianess, because bytes
8365 in CBOR, MessagePack, and UBJSON are stored in network order (big
8366 endian) and therefore need reordering on little endian systems.
8367 */
8368 template<typename NumberType>
write_number(const NumberType n)8369 void write_number(const NumberType n)
8370 {
8371 // step 1: write number to array of length NumberType
8372 std::array<CharType, sizeof(NumberType)> vec;
8373 std::memcpy(vec.data(), &n, sizeof(NumberType));
8374
8375 // step 2: write array to output (with possible reordering)
8376 if (is_little_endian)
8377 {
8378 // reverse byte order prior to conversion if necessary
8379 std::reverse(vec.begin(), vec.end());
8380 }
8381
8382 oa->write_characters(vec.data(), sizeof(NumberType));
8383 }
8384
8385 // UBJSON: write number (floating point)
8386 template<typename NumberType, typename std::enable_if<
8387 std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8388 void write_number_with_ubjson_prefix(const NumberType n,
8389 const bool add_prefix)
8390 {
8391 if (add_prefix)
8392 {
8393 oa->write_character(get_ubjson_float_prefix(n));
8394 }
8395 write_number(n);
8396 }
8397
8398 // UBJSON: write number (unsigned integer)
8399 template<typename NumberType, typename std::enable_if<
8400 std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8401 void write_number_with_ubjson_prefix(const NumberType n,
8402 const bool add_prefix)
8403 {
8404 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
8405 {
8406 if (add_prefix)
8407 {
8408 oa->write_character(static_cast<CharType>('i')); // int8
8409 }
8410 write_number(static_cast<uint8_t>(n));
8411 }
8412 else if (n <= (std::numeric_limits<uint8_t>::max)())
8413 {
8414 if (add_prefix)
8415 {
8416 oa->write_character(static_cast<CharType>('U')); // uint8
8417 }
8418 write_number(static_cast<uint8_t>(n));
8419 }
8420 else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
8421 {
8422 if (add_prefix)
8423 {
8424 oa->write_character(static_cast<CharType>('I')); // int16
8425 }
8426 write_number(static_cast<int16_t>(n));
8427 }
8428 else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
8429 {
8430 if (add_prefix)
8431 {
8432 oa->write_character(static_cast<CharType>('l')); // int32
8433 }
8434 write_number(static_cast<int32_t>(n));
8435 }
8436 else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
8437 {
8438 if (add_prefix)
8439 {
8440 oa->write_character(static_cast<CharType>('L')); // int64
8441 }
8442 write_number(static_cast<int64_t>(n));
8443 }
8444 else
8445 {
8446 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8447 }
8448 }
8449
8450 // UBJSON: write number (signed integer)
8451 template<typename NumberType, typename std::enable_if<
8452 std::is_signed<NumberType>::value and
8453 not std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8454 void write_number_with_ubjson_prefix(const NumberType n,
8455 const bool add_prefix)
8456 {
8457 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
8458 {
8459 if (add_prefix)
8460 {
8461 oa->write_character(static_cast<CharType>('i')); // int8
8462 }
8463 write_number(static_cast<int8_t>(n));
8464 }
8465 else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
8466 {
8467 if (add_prefix)
8468 {
8469 oa->write_character(static_cast<CharType>('U')); // uint8
8470 }
8471 write_number(static_cast<uint8_t>(n));
8472 }
8473 else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
8474 {
8475 if (add_prefix)
8476 {
8477 oa->write_character(static_cast<CharType>('I')); // int16
8478 }
8479 write_number(static_cast<int16_t>(n));
8480 }
8481 else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
8482 {
8483 if (add_prefix)
8484 {
8485 oa->write_character(static_cast<CharType>('l')); // int32
8486 }
8487 write_number(static_cast<int32_t>(n));
8488 }
8489 else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
8490 {
8491 if (add_prefix)
8492 {
8493 oa->write_character(static_cast<CharType>('L')); // int64
8494 }
8495 write_number(static_cast<int64_t>(n));
8496 }
8497 // LCOV_EXCL_START
8498 else
8499 {
8500 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8501 }
8502 // LCOV_EXCL_STOP
8503 }
8504
8505 /*!
8506 @brief determine the type prefix of container values
8507
8508 @note This function does not need to be 100% accurate when it comes to
8509 integer limits. In case a number exceeds the limits of int64_t,
8510 this will be detected by a later call to function
8511 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
8512 value that does not fit the previous limits.
8513 */
ubjson_prefix(const BasicJsonType & j) const8514 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
8515 {
8516 switch (j.type())
8517 {
8518 case value_t::null:
8519 return 'Z';
8520
8521 case value_t::boolean:
8522 return j.m_value.boolean ? 'T' : 'F';
8523
8524 case value_t::number_integer:
8525 {
8526 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8527 {
8528 return 'i';
8529 }
8530 else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
8531 {
8532 return 'U';
8533 }
8534 else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8535 {
8536 return 'I';
8537 }
8538 else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8539 {
8540 return 'l';
8541 }
8542 else // no check and assume int64_t (see note above)
8543 {
8544 return 'L';
8545 }
8546 }
8547
8548 case value_t::number_unsigned:
8549 {
8550 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
8551 {
8552 return 'i';
8553 }
8554 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8555 {
8556 return 'U';
8557 }
8558 else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
8559 {
8560 return 'I';
8561 }
8562 else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
8563 {
8564 return 'l';
8565 }
8566 else // no check and assume int64_t (see note above)
8567 {
8568 return 'L';
8569 }
8570 }
8571
8572 case value_t::number_float:
8573 return get_ubjson_float_prefix(j.m_value.number_float);
8574
8575 case value_t::string:
8576 return 'S';
8577
8578 case value_t::array:
8579 return '[';
8580
8581 case value_t::object:
8582 return '{';
8583
8584 default: // discarded values
8585 return 'N';
8586 }
8587 }
8588
get_cbor_float_prefix(float)8589 static constexpr CharType get_cbor_float_prefix(float)
8590 {
8591 return static_cast<CharType>(0xFA); // Single-Precision Float
8592 }
8593
get_cbor_float_prefix(double)8594 static constexpr CharType get_cbor_float_prefix(double)
8595 {
8596 return static_cast<CharType>(0xFB); // Double-Precision Float
8597 }
8598
get_msgpack_float_prefix(float)8599 static constexpr CharType get_msgpack_float_prefix(float)
8600 {
8601 return static_cast<CharType>(0xCA); // float 32
8602 }
8603
get_msgpack_float_prefix(double)8604 static constexpr CharType get_msgpack_float_prefix(double)
8605 {
8606 return static_cast<CharType>(0xCB); // float 64
8607 }
8608
get_ubjson_float_prefix(float)8609 static constexpr CharType get_ubjson_float_prefix(float)
8610 {
8611 return 'd'; // float 32
8612 }
8613
get_ubjson_float_prefix(double)8614 static constexpr CharType get_ubjson_float_prefix(double)
8615 {
8616 return 'D'; // float 64
8617 }
8618
8619 private:
8620 /// whether we can assume little endianess
8621 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
8622
8623 /// the output
8624 output_adapter_t<CharType> oa = nullptr;
8625 };
8626 }
8627 }
8628
8629 // #include <nlohmann/detail/output/serializer.hpp>
8630
8631
8632 #include <algorithm> // reverse, remove, fill, find, none_of
8633 #include <array> // array
8634 #include <cassert> // assert
8635 #include <ciso646> // and, or
8636 #include <clocale> // localeconv, lconv
8637 #include <cmath> // labs, isfinite, isnan, signbit
8638 #include <cstddef> // size_t, ptrdiff_t
8639 #include <cstdint> // uint8_t
8640 #include <cstdio> // snprintf
8641 #include <limits> // numeric_limits
8642 #include <string> // string
8643 #include <type_traits> // is_same
8644
8645 // #include <nlohmann/detail/exceptions.hpp>
8646
8647 // #include <nlohmann/detail/conversions/to_chars.hpp>
8648
8649
8650 #include <cassert> // assert
8651 #include <ciso646> // or, and, not
8652 #include <cmath> // signbit, isfinite
8653 #include <cstdint> // intN_t, uintN_t
8654 #include <cstring> // memcpy, memmove
8655
8656 namespace nlohmann
8657 {
8658 namespace detail
8659 {
8660
8661 /*!
8662 @brief implements the Grisu2 algorithm for binary to decimal floating-point
8663 conversion.
8664
8665 This implementation is a slightly modified version of the reference
8666 implementation which may be obtained from
8667 http://florian.loitsch.com/publications (bench.tar.gz).
8668
8669 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
8670
8671 For a detailed description of the algorithm see:
8672
8673 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
8674 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
8675 Language Design and Implementation, PLDI 2010
8676 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
8677 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
8678 Design and Implementation, PLDI 1996
8679 */
8680 namespace dtoa_impl
8681 {
8682
8683 template <typename Target, typename Source>
8684 Target reinterpret_bits(const Source source)
8685 {
8686 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
8687
8688 Target target;
8689 std::memcpy(&target, &source, sizeof(Source));
8690 return target;
8691 }
8692
8693 struct diyfp // f * 2^e
8694 {
8695 static constexpr int kPrecision = 64; // = q
8696
8697 uint64_t f;
8698 int e;
8699
diyfpnlohmann::detail::dtoa_impl::diyfp8700 constexpr diyfp() noexcept : f(0), e(0) {}
diyfpnlohmann::detail::dtoa_impl::diyfp8701 constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
8702
8703 /*!
8704 @brief returns x - y
8705 @pre x.e == y.e and x.f >= y.f
8706 */
subnlohmann::detail::dtoa_impl::diyfp8707 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
8708 {
8709 assert(x.e == y.e);
8710 assert(x.f >= y.f);
8711
8712 return diyfp(x.f - y.f, x.e);
8713 }
8714
8715 /*!
8716 @brief returns x * y
8717 @note The result is rounded. (Only the upper q bits are returned.)
8718 */
mulnlohmann::detail::dtoa_impl::diyfp8719 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
8720 {
8721 static_assert(kPrecision == 64, "internal error");
8722
8723 // Computes:
8724 // f = round((x.f * y.f) / 2^q)
8725 // e = x.e + y.e + q
8726
8727 // Emulate the 64-bit * 64-bit multiplication:
8728 //
8729 // p = u * v
8730 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
8731 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
8732 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
8733 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
8734 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
8735 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
8736 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
8737 //
8738 // (Since Q might be larger than 2^32 - 1)
8739 //
8740 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
8741 //
8742 // (Q_hi + H does not overflow a 64-bit int)
8743 //
8744 // = p_lo + 2^64 p_hi
8745
8746 const uint64_t u_lo = x.f & 0xFFFFFFFF;
8747 const uint64_t u_hi = x.f >> 32;
8748 const uint64_t v_lo = y.f & 0xFFFFFFFF;
8749 const uint64_t v_hi = y.f >> 32;
8750
8751 const uint64_t p0 = u_lo * v_lo;
8752 const uint64_t p1 = u_lo * v_hi;
8753 const uint64_t p2 = u_hi * v_lo;
8754 const uint64_t p3 = u_hi * v_hi;
8755
8756 const uint64_t p0_hi = p0 >> 32;
8757 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
8758 const uint64_t p1_hi = p1 >> 32;
8759 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
8760 const uint64_t p2_hi = p2 >> 32;
8761
8762 uint64_t Q = p0_hi + p1_lo + p2_lo;
8763
8764 // The full product might now be computed as
8765 //
8766 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
8767 // p_lo = p0_lo + (Q << 32)
8768 //
8769 // But in this particular case here, the full p_lo is not required.
8770 // Effectively we only need to add the highest bit in p_lo to p_hi (and
8771 // Q_hi + 1 does not overflow).
8772
8773 Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
8774
8775 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
8776
8777 return diyfp(h, x.e + y.e + 64);
8778 }
8779
8780 /*!
8781 @brief normalize x such that the significand is >= 2^(q-1)
8782 @pre x.f != 0
8783 */
normalizenlohmann::detail::dtoa_impl::diyfp8784 static diyfp normalize(diyfp x) noexcept
8785 {
8786 assert(x.f != 0);
8787
8788 while ((x.f >> 63) == 0)
8789 {
8790 x.f <<= 1;
8791 x.e--;
8792 }
8793
8794 return x;
8795 }
8796
8797 /*!
8798 @brief normalize x such that the result has the exponent E
8799 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
8800 */
normalize_tonlohmann::detail::dtoa_impl::diyfp8801 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
8802 {
8803 const int delta = x.e - target_exponent;
8804
8805 assert(delta >= 0);
8806 assert(((x.f << delta) >> delta) == x.f);
8807
8808 return diyfp(x.f << delta, target_exponent);
8809 }
8810 };
8811
8812 struct boundaries
8813 {
8814 diyfp w;
8815 diyfp minus;
8816 diyfp plus;
8817 };
8818
8819 /*!
8820 Compute the (normalized) diyfp representing the input number 'value' and its
8821 boundaries.
8822
8823 @pre value must be finite and positive
8824 */
8825 template <typename FloatType>
compute_boundaries(FloatType value)8826 boundaries compute_boundaries(FloatType value)
8827 {
8828 assert(std::isfinite(value));
8829 assert(value > 0);
8830
8831 // Convert the IEEE representation into a diyfp.
8832 //
8833 // If v is denormal:
8834 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
8835 // If v is normalized:
8836 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
8837
8838 static_assert(std::numeric_limits<FloatType>::is_iec559,
8839 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
8840
8841 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
8842 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
8843 constexpr int kMinExp = 1 - kBias;
8844 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
8845
8846 using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
8847
8848 const uint64_t bits = reinterpret_bits<bits_type>(value);
8849 const uint64_t E = bits >> (kPrecision - 1);
8850 const uint64_t F = bits & (kHiddenBit - 1);
8851
8852 const bool is_denormal = (E == 0);
8853 const diyfp v = is_denormal
8854 ? diyfp(F, kMinExp)
8855 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
8856
8857 // Compute the boundaries m- and m+ of the floating-point value
8858 // v = f * 2^e.
8859 //
8860 // Determine v- and v+, the floating-point predecessor and successor if v,
8861 // respectively.
8862 //
8863 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
8864 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
8865 //
8866 // v+ = v + 2^e
8867 //
8868 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
8869 // between m- and m+ round to v, regardless of how the input rounding
8870 // algorithm breaks ties.
8871 //
8872 // ---+-------------+-------------+-------------+-------------+--- (A)
8873 // v- m- v m+ v+
8874 //
8875 // -----------------+------+------+-------------+-------------+--- (B)
8876 // v- m- v m+ v+
8877
8878 const bool lower_boundary_is_closer = (F == 0 and E > 1);
8879 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
8880 const diyfp m_minus = lower_boundary_is_closer
8881 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
8882 : diyfp(2 * v.f - 1, v.e - 1); // (A)
8883
8884 // Determine the normalized w+ = m+.
8885 const diyfp w_plus = diyfp::normalize(m_plus);
8886
8887 // Determine w- = m- such that e_(w-) = e_(w+).
8888 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
8889
8890 return {diyfp::normalize(v), w_minus, w_plus};
8891 }
8892
8893 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
8894 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
8895 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
8896 //
8897 // alpha <= e = e_c + e_w + q <= gamma
8898 //
8899 // or
8900 //
8901 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
8902 // <= f_c * f_w * 2^gamma
8903 //
8904 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
8905 //
8906 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
8907 //
8908 // or
8909 //
8910 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
8911 //
8912 // The choice of (alpha,gamma) determines the size of the table and the form of
8913 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
8914 // in practice:
8915 //
8916 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
8917 // processed independently: An integral part p1, and a fractional part p2:
8918 //
8919 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
8920 // = (f div 2^-e) + (f mod 2^-e) * 2^e
8921 // = p1 + p2 * 2^e
8922 //
8923 // The conversion of p1 into decimal form requires a series of divisions and
8924 // modulos by (a power of) 10. These operations are faster for 32-bit than for
8925 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
8926 // achieved by choosing
8927 //
8928 // -e >= 32 or e <= -32 := gamma
8929 //
8930 // In order to convert the fractional part
8931 //
8932 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
8933 //
8934 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
8935 // d[-i] are extracted in order:
8936 //
8937 // (10 * p2) div 2^-e = d[-1]
8938 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
8939 //
8940 // The multiplication by 10 must not overflow. It is sufficient to choose
8941 //
8942 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
8943 //
8944 // Since p2 = f mod 2^-e < 2^-e,
8945 //
8946 // -e <= 60 or e >= -60 := alpha
8947
8948 constexpr int kAlpha = -60;
8949 constexpr int kGamma = -32;
8950
8951 struct cached_power // c = f * 2^e ~= 10^k
8952 {
8953 uint64_t f;
8954 int e;
8955 int k;
8956 };
8957
8958 /*!
8959 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
8960 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
8961 satisfies (Definition 3.2 from [1])
8962
8963 alpha <= e_c + e + q <= gamma.
8964 */
get_cached_power_for_binary_exponent(int e)8965 inline cached_power get_cached_power_for_binary_exponent(int e)
8966 {
8967 // Now
8968 //
8969 // alpha <= e_c + e + q <= gamma (1)
8970 // ==> f_c * 2^alpha <= c * 2^e * 2^q
8971 //
8972 // and since the c's are normalized, 2^(q-1) <= f_c,
8973 //
8974 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
8975 // ==> 2^(alpha - e - 1) <= c
8976 //
8977 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
8978 //
8979 // k = ceil( log_10( 2^(alpha - e - 1) ) )
8980 // = ceil( (alpha - e - 1) * log_10(2) )
8981 //
8982 // From the paper:
8983 // "In theory the result of the procedure could be wrong since c is rounded,
8984 // and the computation itself is approximated [...]. In practice, however,
8985 // this simple function is sufficient."
8986 //
8987 // For IEEE double precision floating-point numbers converted into
8988 // normalized diyfp's w = f * 2^e, with q = 64,
8989 //
8990 // e >= -1022 (min IEEE exponent)
8991 // -52 (p - 1)
8992 // -52 (p - 1, possibly normalize denormal IEEE numbers)
8993 // -11 (normalize the diyfp)
8994 // = -1137
8995 //
8996 // and
8997 //
8998 // e <= +1023 (max IEEE exponent)
8999 // -52 (p - 1)
9000 // -11 (normalize the diyfp)
9001 // = 960
9002 //
9003 // This binary exponent range [-1137,960] results in a decimal exponent
9004 // range [-307,324]. One does not need to store a cached power for each
9005 // k in this range. For each such k it suffices to find a cached power
9006 // such that the exponent of the product lies in [alpha,gamma].
9007 // This implies that the difference of the decimal exponents of adjacent
9008 // table entries must be less than or equal to
9009 //
9010 // floor( (gamma - alpha) * log_10(2) ) = 8.
9011 //
9012 // (A smaller distance gamma-alpha would require a larger table.)
9013
9014 // NB:
9015 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
9016
9017 constexpr int kCachedPowersSize = 79;
9018 constexpr int kCachedPowersMinDecExp = -300;
9019 constexpr int kCachedPowersDecStep = 8;
9020
9021 static constexpr cached_power kCachedPowers[] =
9022 {
9023 { 0xAB70FE17C79AC6CA, -1060, -300 },
9024 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
9025 { 0xBE5691EF416BD60C, -1007, -284 },
9026 { 0x8DD01FAD907FFC3C, -980, -276 },
9027 { 0xD3515C2831559A83, -954, -268 },
9028 { 0x9D71AC8FADA6C9B5, -927, -260 },
9029 { 0xEA9C227723EE8BCB, -901, -252 },
9030 { 0xAECC49914078536D, -874, -244 },
9031 { 0x823C12795DB6CE57, -847, -236 },
9032 { 0xC21094364DFB5637, -821, -228 },
9033 { 0x9096EA6F3848984F, -794, -220 },
9034 { 0xD77485CB25823AC7, -768, -212 },
9035 { 0xA086CFCD97BF97F4, -741, -204 },
9036 { 0xEF340A98172AACE5, -715, -196 },
9037 { 0xB23867FB2A35B28E, -688, -188 },
9038 { 0x84C8D4DFD2C63F3B, -661, -180 },
9039 { 0xC5DD44271AD3CDBA, -635, -172 },
9040 { 0x936B9FCEBB25C996, -608, -164 },
9041 { 0xDBAC6C247D62A584, -582, -156 },
9042 { 0xA3AB66580D5FDAF6, -555, -148 },
9043 { 0xF3E2F893DEC3F126, -529, -140 },
9044 { 0xB5B5ADA8AAFF80B8, -502, -132 },
9045 { 0x87625F056C7C4A8B, -475, -124 },
9046 { 0xC9BCFF6034C13053, -449, -116 },
9047 { 0x964E858C91BA2655, -422, -108 },
9048 { 0xDFF9772470297EBD, -396, -100 },
9049 { 0xA6DFBD9FB8E5B88F, -369, -92 },
9050 { 0xF8A95FCF88747D94, -343, -84 },
9051 { 0xB94470938FA89BCF, -316, -76 },
9052 { 0x8A08F0F8BF0F156B, -289, -68 },
9053 { 0xCDB02555653131B6, -263, -60 },
9054 { 0x993FE2C6D07B7FAC, -236, -52 },
9055 { 0xE45C10C42A2B3B06, -210, -44 },
9056 { 0xAA242499697392D3, -183, -36 },
9057 { 0xFD87B5F28300CA0E, -157, -28 },
9058 { 0xBCE5086492111AEB, -130, -20 },
9059 { 0x8CBCCC096F5088CC, -103, -12 },
9060 { 0xD1B71758E219652C, -77, -4 },
9061 { 0x9C40000000000000, -50, 4 },
9062 { 0xE8D4A51000000000, -24, 12 },
9063 { 0xAD78EBC5AC620000, 3, 20 },
9064 { 0x813F3978F8940984, 30, 28 },
9065 { 0xC097CE7BC90715B3, 56, 36 },
9066 { 0x8F7E32CE7BEA5C70, 83, 44 },
9067 { 0xD5D238A4ABE98068, 109, 52 },
9068 { 0x9F4F2726179A2245, 136, 60 },
9069 { 0xED63A231D4C4FB27, 162, 68 },
9070 { 0xB0DE65388CC8ADA8, 189, 76 },
9071 { 0x83C7088E1AAB65DB, 216, 84 },
9072 { 0xC45D1DF942711D9A, 242, 92 },
9073 { 0x924D692CA61BE758, 269, 100 },
9074 { 0xDA01EE641A708DEA, 295, 108 },
9075 { 0xA26DA3999AEF774A, 322, 116 },
9076 { 0xF209787BB47D6B85, 348, 124 },
9077 { 0xB454E4A179DD1877, 375, 132 },
9078 { 0x865B86925B9BC5C2, 402, 140 },
9079 { 0xC83553C5C8965D3D, 428, 148 },
9080 { 0x952AB45CFA97A0B3, 455, 156 },
9081 { 0xDE469FBD99A05FE3, 481, 164 },
9082 { 0xA59BC234DB398C25, 508, 172 },
9083 { 0xF6C69A72A3989F5C, 534, 180 },
9084 { 0xB7DCBF5354E9BECE, 561, 188 },
9085 { 0x88FCF317F22241E2, 588, 196 },
9086 { 0xCC20CE9BD35C78A5, 614, 204 },
9087 { 0x98165AF37B2153DF, 641, 212 },
9088 { 0xE2A0B5DC971F303A, 667, 220 },
9089 { 0xA8D9D1535CE3B396, 694, 228 },
9090 { 0xFB9B7CD9A4A7443C, 720, 236 },
9091 { 0xBB764C4CA7A44410, 747, 244 },
9092 { 0x8BAB8EEFB6409C1A, 774, 252 },
9093 { 0xD01FEF10A657842C, 800, 260 },
9094 { 0x9B10A4E5E9913129, 827, 268 },
9095 { 0xE7109BFBA19C0C9D, 853, 276 },
9096 { 0xAC2820D9623BF429, 880, 284 },
9097 { 0x80444B5E7AA7CF85, 907, 292 },
9098 { 0xBF21E44003ACDD2D, 933, 300 },
9099 { 0x8E679C2F5E44FF8F, 960, 308 },
9100 { 0xD433179D9C8CB841, 986, 316 },
9101 { 0x9E19DB92B4E31BA9, 1013, 324 },
9102 };
9103
9104 // This computation gives exactly the same results for k as
9105 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
9106 // for |e| <= 1500, but doesn't require floating-point operations.
9107 // NB: log_10(2) ~= 78913 / 2^18
9108 assert(e >= -1500);
9109 assert(e <= 1500);
9110 const int f = kAlpha - e - 1;
9111 const int k = (f * 78913) / (1 << 18) + (f > 0);
9112
9113 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
9114 assert(index >= 0);
9115 assert(index < kCachedPowersSize);
9116 static_cast<void>(kCachedPowersSize); // Fix warning.
9117
9118 const cached_power cached = kCachedPowers[index];
9119 assert(kAlpha <= cached.e + e + 64);
9120 assert(kGamma >= cached.e + e + 64);
9121
9122 return cached;
9123 }
9124
9125 /*!
9126 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
9127 For n == 0, returns 1 and sets pow10 := 1.
9128 */
find_largest_pow10(const uint32_t n,uint32_t & pow10)9129 inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
9130 {
9131 // LCOV_EXCL_START
9132 if (n >= 1000000000)
9133 {
9134 pow10 = 1000000000;
9135 return 10;
9136 }
9137 // LCOV_EXCL_STOP
9138 else if (n >= 100000000)
9139 {
9140 pow10 = 100000000;
9141 return 9;
9142 }
9143 else if (n >= 10000000)
9144 {
9145 pow10 = 10000000;
9146 return 8;
9147 }
9148 else if (n >= 1000000)
9149 {
9150 pow10 = 1000000;
9151 return 7;
9152 }
9153 else if (n >= 100000)
9154 {
9155 pow10 = 100000;
9156 return 6;
9157 }
9158 else if (n >= 10000)
9159 {
9160 pow10 = 10000;
9161 return 5;
9162 }
9163 else if (n >= 1000)
9164 {
9165 pow10 = 1000;
9166 return 4;
9167 }
9168 else if (n >= 100)
9169 {
9170 pow10 = 100;
9171 return 3;
9172 }
9173 else if (n >= 10)
9174 {
9175 pow10 = 10;
9176 return 2;
9177 }
9178 else
9179 {
9180 pow10 = 1;
9181 return 1;
9182 }
9183 }
9184
grisu2_round(char * buf,int len,uint64_t dist,uint64_t delta,uint64_t rest,uint64_t ten_k)9185 inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
9186 uint64_t rest, uint64_t ten_k)
9187 {
9188 assert(len >= 1);
9189 assert(dist <= delta);
9190 assert(rest <= delta);
9191 assert(ten_k > 0);
9192
9193 // <--------------------------- delta ---->
9194 // <---- dist --------->
9195 // --------------[------------------+-------------------]--------------
9196 // M- w M+
9197 //
9198 // ten_k
9199 // <------>
9200 // <---- rest ---->
9201 // --------------[------------------+----+--------------]--------------
9202 // w V
9203 // = buf * 10^k
9204 //
9205 // ten_k represents a unit-in-the-last-place in the decimal representation
9206 // stored in buf.
9207 // Decrement buf by ten_k while this takes buf closer to w.
9208
9209 // The tests are written in this order to avoid overflow in unsigned
9210 // integer arithmetic.
9211
9212 while (rest < dist
9213 and delta - rest >= ten_k
9214 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
9215 {
9216 assert(buf[len - 1] != '0');
9217 buf[len - 1]--;
9218 rest += ten_k;
9219 }
9220 }
9221
9222 /*!
9223 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
9224 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
9225 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)9226 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
9227 diyfp M_minus, diyfp w, diyfp M_plus)
9228 {
9229 static_assert(kAlpha >= -60, "internal error");
9230 static_assert(kGamma <= -32, "internal error");
9231
9232 // Generates the digits (and the exponent) of a decimal floating-point
9233 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
9234 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
9235 //
9236 // <--------------------------- delta ---->
9237 // <---- dist --------->
9238 // --------------[------------------+-------------------]--------------
9239 // M- w M+
9240 //
9241 // Grisu2 generates the digits of M+ from left to right and stops as soon as
9242 // V is in [M-,M+].
9243
9244 assert(M_plus.e >= kAlpha);
9245 assert(M_plus.e <= kGamma);
9246
9247 uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
9248 uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
9249
9250 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
9251 //
9252 // M+ = f * 2^e
9253 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
9254 // = ((p1 ) * 2^-e + (p2 )) * 2^e
9255 // = p1 + p2 * 2^e
9256
9257 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
9258
9259 uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
9260 uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
9261
9262 // 1)
9263 //
9264 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
9265
9266 assert(p1 > 0);
9267
9268 uint32_t pow10;
9269 const int k = find_largest_pow10(p1, pow10);
9270
9271 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
9272 //
9273 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
9274 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
9275 //
9276 // M+ = p1 + p2 * 2^e
9277 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
9278 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
9279 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
9280 //
9281 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
9282 //
9283 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
9284 //
9285 // but stop as soon as
9286 //
9287 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
9288
9289 int n = k;
9290 while (n > 0)
9291 {
9292 // Invariants:
9293 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
9294 // pow10 = 10^(n-1) <= p1 < 10^n
9295 //
9296 const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
9297 const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
9298 //
9299 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
9300 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
9301 //
9302 assert(d <= 9);
9303 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9304 //
9305 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
9306 //
9307 p1 = r;
9308 n--;
9309 //
9310 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
9311 // pow10 = 10^n
9312 //
9313
9314 // Now check if enough digits have been generated.
9315 // Compute
9316 //
9317 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
9318 //
9319 // Note:
9320 // Since rest and delta share the same exponent e, it suffices to
9321 // compare the significands.
9322 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
9323 if (rest <= delta)
9324 {
9325 // V = buffer * 10^n, with M- <= V <= M+.
9326
9327 decimal_exponent += n;
9328
9329 // We may now just stop. But instead look if the buffer could be
9330 // decremented to bring V closer to w.
9331 //
9332 // pow10 = 10^n is now 1 ulp in the decimal representation V.
9333 // The rounding procedure works with diyfp's with an implicit
9334 // exponent of e.
9335 //
9336 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
9337 //
9338 const uint64_t ten_n = uint64_t{pow10} << -one.e;
9339 grisu2_round(buffer, length, dist, delta, rest, ten_n);
9340
9341 return;
9342 }
9343
9344 pow10 /= 10;
9345 //
9346 // pow10 = 10^(n-1) <= p1 < 10^n
9347 // Invariants restored.
9348 }
9349
9350 // 2)
9351 //
9352 // The digits of the integral part have been generated:
9353 //
9354 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
9355 // = buffer + p2 * 2^e
9356 //
9357 // Now generate the digits of the fractional part p2 * 2^e.
9358 //
9359 // Note:
9360 // No decimal point is generated: the exponent is adjusted instead.
9361 //
9362 // p2 actually represents the fraction
9363 //
9364 // p2 * 2^e
9365 // = p2 / 2^-e
9366 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
9367 //
9368 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
9369 //
9370 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
9371 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
9372 //
9373 // using
9374 //
9375 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
9376 // = ( d) * 2^-e + ( r)
9377 //
9378 // or
9379 // 10^m * p2 * 2^e = d + r * 2^e
9380 //
9381 // i.e.
9382 //
9383 // M+ = buffer + p2 * 2^e
9384 // = buffer + 10^-m * (d + r * 2^e)
9385 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
9386 //
9387 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
9388
9389 assert(p2 > delta);
9390
9391 int m = 0;
9392 for (;;)
9393 {
9394 // Invariant:
9395 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
9396 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
9397 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
9398 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
9399 //
9400 assert(p2 <= UINT64_MAX / 10);
9401 p2 *= 10;
9402 const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
9403 const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
9404 //
9405 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
9406 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
9407 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
9408 //
9409 assert(d <= 9);
9410 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9411 //
9412 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
9413 //
9414 p2 = r;
9415 m++;
9416 //
9417 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
9418 // Invariant restored.
9419
9420 // Check if enough digits have been generated.
9421 //
9422 // 10^-m * p2 * 2^e <= delta * 2^e
9423 // p2 * 2^e <= 10^m * delta * 2^e
9424 // p2 <= 10^m * delta
9425 delta *= 10;
9426 dist *= 10;
9427 if (p2 <= delta)
9428 {
9429 break;
9430 }
9431 }
9432
9433 // V = buffer * 10^-m, with M- <= V <= M+.
9434
9435 decimal_exponent -= m;
9436
9437 // 1 ulp in the decimal representation is now 10^-m.
9438 // Since delta and dist are now scaled by 10^m, we need to do the
9439 // same with ulp in order to keep the units in sync.
9440 //
9441 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
9442 //
9443 const uint64_t ten_m = one.f;
9444 grisu2_round(buffer, length, dist, delta, p2, ten_m);
9445
9446 // By construction this algorithm generates the shortest possible decimal
9447 // number (Loitsch, Theorem 6.2) which rounds back to w.
9448 // For an input number of precision p, at least
9449 //
9450 // N = 1 + ceil(p * log_10(2))
9451 //
9452 // decimal digits are sufficient to identify all binary floating-point
9453 // numbers (Matula, "In-and-Out conversions").
9454 // This implies that the algorithm does not produce more than N decimal
9455 // digits.
9456 //
9457 // N = 17 for p = 53 (IEEE double precision)
9458 // N = 9 for p = 24 (IEEE single precision)
9459 }
9460
9461 /*!
9462 v = buf * 10^decimal_exponent
9463 len is the length of the buffer (number of decimal digits)
9464 The buffer must be large enough, i.e. >= max_digits10.
9465 */
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)9466 inline void grisu2(char* buf, int& len, int& decimal_exponent,
9467 diyfp m_minus, diyfp v, diyfp m_plus)
9468 {
9469 assert(m_plus.e == m_minus.e);
9470 assert(m_plus.e == v.e);
9471
9472 // --------(-----------------------+-----------------------)-------- (A)
9473 // m- v m+
9474 //
9475 // --------------------(-----------+-----------------------)-------- (B)
9476 // m- v m+
9477 //
9478 // First scale v (and m- and m+) such that the exponent is in the range
9479 // [alpha, gamma].
9480
9481 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
9482
9483 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
9484
9485 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
9486 const diyfp w = diyfp::mul(v, c_minus_k);
9487 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
9488 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
9489
9490 // ----(---+---)---------------(---+---)---------------(---+---)----
9491 // w- w w+
9492 // = c*m- = c*v = c*m+
9493 //
9494 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
9495 // w+ are now off by a small amount.
9496 // In fact:
9497 //
9498 // w - v * 10^k < 1 ulp
9499 //
9500 // To account for this inaccuracy, add resp. subtract 1 ulp.
9501 //
9502 // --------+---[---------------(---+---)---------------]---+--------
9503 // w- M- w M+ w+
9504 //
9505 // Now any number in [M-, M+] (bounds included) will round to w when input,
9506 // regardless of how the input rounding algorithm breaks ties.
9507 //
9508 // And digit_gen generates the shortest possible such number in [M-, M+].
9509 // Note that this does not mean that Grisu2 always generates the shortest
9510 // possible number in the interval (m-, m+).
9511 const diyfp M_minus(w_minus.f + 1, w_minus.e);
9512 const diyfp M_plus (w_plus.f - 1, w_plus.e );
9513
9514 decimal_exponent = -cached.k; // = -(-k) = k
9515
9516 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
9517 }
9518
9519 /*!
9520 v = buf * 10^decimal_exponent
9521 len is the length of the buffer (number of decimal digits)
9522 The buffer must be large enough, i.e. >= max_digits10.
9523 */
9524 template <typename FloatType>
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)9525 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
9526 {
9527 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
9528 "internal error: not enough precision");
9529
9530 assert(std::isfinite(value));
9531 assert(value > 0);
9532
9533 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
9534 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
9535 // decimal representations are not exactly "short".
9536 //
9537 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
9538 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
9539 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
9540 // does.
9541 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
9542 // representation using the corresponding std::from_chars function recovers value exactly". That
9543 // indicates that single precision floating-point numbers should be recovered using
9544 // 'std::strtof'.
9545 //
9546 // NB: If the neighbors are computed for single-precision numbers, there is a single float
9547 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
9548 // value is off by 1 ulp.
9549 #if 0
9550 const boundaries w = compute_boundaries(static_cast<double>(value));
9551 #else
9552 const boundaries w = compute_boundaries(value);
9553 #endif
9554
9555 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
9556 }
9557
9558 /*!
9559 @brief appends a decimal representation of e to buf
9560 @return a pointer to the element following the exponent.
9561 @pre -1000 < e < 1000
9562 */
append_exponent(char * buf,int e)9563 inline char* append_exponent(char* buf, int e)
9564 {
9565 assert(e > -1000);
9566 assert(e < 1000);
9567
9568 if (e < 0)
9569 {
9570 e = -e;
9571 *buf++ = '-';
9572 }
9573 else
9574 {
9575 *buf++ = '+';
9576 }
9577
9578 uint32_t k = static_cast<uint32_t>(e);
9579 if (k < 10)
9580 {
9581 // Always print at least two digits in the exponent.
9582 // This is for compatibility with printf("%g").
9583 *buf++ = '0';
9584 *buf++ = static_cast<char>('0' + k);
9585 }
9586 else if (k < 100)
9587 {
9588 *buf++ = static_cast<char>('0' + k / 10);
9589 k %= 10;
9590 *buf++ = static_cast<char>('0' + k);
9591 }
9592 else
9593 {
9594 *buf++ = static_cast<char>('0' + k / 100);
9595 k %= 100;
9596 *buf++ = static_cast<char>('0' + k / 10);
9597 k %= 10;
9598 *buf++ = static_cast<char>('0' + k);
9599 }
9600
9601 return buf;
9602 }
9603
9604 /*!
9605 @brief prettify v = buf * 10^decimal_exponent
9606
9607 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
9608 notation. Otherwise it will be printed in exponential notation.
9609
9610 @pre min_exp < 0
9611 @pre max_exp > 0
9612 */
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)9613 inline char* format_buffer(char* buf, int len, int decimal_exponent,
9614 int min_exp, int max_exp)
9615 {
9616 assert(min_exp < 0);
9617 assert(max_exp > 0);
9618
9619 const int k = len;
9620 const int n = len + decimal_exponent;
9621
9622 // v = buf * 10^(n-k)
9623 // k is the length of the buffer (number of decimal digits)
9624 // n is the position of the decimal point relative to the start of the buffer.
9625
9626 if (k <= n and n <= max_exp)
9627 {
9628 // digits[000]
9629 // len <= max_exp + 2
9630
9631 std::memset(buf + k, '0', static_cast<size_t>(n - k));
9632 // Make it look like a floating-point number (#362, #378)
9633 buf[n + 0] = '.';
9634 buf[n + 1] = '0';
9635 return buf + (n + 2);
9636 }
9637
9638 if (0 < n and n <= max_exp)
9639 {
9640 // dig.its
9641 // len <= max_digits10 + 1
9642
9643 assert(k > n);
9644
9645 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
9646 buf[n] = '.';
9647 return buf + (k + 1);
9648 }
9649
9650 if (min_exp < n and n <= 0)
9651 {
9652 // 0.[000]digits
9653 // len <= 2 + (-min_exp - 1) + max_digits10
9654
9655 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
9656 buf[0] = '0';
9657 buf[1] = '.';
9658 std::memset(buf + 2, '0', static_cast<size_t>(-n));
9659 return buf + (2 + (-n) + k);
9660 }
9661
9662 if (k == 1)
9663 {
9664 // dE+123
9665 // len <= 1 + 5
9666
9667 buf += 1;
9668 }
9669 else
9670 {
9671 // d.igitsE+123
9672 // len <= max_digits10 + 1 + 5
9673
9674 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
9675 buf[1] = '.';
9676 buf += 1 + k;
9677 }
9678
9679 *buf++ = 'e';
9680 return append_exponent(buf, n - 1);
9681 }
9682
9683 } // namespace dtoa_impl
9684
9685 /*!
9686 @brief generates a decimal representation of the floating-point number value in [first, last).
9687
9688 The format of the resulting decimal representation is similar to printf's %g
9689 format. Returns an iterator pointing past-the-end of the decimal representation.
9690
9691 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
9692 @note The buffer must be large enough.
9693 @note The result is NOT null-terminated.
9694 */
9695 template <typename FloatType>
to_chars(char * first,char * last,FloatType value)9696 char* to_chars(char* first, char* last, FloatType value)
9697 {
9698 static_cast<void>(last); // maybe unused - fix warning
9699 assert(std::isfinite(value));
9700
9701 // Use signbit(value) instead of (value < 0) since signbit works for -0.
9702 if (std::signbit(value))
9703 {
9704 value = -value;
9705 *first++ = '-';
9706 }
9707
9708 if (value == 0) // +-0
9709 {
9710 *first++ = '0';
9711 // Make it look like a floating-point number (#362, #378)
9712 *first++ = '.';
9713 *first++ = '0';
9714 return first;
9715 }
9716
9717 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
9718
9719 // Compute v = buffer * 10^decimal_exponent.
9720 // The decimal digits are stored in the buffer, which needs to be interpreted
9721 // as an unsigned decimal integer.
9722 // len is the length of the buffer, i.e. the number of decimal digits.
9723 int len = 0;
9724 int decimal_exponent = 0;
9725 dtoa_impl::grisu2(first, len, decimal_exponent, value);
9726
9727 assert(len <= std::numeric_limits<FloatType>::max_digits10);
9728
9729 // Format the buffer like printf("%.*g", prec, value)
9730 constexpr int kMinExp = -4;
9731 // Use digits10 here to increase compatibility with version 2.
9732 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
9733
9734 assert(last - first >= kMaxExp + 2);
9735 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
9736 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
9737
9738 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
9739 }
9740
9741 } // namespace detail
9742 } // namespace nlohmann
9743
9744 // #include <nlohmann/detail/macro_scope.hpp>
9745
9746 // #include <nlohmann/detail/meta/cpp_future.hpp>
9747
9748 // #include <nlohmann/detail/output/output_adapters.hpp>
9749
9750 // #include <nlohmann/detail/value_t.hpp>
9751
9752
9753 namespace nlohmann
9754 {
9755 namespace detail
9756 {
9757 ///////////////////
9758 // serialization //
9759 ///////////////////
9760
9761 template<typename BasicJsonType>
9762 class serializer
9763 {
9764 using string_t = typename BasicJsonType::string_t;
9765 using number_float_t = typename BasicJsonType::number_float_t;
9766 using number_integer_t = typename BasicJsonType::number_integer_t;
9767 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9768 static constexpr uint8_t UTF8_ACCEPT = 0;
9769 static constexpr uint8_t UTF8_REJECT = 1;
9770
9771 public:
9772 /*!
9773 @param[in] s output stream to serialize to
9774 @param[in] ichar indentation character to use
9775 */
serializer(output_adapter_t<char> s,const char ichar)9776 serializer(output_adapter_t<char> s, const char ichar)
9777 : o(std::move(s)), loc(std::localeconv()),
9778 thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep)),
9779 decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point)),
9780 indent_char(ichar), indent_string(512, indent_char)
9781 {}
9782
9783 // delete because of pointer members
9784 serializer(const serializer&) = delete;
9785 serializer& operator=(const serializer&) = delete;
9786
9787 /*!
9788 @brief internal implementation of the serialization function
9789
9790 This function is called by the public member function dump and organizes
9791 the serialization internally. The indentation level is propagated as
9792 additional parameter. In case of arrays and objects, the function is
9793 called recursively.
9794
9795 - strings and object keys are escaped using `escape_string()`
9796 - integer numbers are converted implicitly via `operator<<`
9797 - floating-point numbers are converted to a string using `"%g"` format
9798
9799 @param[in] val value to serialize
9800 @param[in] pretty_print whether the output shall be pretty-printed
9801 @param[in] indent_step the indent level
9802 @param[in] current_indent the current indent level (only used internally)
9803 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)9804 void dump(const BasicJsonType& val, const bool pretty_print,
9805 const bool ensure_ascii,
9806 const unsigned int indent_step,
9807 const unsigned int current_indent = 0)
9808 {
9809 switch (val.m_type)
9810 {
9811 case value_t::object:
9812 {
9813 if (val.m_value.object->empty())
9814 {
9815 o->write_characters("{}", 2);
9816 return;
9817 }
9818
9819 if (pretty_print)
9820 {
9821 o->write_characters("{\n", 2);
9822
9823 // variable to hold indentation for recursive calls
9824 const auto new_indent = current_indent + indent_step;
9825 if (JSON_UNLIKELY(indent_string.size() < new_indent))
9826 {
9827 indent_string.resize(indent_string.size() * 2, ' ');
9828 }
9829
9830 // first n-1 elements
9831 auto i = val.m_value.object->cbegin();
9832 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9833 {
9834 o->write_characters(indent_string.c_str(), new_indent);
9835 o->write_character('\"');
9836 dump_escaped(i->first, ensure_ascii);
9837 o->write_characters("\": ", 3);
9838 dump(i->second, true, ensure_ascii, indent_step, new_indent);
9839 o->write_characters(",\n", 2);
9840 }
9841
9842 // last element
9843 assert(i != val.m_value.object->cend());
9844 assert(std::next(i) == val.m_value.object->cend());
9845 o->write_characters(indent_string.c_str(), new_indent);
9846 o->write_character('\"');
9847 dump_escaped(i->first, ensure_ascii);
9848 o->write_characters("\": ", 3);
9849 dump(i->second, true, ensure_ascii, indent_step, new_indent);
9850
9851 o->write_character('\n');
9852 o->write_characters(indent_string.c_str(), current_indent);
9853 o->write_character('}');
9854 }
9855 else
9856 {
9857 o->write_character('{');
9858
9859 // first n-1 elements
9860 auto i = val.m_value.object->cbegin();
9861 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9862 {
9863 o->write_character('\"');
9864 dump_escaped(i->first, ensure_ascii);
9865 o->write_characters("\":", 2);
9866 dump(i->second, false, ensure_ascii, indent_step, current_indent);
9867 o->write_character(',');
9868 }
9869
9870 // last element
9871 assert(i != val.m_value.object->cend());
9872 assert(std::next(i) == val.m_value.object->cend());
9873 o->write_character('\"');
9874 dump_escaped(i->first, ensure_ascii);
9875 o->write_characters("\":", 2);
9876 dump(i->second, false, ensure_ascii, indent_step, current_indent);
9877
9878 o->write_character('}');
9879 }
9880
9881 return;
9882 }
9883
9884 case value_t::array:
9885 {
9886 if (val.m_value.array->empty())
9887 {
9888 o->write_characters("[]", 2);
9889 return;
9890 }
9891
9892 if (pretty_print)
9893 {
9894 o->write_characters("[\n", 2);
9895
9896 // variable to hold indentation for recursive calls
9897 const auto new_indent = current_indent + indent_step;
9898 if (JSON_UNLIKELY(indent_string.size() < new_indent))
9899 {
9900 indent_string.resize(indent_string.size() * 2, ' ');
9901 }
9902
9903 // first n-1 elements
9904 for (auto i = val.m_value.array->cbegin();
9905 i != val.m_value.array->cend() - 1; ++i)
9906 {
9907 o->write_characters(indent_string.c_str(), new_indent);
9908 dump(*i, true, ensure_ascii, indent_step, new_indent);
9909 o->write_characters(",\n", 2);
9910 }
9911
9912 // last element
9913 assert(not val.m_value.array->empty());
9914 o->write_characters(indent_string.c_str(), new_indent);
9915 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
9916
9917 o->write_character('\n');
9918 o->write_characters(indent_string.c_str(), current_indent);
9919 o->write_character(']');
9920 }
9921 else
9922 {
9923 o->write_character('[');
9924
9925 // first n-1 elements
9926 for (auto i = val.m_value.array->cbegin();
9927 i != val.m_value.array->cend() - 1; ++i)
9928 {
9929 dump(*i, false, ensure_ascii, indent_step, current_indent);
9930 o->write_character(',');
9931 }
9932
9933 // last element
9934 assert(not val.m_value.array->empty());
9935 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
9936
9937 o->write_character(']');
9938 }
9939
9940 return;
9941 }
9942
9943 case value_t::string:
9944 {
9945 o->write_character('\"');
9946 dump_escaped(*val.m_value.string, ensure_ascii);
9947 o->write_character('\"');
9948 return;
9949 }
9950
9951 case value_t::boolean:
9952 {
9953 if (val.m_value.boolean)
9954 {
9955 o->write_characters("true", 4);
9956 }
9957 else
9958 {
9959 o->write_characters("false", 5);
9960 }
9961 return;
9962 }
9963
9964 case value_t::number_integer:
9965 {
9966 dump_integer(val.m_value.number_integer);
9967 return;
9968 }
9969
9970 case value_t::number_unsigned:
9971 {
9972 dump_integer(val.m_value.number_unsigned);
9973 return;
9974 }
9975
9976 case value_t::number_float:
9977 {
9978 dump_float(val.m_value.number_float);
9979 return;
9980 }
9981
9982 case value_t::discarded:
9983 {
9984 o->write_characters("<discarded>", 11);
9985 return;
9986 }
9987
9988 case value_t::null:
9989 {
9990 o->write_characters("null", 4);
9991 return;
9992 }
9993 }
9994 }
9995
9996 private:
9997 /*!
9998 @brief dump escaped string
9999
10000 Escape a string by replacing certain special characters by a sequence of an
10001 escape character (backslash) and another character and other control
10002 characters by a sequence of "\u" followed by a four-digit hex
10003 representation. The escaped string is written to output stream @a o.
10004
10005 @param[in] s the string to escape
10006 @param[in] ensure_ascii whether to escape non-ASCII characters with
10007 \uXXXX sequences
10008
10009 @complexity Linear in the length of string @a s.
10010 */
dump_escaped(const string_t & s,const bool ensure_ascii)10011 void dump_escaped(const string_t& s, const bool ensure_ascii)
10012 {
10013 uint32_t codepoint;
10014 uint8_t state = UTF8_ACCEPT;
10015 std::size_t bytes = 0; // number of bytes written to string_buffer
10016
10017 for (std::size_t i = 0; i < s.size(); ++i)
10018 {
10019 const auto byte = static_cast<uint8_t>(s[i]);
10020
10021 switch (decode(state, codepoint, byte))
10022 {
10023 case UTF8_ACCEPT: // decode found a new code point
10024 {
10025 switch (codepoint)
10026 {
10027 case 0x08: // backspace
10028 {
10029 string_buffer[bytes++] = '\\';
10030 string_buffer[bytes++] = 'b';
10031 break;
10032 }
10033
10034 case 0x09: // horizontal tab
10035 {
10036 string_buffer[bytes++] = '\\';
10037 string_buffer[bytes++] = 't';
10038 break;
10039 }
10040
10041 case 0x0A: // newline
10042 {
10043 string_buffer[bytes++] = '\\';
10044 string_buffer[bytes++] = 'n';
10045 break;
10046 }
10047
10048 case 0x0C: // formfeed
10049 {
10050 string_buffer[bytes++] = '\\';
10051 string_buffer[bytes++] = 'f';
10052 break;
10053 }
10054
10055 case 0x0D: // carriage return
10056 {
10057 string_buffer[bytes++] = '\\';
10058 string_buffer[bytes++] = 'r';
10059 break;
10060 }
10061
10062 case 0x22: // quotation mark
10063 {
10064 string_buffer[bytes++] = '\\';
10065 string_buffer[bytes++] = '\"';
10066 break;
10067 }
10068
10069 case 0x5C: // reverse solidus
10070 {
10071 string_buffer[bytes++] = '\\';
10072 string_buffer[bytes++] = '\\';
10073 break;
10074 }
10075
10076 default:
10077 {
10078 // escape control characters (0x00..0x1F) or, if
10079 // ensure_ascii parameter is used, non-ASCII characters
10080 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
10081 {
10082 if (codepoint <= 0xFFFF)
10083 {
10084 std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
10085 static_cast<uint16_t>(codepoint));
10086 bytes += 6;
10087 }
10088 else
10089 {
10090 std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
10091 static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
10092 static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
10093 bytes += 12;
10094 }
10095 }
10096 else
10097 {
10098 // copy byte to buffer (all previous bytes
10099 // been copied have in default case above)
10100 string_buffer[bytes++] = s[i];
10101 }
10102 break;
10103 }
10104 }
10105
10106 // write buffer and reset index; there must be 13 bytes
10107 // left, as this is the maximal number of bytes to be
10108 // written ("\uxxxx\uxxxx\0") for one code point
10109 if (string_buffer.size() - bytes < 13)
10110 {
10111 o->write_characters(string_buffer.data(), bytes);
10112 bytes = 0;
10113 }
10114 break;
10115 }
10116
10117 case UTF8_REJECT: // decode found invalid UTF-8 byte
10118 {
10119 std::string sn(3, '\0');
10120 snprintf(&sn[0], sn.size(), "%.2X", byte);
10121 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
10122 }
10123
10124 default: // decode found yet incomplete multi-byte code point
10125 {
10126 if (not ensure_ascii)
10127 {
10128 // code point will not be escaped - copy byte to buffer
10129 string_buffer[bytes++] = s[i];
10130 }
10131 break;
10132 }
10133 }
10134 }
10135
10136 if (JSON_LIKELY(state == UTF8_ACCEPT))
10137 {
10138 // write buffer
10139 if (bytes > 0)
10140 {
10141 o->write_characters(string_buffer.data(), bytes);
10142 }
10143 }
10144 else
10145 {
10146 // we finish reading, but do not accept: string was incomplete
10147 std::string sn(3, '\0');
10148 snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
10149 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
10150 }
10151 }
10152
10153 /*!
10154 @brief dump an integer
10155
10156 Dump a given integer to output stream @a o. Works internally with
10157 @a number_buffer.
10158
10159 @param[in] x integer number (signed or unsigned) to dump
10160 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
10161 */
10162 template<typename NumberType, detail::enable_if_t<
10163 std::is_same<NumberType, number_unsigned_t>::value or
10164 std::is_same<NumberType, number_integer_t>::value,
10165 int> = 0>
dump_integer(NumberType x)10166 void dump_integer(NumberType x)
10167 {
10168 // special case for "0"
10169 if (x == 0)
10170 {
10171 o->write_character('0');
10172 return;
10173 }
10174
10175 const bool is_negative = !(x>=0); // see issue #755
10176 std::size_t i = 0;
10177
10178 while (x != 0)
10179 {
10180 // spare 1 byte for '\0'
10181 assert(i < number_buffer.size() - 1);
10182
10183 const auto digit = std::labs(static_cast<long>(x % 10));
10184 number_buffer[i++] = static_cast<char>('0' + digit);
10185 x /= 10;
10186 }
10187
10188 if (is_negative)
10189 {
10190 // make sure there is capacity for the '-'
10191 assert(i < number_buffer.size() - 2);
10192 number_buffer[i++] = '-';
10193 }
10194
10195 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
10196 o->write_characters(number_buffer.data(), i);
10197 }
10198
10199 /*!
10200 @brief dump a floating-point number
10201
10202 Dump a given floating-point number to output stream @a o. Works internally
10203 with @a number_buffer.
10204
10205 @param[in] x floating-point number to dump
10206 */
dump_float(number_float_t x)10207 void dump_float(number_float_t x)
10208 {
10209 // NaN / inf
10210 if (not std::isfinite(x))
10211 {
10212 o->write_characters("null", 4);
10213 return;
10214 }
10215
10216 // If number_float_t is an IEEE-754 single or double precision number,
10217 // use the Grisu2 algorithm to produce short numbers which are
10218 // guaranteed to round-trip, using strtof and strtod, resp.
10219 //
10220 // NB: The test below works if <long double> == <double>.
10221 static constexpr bool is_ieee_single_or_double
10222 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
10223 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
10224
10225 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
10226 }
10227
dump_float(number_float_t x,std::true_type)10228 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
10229 {
10230 char* begin = number_buffer.data();
10231 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
10232
10233 o->write_characters(begin, static_cast<size_t>(end - begin));
10234 }
10235
dump_float(number_float_t x,std::false_type)10236 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
10237 {
10238 // get number of digits for a float -> text -> float round-trip
10239 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
10240
10241 // the actual conversion
10242 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
10243
10244 // negative value indicates an error
10245 assert(len > 0);
10246 // check if buffer was large enough
10247 assert(static_cast<std::size_t>(len) < number_buffer.size());
10248
10249 // erase thousands separator
10250 if (thousands_sep != '\0')
10251 {
10252 const auto end = std::remove(number_buffer.begin(),
10253 number_buffer.begin() + len, thousands_sep);
10254 std::fill(end, number_buffer.end(), '\0');
10255 assert((end - number_buffer.begin()) <= len);
10256 len = (end - number_buffer.begin());
10257 }
10258
10259 // convert decimal point to '.'
10260 if (decimal_point != '\0' and decimal_point != '.')
10261 {
10262 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
10263 if (dec_pos != number_buffer.end())
10264 {
10265 *dec_pos = '.';
10266 }
10267 }
10268
10269 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
10270
10271 // determine if need to append ".0"
10272 const bool value_is_int_like =
10273 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
10274 [](char c)
10275 {
10276 return (c == '.' or c == 'e');
10277 });
10278
10279 if (value_is_int_like)
10280 {
10281 o->write_characters(".0", 2);
10282 }
10283 }
10284
10285 /*!
10286 @brief check whether a string is UTF-8 encoded
10287
10288 The function checks each byte of a string whether it is UTF-8 encoded. The
10289 result of the check is stored in the @a state parameter. The function must
10290 be called initially with state 0 (accept). State 1 means the string must
10291 be rejected, because the current byte is not allowed. If the string is
10292 completely processed, but the state is non-zero, the string ended
10293 prematurely; that is, the last byte indicated more bytes should have
10294 followed.
10295
10296 @param[in,out] state the state of the decoding
10297 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
10298 @param[in] byte next byte to decode
10299 @return new state
10300
10301 @note The function has been edited: a std::array is used.
10302
10303 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
10304 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
10305 */
decode(uint8_t & state,uint32_t & codep,const uint8_t byte)10306 static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
10307 {
10308 static const std::array<uint8_t, 400> utf8d =
10309 {
10310 {
10311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
10312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
10313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
10314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
10315 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
10316 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
10317 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
10318 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
10319 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
10320 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
10321 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
10322 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
10323 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
10324 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
10325 }
10326 };
10327
10328 const uint8_t type = utf8d[byte];
10329
10330 codep = (state != UTF8_ACCEPT)
10331 ? (byte & 0x3fu) | (codep << 6)
10332 : static_cast<uint32_t>(0xff >> type) & (byte);
10333
10334 state = utf8d[256u + state * 16u + type];
10335 return state;
10336 }
10337
10338 private:
10339 /// the output of the serializer
10340 output_adapter_t<char> o = nullptr;
10341
10342 /// a (hopefully) large enough character buffer
10343 std::array<char, 64> number_buffer{{}};
10344
10345 /// the locale
10346 const std::lconv* loc = nullptr;
10347 /// the locale's thousand separator character
10348 const char thousands_sep = '\0';
10349 /// the locale's decimal point character
10350 const char decimal_point = '\0';
10351
10352 /// string buffer
10353 std::array<char, 512> string_buffer{{}};
10354
10355 /// the indentation character
10356 const char indent_char;
10357 /// the indentation string
10358 string_t indent_string;
10359 };
10360 }
10361 }
10362
10363 // #include <nlohmann/detail/json_ref.hpp>
10364
10365
10366 #include <initializer_list>
10367 #include <utility>
10368
10369 namespace nlohmann
10370 {
10371 namespace detail
10372 {
10373 template<typename BasicJsonType>
10374 class json_ref
10375 {
10376 public:
10377 using value_type = BasicJsonType;
10378
json_ref(value_type && value)10379 json_ref(value_type&& value)
10380 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
10381 {}
10382
json_ref(const value_type & value)10383 json_ref(const value_type& value)
10384 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
10385 {}
10386
json_ref(std::initializer_list<json_ref> init)10387 json_ref(std::initializer_list<json_ref> init)
10388 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
10389 {}
10390
10391 template<class... Args>
json_ref(Args &&...args)10392 json_ref(Args&& ... args)
10393 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
10394 {}
10395
10396 // class should be movable only
10397 json_ref(json_ref&&) = default;
10398 json_ref(const json_ref&) = delete;
10399 json_ref& operator=(const json_ref&) = delete;
10400
moved_or_copied() const10401 value_type moved_or_copied() const
10402 {
10403 if (is_rvalue)
10404 {
10405 return std::move(*value_ref);
10406 }
10407 return *value_ref;
10408 }
10409
operator *() const10410 value_type const& operator*() const
10411 {
10412 return *static_cast<value_type const*>(value_ref);
10413 }
10414
operator ->() const10415 value_type const* operator->() const
10416 {
10417 return static_cast<value_type const*>(value_ref);
10418 }
10419
10420 private:
10421 mutable value_type owned_value = nullptr;
10422 value_type* value_ref = nullptr;
10423 const bool is_rvalue;
10424 };
10425 }
10426 }
10427
10428 // #include <nlohmann/detail/json_pointer.hpp>
10429
10430
10431 #include <cassert> // assert
10432 #include <numeric> // accumulate
10433 #include <string> // string
10434 #include <vector> // vector
10435
10436 // #include <nlohmann/detail/macro_scope.hpp>
10437
10438 // #include <nlohmann/detail/exceptions.hpp>
10439
10440 // #include <nlohmann/detail/value_t.hpp>
10441
10442
10443 namespace nlohmann
10444 {
10445 template<typename BasicJsonType>
10446 class json_pointer
10447 {
10448 // allow basic_json to access private members
10449 NLOHMANN_BASIC_JSON_TPL_DECLARATION
10450 friend class basic_json;
10451
10452 public:
10453 /*!
10454 @brief create JSON pointer
10455
10456 Create a JSON pointer according to the syntax described in
10457 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
10458
10459 @param[in] s string representing the JSON pointer; if omitted, the empty
10460 string is assumed which references the whole JSON value
10461
10462 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
10463 not begin with a slash (`/`); see example below
10464
10465 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
10466 not followed by `0` (representing `~`) or `1` (representing `/`); see
10467 example below
10468
10469 @liveexample{The example shows the construction several valid JSON pointers
10470 as well as the exceptional behavior.,json_pointer}
10471
10472 @since version 2.0.0
10473 */
json_pointer(const std::string & s="")10474 explicit json_pointer(const std::string& s = "")
10475 : reference_tokens(split(s))
10476 {}
10477
10478 /*!
10479 @brief return a string representation of the JSON pointer
10480
10481 @invariant For each JSON pointer `ptr`, it holds:
10482 @code {.cpp}
10483 ptr == json_pointer(ptr.to_string());
10484 @endcode
10485
10486 @return a string representation of the JSON pointer
10487
10488 @liveexample{The example shows the result of `to_string`.,
10489 json_pointer__to_string}
10490
10491 @since version 2.0.0
10492 */
to_string() const10493 std::string to_string() const noexcept
10494 {
10495 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10496 std::string{},
10497 [](const std::string & a, const std::string & b)
10498 {
10499 return a + "/" + escape(b);
10500 });
10501 }
10502
10503 /// @copydoc to_string()
operator std::string() const10504 operator std::string() const
10505 {
10506 return to_string();
10507 }
10508
10509 /*!
10510 @param[in] s reference token to be converted into an array index
10511
10512 @return integer representation of @a s
10513
10514 @throw out_of_range.404 if string @a s could not be converted to an integer
10515 */
array_index(const std::string & s)10516 static int array_index(const std::string& s)
10517 {
10518 std::size_t processed_chars = 0;
10519 const int res = std::stoi(s, &processed_chars);
10520
10521 // check if the string was completely read
10522 if (JSON_UNLIKELY(processed_chars != s.size()))
10523 {
10524 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
10525 }
10526
10527 return res;
10528 }
10529
10530 private:
10531 /*!
10532 @brief remove and return last reference pointer
10533 @throw out_of_range.405 if JSON pointer has no parent
10534 */
pop_back()10535 std::string pop_back()
10536 {
10537 if (JSON_UNLIKELY(is_root()))
10538 {
10539 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10540 }
10541
10542 auto last = reference_tokens.back();
10543 reference_tokens.pop_back();
10544 return last;
10545 }
10546
10547 /// return whether pointer points to the root document
is_root() const10548 bool is_root() const
10549 {
10550 return reference_tokens.empty();
10551 }
10552
top() const10553 json_pointer top() const
10554 {
10555 if (JSON_UNLIKELY(is_root()))
10556 {
10557 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10558 }
10559
10560 json_pointer result = *this;
10561 result.reference_tokens = {reference_tokens[0]};
10562 return result;
10563 }
10564
10565 /*!
10566 @brief create and return a reference to the pointed to value
10567
10568 @complexity Linear in the number of reference tokens.
10569
10570 @throw parse_error.109 if array index is not a number
10571 @throw type_error.313 if value cannot be unflattened
10572 */
get_and_create(BasicJsonType & j) const10573 BasicJsonType& get_and_create(BasicJsonType& j) const
10574 {
10575 using size_type = typename BasicJsonType::size_type;
10576 auto result = &j;
10577
10578 // in case no reference tokens exist, return a reference to the JSON value
10579 // j which will be overwritten by a primitive value
10580 for (const auto& reference_token : reference_tokens)
10581 {
10582 switch (result->m_type)
10583 {
10584 case detail::value_t::null:
10585 {
10586 if (reference_token == "0")
10587 {
10588 // start a new array if reference token is 0
10589 result = &result->operator[](0);
10590 }
10591 else
10592 {
10593 // start a new object otherwise
10594 result = &result->operator[](reference_token);
10595 }
10596 break;
10597 }
10598
10599 case detail::value_t::object:
10600 {
10601 // create an entry in the object
10602 result = &result->operator[](reference_token);
10603 break;
10604 }
10605
10606 case detail::value_t::array:
10607 {
10608 // create an entry in the array
10609 JSON_TRY
10610 {
10611 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
10612 }
10613 JSON_CATCH(std::invalid_argument&)
10614 {
10615 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10616 }
10617 break;
10618 }
10619
10620 /*
10621 The following code is only reached if there exists a reference
10622 token _and_ the current value is primitive. In this case, we have
10623 an error situation, because primitive values may only occur as
10624 single value; that is, with an empty list of reference tokens.
10625 */
10626 default:
10627 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
10628 }
10629 }
10630
10631 return *result;
10632 }
10633
10634 /*!
10635 @brief return a reference to the pointed to value
10636
10637 @note This version does not throw if a value is not present, but tries to
10638 create nested values instead. For instance, calling this function
10639 with pointer `"/this/that"` on a null value is equivalent to calling
10640 `operator[]("this").operator[]("that")` on that value, effectively
10641 changing the null value to an object.
10642
10643 @param[in] ptr a JSON value
10644
10645 @return reference to the JSON value pointed to by the JSON pointer
10646
10647 @complexity Linear in the length of the JSON pointer.
10648
10649 @throw parse_error.106 if an array index begins with '0'
10650 @throw parse_error.109 if an array index was not a number
10651 @throw out_of_range.404 if the JSON pointer can not be resolved
10652 */
get_unchecked(BasicJsonType * ptr) const10653 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
10654 {
10655 using size_type = typename BasicJsonType::size_type;
10656 for (const auto& reference_token : reference_tokens)
10657 {
10658 // convert null values to arrays or objects before continuing
10659 if (ptr->m_type == detail::value_t::null)
10660 {
10661 // check if reference token is a number
10662 const bool nums =
10663 std::all_of(reference_token.begin(), reference_token.end(),
10664 [](const char x)
10665 {
10666 return (x >= '0' and x <= '9');
10667 });
10668
10669 // change value to array for numbers or "-" or to object otherwise
10670 *ptr = (nums or reference_token == "-")
10671 ? detail::value_t::array
10672 : detail::value_t::object;
10673 }
10674
10675 switch (ptr->m_type)
10676 {
10677 case detail::value_t::object:
10678 {
10679 // use unchecked object access
10680 ptr = &ptr->operator[](reference_token);
10681 break;
10682 }
10683
10684 case detail::value_t::array:
10685 {
10686 // error condition (cf. RFC 6901, Sect. 4)
10687 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10688 {
10689 JSON_THROW(detail::parse_error::create(106, 0,
10690 "array index '" + reference_token +
10691 "' must not begin with '0'"));
10692 }
10693
10694 if (reference_token == "-")
10695 {
10696 // explicitly treat "-" as index beyond the end
10697 ptr = &ptr->operator[](ptr->m_value.array->size());
10698 }
10699 else
10700 {
10701 // convert array index to number; unchecked access
10702 JSON_TRY
10703 {
10704 ptr = &ptr->operator[](
10705 static_cast<size_type>(array_index(reference_token)));
10706 }
10707 JSON_CATCH(std::invalid_argument&)
10708 {
10709 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10710 }
10711 }
10712 break;
10713 }
10714
10715 default:
10716 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10717 }
10718 }
10719
10720 return *ptr;
10721 }
10722
10723 /*!
10724 @throw parse_error.106 if an array index begins with '0'
10725 @throw parse_error.109 if an array index was not a number
10726 @throw out_of_range.402 if the array index '-' is used
10727 @throw out_of_range.404 if the JSON pointer can not be resolved
10728 */
get_checked(BasicJsonType * ptr) const10729 BasicJsonType& get_checked(BasicJsonType* ptr) const
10730 {
10731 using size_type = typename BasicJsonType::size_type;
10732 for (const auto& reference_token : reference_tokens)
10733 {
10734 switch (ptr->m_type)
10735 {
10736 case detail::value_t::object:
10737 {
10738 // note: at performs range check
10739 ptr = &ptr->at(reference_token);
10740 break;
10741 }
10742
10743 case detail::value_t::array:
10744 {
10745 if (JSON_UNLIKELY(reference_token == "-"))
10746 {
10747 // "-" always fails the range check
10748 JSON_THROW(detail::out_of_range::create(402,
10749 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10750 ") is out of range"));
10751 }
10752
10753 // error condition (cf. RFC 6901, Sect. 4)
10754 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10755 {
10756 JSON_THROW(detail::parse_error::create(106, 0,
10757 "array index '" + reference_token +
10758 "' must not begin with '0'"));
10759 }
10760
10761 // note: at performs range check
10762 JSON_TRY
10763 {
10764 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10765 }
10766 JSON_CATCH(std::invalid_argument&)
10767 {
10768 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10769 }
10770 break;
10771 }
10772
10773 default:
10774 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10775 }
10776 }
10777
10778 return *ptr;
10779 }
10780
10781 /*!
10782 @brief return a const reference to the pointed to value
10783
10784 @param[in] ptr a JSON value
10785
10786 @return const reference to the JSON value pointed to by the JSON
10787 pointer
10788
10789 @throw parse_error.106 if an array index begins with '0'
10790 @throw parse_error.109 if an array index was not a number
10791 @throw out_of_range.402 if the array index '-' is used
10792 @throw out_of_range.404 if the JSON pointer can not be resolved
10793 */
get_unchecked(const BasicJsonType * ptr) const10794 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
10795 {
10796 using size_type = typename BasicJsonType::size_type;
10797 for (const auto& reference_token : reference_tokens)
10798 {
10799 switch (ptr->m_type)
10800 {
10801 case detail::value_t::object:
10802 {
10803 // use unchecked object access
10804 ptr = &ptr->operator[](reference_token);
10805 break;
10806 }
10807
10808 case detail::value_t::array:
10809 {
10810 if (JSON_UNLIKELY(reference_token == "-"))
10811 {
10812 // "-" cannot be used for const access
10813 JSON_THROW(detail::out_of_range::create(402,
10814 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10815 ") is out of range"));
10816 }
10817
10818 // error condition (cf. RFC 6901, Sect. 4)
10819 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10820 {
10821 JSON_THROW(detail::parse_error::create(106, 0,
10822 "array index '" + reference_token +
10823 "' must not begin with '0'"));
10824 }
10825
10826 // use unchecked array access
10827 JSON_TRY
10828 {
10829 ptr = &ptr->operator[](
10830 static_cast<size_type>(array_index(reference_token)));
10831 }
10832 JSON_CATCH(std::invalid_argument&)
10833 {
10834 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10835 }
10836 break;
10837 }
10838
10839 default:
10840 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10841 }
10842 }
10843
10844 return *ptr;
10845 }
10846
10847 /*!
10848 @throw parse_error.106 if an array index begins with '0'
10849 @throw parse_error.109 if an array index was not a number
10850 @throw out_of_range.402 if the array index '-' is used
10851 @throw out_of_range.404 if the JSON pointer can not be resolved
10852 */
get_checked(const BasicJsonType * ptr) const10853 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
10854 {
10855 using size_type = typename BasicJsonType::size_type;
10856 for (const auto& reference_token : reference_tokens)
10857 {
10858 switch (ptr->m_type)
10859 {
10860 case detail::value_t::object:
10861 {
10862 // note: at performs range check
10863 ptr = &ptr->at(reference_token);
10864 break;
10865 }
10866
10867 case detail::value_t::array:
10868 {
10869 if (JSON_UNLIKELY(reference_token == "-"))
10870 {
10871 // "-" always fails the range check
10872 JSON_THROW(detail::out_of_range::create(402,
10873 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10874 ") is out of range"));
10875 }
10876
10877 // error condition (cf. RFC 6901, Sect. 4)
10878 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10879 {
10880 JSON_THROW(detail::parse_error::create(106, 0,
10881 "array index '" + reference_token +
10882 "' must not begin with '0'"));
10883 }
10884
10885 // note: at performs range check
10886 JSON_TRY
10887 {
10888 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10889 }
10890 JSON_CATCH(std::invalid_argument&)
10891 {
10892 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10893 }
10894 break;
10895 }
10896
10897 default:
10898 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10899 }
10900 }
10901
10902 return *ptr;
10903 }
10904
10905 /*!
10906 @brief split the string input to reference tokens
10907
10908 @note This function is only called by the json_pointer constructor.
10909 All exceptions below are documented there.
10910
10911 @throw parse_error.107 if the pointer is not empty or begins with '/'
10912 @throw parse_error.108 if character '~' is not followed by '0' or '1'
10913 */
split(const std::string & reference_string)10914 static std::vector<std::string> split(const std::string& reference_string)
10915 {
10916 std::vector<std::string> result;
10917
10918 // special case: empty reference string -> no reference tokens
10919 if (reference_string.empty())
10920 {
10921 return result;
10922 }
10923
10924 // check if nonempty reference string begins with slash
10925 if (JSON_UNLIKELY(reference_string[0] != '/'))
10926 {
10927 JSON_THROW(detail::parse_error::create(107, 1,
10928 "JSON pointer must be empty or begin with '/' - was: '" +
10929 reference_string + "'"));
10930 }
10931
10932 // extract the reference tokens:
10933 // - slash: position of the last read slash (or end of string)
10934 // - start: position after the previous slash
10935 for (
10936 // search for the first slash after the first character
10937 std::size_t slash = reference_string.find_first_of('/', 1),
10938 // set the beginning of the first reference token
10939 start = 1;
10940 // we can stop if start == string::npos+1 = 0
10941 start != 0;
10942 // set the beginning of the next reference token
10943 // (will eventually be 0 if slash == std::string::npos)
10944 start = slash + 1,
10945 // find next slash
10946 slash = reference_string.find_first_of('/', start))
10947 {
10948 // use the text between the beginning of the reference token
10949 // (start) and the last slash (slash).
10950 auto reference_token = reference_string.substr(start, slash - start);
10951
10952 // check reference tokens are properly escaped
10953 for (std::size_t pos = reference_token.find_first_of('~');
10954 pos != std::string::npos;
10955 pos = reference_token.find_first_of('~', pos + 1))
10956 {
10957 assert(reference_token[pos] == '~');
10958
10959 // ~ must be followed by 0 or 1
10960 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
10961 (reference_token[pos + 1] != '0' and
10962 reference_token[pos + 1] != '1')))
10963 {
10964 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
10965 }
10966 }
10967
10968 // finally, store the reference token
10969 unescape(reference_token);
10970 result.push_back(reference_token);
10971 }
10972
10973 return result;
10974 }
10975
10976 /*!
10977 @brief replace all occurrences of a substring by another string
10978
10979 @param[in,out] s the string to manipulate; changed so that all
10980 occurrences of @a f are replaced with @a t
10981 @param[in] f the substring to replace with @a t
10982 @param[in] t the string to replace @a f
10983
10984 @pre The search string @a f must not be empty. **This precondition is
10985 enforced with an assertion.**
10986
10987 @since version 2.0.0
10988 */
replace_substring(std::string & s,const std::string & f,const std::string & t)10989 static void replace_substring(std::string& s, const std::string& f,
10990 const std::string& t)
10991 {
10992 assert(not f.empty());
10993 for (auto pos = s.find(f); // find first occurrence of f
10994 pos != std::string::npos; // make sure f was found
10995 s.replace(pos, f.size(), t), // replace with t, and
10996 pos = s.find(f, pos + t.size())) // find next occurrence of f
10997 {}
10998 }
10999
11000 /// escape "~"" to "~0" and "/" to "~1"
escape(std::string s)11001 static std::string escape(std::string s)
11002 {
11003 replace_substring(s, "~", "~0");
11004 replace_substring(s, "/", "~1");
11005 return s;
11006 }
11007
11008 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)11009 static void unescape(std::string& s)
11010 {
11011 replace_substring(s, "~1", "/");
11012 replace_substring(s, "~0", "~");
11013 }
11014
11015 /*!
11016 @param[in] reference_string the reference string to the current value
11017 @param[in] value the value to consider
11018 @param[in,out] result the result object to insert values to
11019
11020 @note Empty objects or arrays are flattened to `null`.
11021 */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)11022 static void flatten(const std::string& reference_string,
11023 const BasicJsonType& value,
11024 BasicJsonType& result)
11025 {
11026 switch (value.m_type)
11027 {
11028 case detail::value_t::array:
11029 {
11030 if (value.m_value.array->empty())
11031 {
11032 // flatten empty array as null
11033 result[reference_string] = nullptr;
11034 }
11035 else
11036 {
11037 // iterate array and use index as reference string
11038 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11039 {
11040 flatten(reference_string + "/" + std::to_string(i),
11041 value.m_value.array->operator[](i), result);
11042 }
11043 }
11044 break;
11045 }
11046
11047 case detail::value_t::object:
11048 {
11049 if (value.m_value.object->empty())
11050 {
11051 // flatten empty object as null
11052 result[reference_string] = nullptr;
11053 }
11054 else
11055 {
11056 // iterate object and use keys as reference string
11057 for (const auto& element : *value.m_value.object)
11058 {
11059 flatten(reference_string + "/" + escape(element.first), element.second, result);
11060 }
11061 }
11062 break;
11063 }
11064
11065 default:
11066 {
11067 // add primitive value with its reference string
11068 result[reference_string] = value;
11069 break;
11070 }
11071 }
11072 }
11073
11074 /*!
11075 @param[in] value flattened JSON
11076
11077 @return unflattened JSON
11078
11079 @throw parse_error.109 if array index is not a number
11080 @throw type_error.314 if value is not an object
11081 @throw type_error.315 if object values are not primitive
11082 @throw type_error.313 if value cannot be unflattened
11083 */
11084 static BasicJsonType
unflatten(const BasicJsonType & value)11085 unflatten(const BasicJsonType& value)
11086 {
11087 if (JSON_UNLIKELY(not value.is_object()))
11088 {
11089 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11090 }
11091
11092 BasicJsonType result;
11093
11094 // iterate the JSON object values
11095 for (const auto& element : *value.m_value.object)
11096 {
11097 if (JSON_UNLIKELY(not element.second.is_primitive()))
11098 {
11099 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11100 }
11101
11102 // assign value to reference pointed to by JSON pointer; Note that if
11103 // the JSON pointer is "" (i.e., points to the whole value), function
11104 // get_and_create returns a reference to result itself. An assignment
11105 // will then create a primitive value.
11106 json_pointer(element.first).get_and_create(result) = element.second;
11107 }
11108
11109 return result;
11110 }
11111
operator ==(json_pointer const & lhs,json_pointer const & rhs)11112 friend bool operator==(json_pointer const& lhs,
11113 json_pointer const& rhs) noexcept
11114 {
11115 return (lhs.reference_tokens == rhs.reference_tokens);
11116 }
11117
operator !=(json_pointer const & lhs,json_pointer const & rhs)11118 friend bool operator!=(json_pointer const& lhs,
11119 json_pointer const& rhs) noexcept
11120 {
11121 return not (lhs == rhs);
11122 }
11123
11124 /// the reference tokens
11125 std::vector<std::string> reference_tokens;
11126 };
11127 }
11128
11129 // #include <nlohmann/adl_serializer.hpp>
11130
11131
11132 #include <utility>
11133
11134 // #include <nlohmann/detail/conversions/from_json.hpp>
11135
11136 // #include <nlohmann/detail/conversions/to_json.hpp>
11137
11138
11139 namespace nlohmann
11140 {
11141 template<typename, typename>
11142 struct adl_serializer
11143 {
11144 /*!
11145 @brief convert a JSON value to any value type
11146
11147 This function is usually called by the `get()` function of the
11148 @ref basic_json class (either explicit or via conversion operators).
11149
11150 @param[in] j JSON value to read from
11151 @param[in,out] val value to write to
11152 */
11153 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer11154 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
11155 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
11156 {
11157 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
11158 }
11159
11160 /*!
11161 @brief convert any value type to a JSON value
11162
11163 This function is usually called by the constructors of the @ref basic_json
11164 class.
11165
11166 @param[in,out] j JSON value to write to
11167 @param[in] val value to read from
11168 */
11169 template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer11170 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
11171 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
11172 {
11173 ::nlohmann::to_json(j, std::forward<ValueType>(val));
11174 }
11175 };
11176 }
11177
11178
11179 /*!
11180 @brief namespace for Niels Lohmann
11181 @see https://github.com/nlohmann
11182 @since version 1.0.0
11183 */
11184 namespace nlohmann
11185 {
11186
11187 /*!
11188 @brief a class to store JSON values
11189
11190 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
11191 in @ref object_t)
11192 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
11193 in @ref array_t)
11194 @tparam StringType type for JSON strings and object keys (`std::string` by
11195 default; will be used in @ref string_t)
11196 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
11197 in @ref boolean_t)
11198 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
11199 default; will be used in @ref number_integer_t)
11200 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
11201 `uint64_t` by default; will be used in @ref number_unsigned_t)
11202 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
11203 default; will be used in @ref number_float_t)
11204 @tparam AllocatorType type of the allocator to use (`std::allocator` by
11205 default)
11206 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
11207 and `from_json()` (@ref adl_serializer by default)
11208
11209 @requirement The class satisfies the following concept requirements:
11210 - Basic
11211 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
11212 JSON values can be default constructed. The result will be a JSON null
11213 value.
11214 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
11215 A JSON value can be constructed from an rvalue argument.
11216 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
11217 A JSON value can be copy-constructed from an lvalue expression.
11218 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
11219 A JSON value van be assigned from an rvalue argument.
11220 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
11221 A JSON value can be copy-assigned from an lvalue expression.
11222 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
11223 JSON values can be destructed.
11224 - Layout
11225 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
11226 JSON values have
11227 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
11228 All non-static data members are private and standard layout types, the
11229 class has no virtual functions or (virtual) base classes.
11230 - Library-wide
11231 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
11232 JSON values can be compared with `==`, see @ref
11233 operator==(const_reference,const_reference).
11234 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
11235 JSON values can be compared with `<`, see @ref
11236 operator<(const_reference,const_reference).
11237 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
11238 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
11239 other compatible types, using unqualified function call @ref swap().
11240 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
11241 JSON values can be compared against `std::nullptr_t` objects which are used
11242 to model the `null` value.
11243 - Container
11244 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
11245 JSON values can be used like STL containers and provide iterator access.
11246 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
11247 JSON values can be used like STL containers and provide reverse iterator
11248 access.
11249
11250 @invariant The member variables @a m_value and @a m_type have the following
11251 relationship:
11252 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
11253 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
11254 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
11255 The invariants are checked by member function assert_invariant().
11256
11257 @internal
11258 @note ObjectType trick from http://stackoverflow.com/a/9860911
11259 @endinternal
11260
11261 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
11262 Format](http://rfc7159.net/rfc7159)
11263
11264 @since version 1.0.0
11265
11266 @nosubgrouping
11267 */
11268 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11269 class basic_json
11270 {
11271 private:
11272 template<detail::value_t> friend struct detail::external_constructor;
11273 friend ::nlohmann::json_pointer<basic_json>;
11274 friend ::nlohmann::detail::parser<basic_json>;
11275 friend ::nlohmann::detail::serializer<basic_json>;
11276 template<typename BasicJsonType>
11277 friend class ::nlohmann::detail::iter_impl;
11278 template<typename BasicJsonType, typename CharType>
11279 friend class ::nlohmann::detail::binary_writer;
11280 template<typename BasicJsonType, typename SAX>
11281 friend class ::nlohmann::detail::binary_reader;
11282 template<typename BasicJsonType>
11283 friend class ::nlohmann::detail::json_sax_dom_parser;
11284 template<typename BasicJsonType>
11285 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
11286
11287 /// workaround type for MSVC
11288 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
11289
11290 // convenience aliases for types residing in namespace detail;
11291 using lexer = ::nlohmann::detail::lexer<basic_json>;
11292 using parser = ::nlohmann::detail::parser<basic_json>;
11293
11294 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
11295 template<typename BasicJsonType>
11296 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
11297 template<typename BasicJsonType>
11298 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
11299 template<typename Iterator>
11300 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
11301 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
11302
11303 template<typename CharType>
11304 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
11305
11306 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
11307 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
11308
11309 using serializer = ::nlohmann::detail::serializer<basic_json>;
11310
11311 public:
11312 using value_t = detail::value_t;
11313 /// JSON Pointer, see @ref nlohmann::json_pointer
11314 using json_pointer = ::nlohmann::json_pointer<basic_json>;
11315 template<typename T, typename SFINAE>
11316 using json_serializer = JSONSerializer<T, SFINAE>;
11317 /// helper type for initializer lists of basic_json values
11318 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
11319
11320 using input_format_t = detail::input_format_t;
11321 /// SAX interface type, see @ref nlohmann::json_sax
11322 using json_sax_t = json_sax<basic_json>;
11323
11324 ////////////////
11325 // exceptions //
11326 ////////////////
11327
11328 /// @name exceptions
11329 /// Classes to implement user-defined exceptions.
11330 /// @{
11331
11332 /// @copydoc detail::exception
11333 using exception = detail::exception;
11334 /// @copydoc detail::parse_error
11335 using parse_error = detail::parse_error;
11336 /// @copydoc detail::invalid_iterator
11337 using invalid_iterator = detail::invalid_iterator;
11338 /// @copydoc detail::type_error
11339 using type_error = detail::type_error;
11340 /// @copydoc detail::out_of_range
11341 using out_of_range = detail::out_of_range;
11342 /// @copydoc detail::other_error
11343 using other_error = detail::other_error;
11344
11345 /// @}
11346
11347
11348 /////////////////////
11349 // container types //
11350 /////////////////////
11351
11352 /// @name container types
11353 /// The canonic container types to use @ref basic_json like any other STL
11354 /// container.
11355 /// @{
11356
11357 /// the type of elements in a basic_json container
11358 using value_type = basic_json;
11359
11360 /// the type of an element reference
11361 using reference = value_type&;
11362 /// the type of an element const reference
11363 using const_reference = const value_type&;
11364
11365 /// a type to represent differences between iterators
11366 using difference_type = std::ptrdiff_t;
11367 /// a type to represent container sizes
11368 using size_type = std::size_t;
11369
11370 /// the allocator type
11371 using allocator_type = AllocatorType<basic_json>;
11372
11373 /// the type of an element pointer
11374 using pointer = typename std::allocator_traits<allocator_type>::pointer;
11375 /// the type of an element const pointer
11376 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
11377
11378 /// an iterator for a basic_json container
11379 using iterator = iter_impl<basic_json>;
11380 /// a const iterator for a basic_json container
11381 using const_iterator = iter_impl<const basic_json>;
11382 /// a reverse iterator for a basic_json container
11383 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
11384 /// a const reverse iterator for a basic_json container
11385 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
11386
11387 /// @}
11388
11389
11390 /*!
11391 @brief returns the allocator associated with the container
11392 */
get_allocator()11393 static allocator_type get_allocator()
11394 {
11395 return allocator_type();
11396 }
11397
11398 /*!
11399 @brief returns version information on the library
11400
11401 This function returns a JSON object with information about the library,
11402 including the version number and information on the platform and compiler.
11403
11404 @return JSON object holding version information
11405 key | description
11406 ----------- | ---------------
11407 `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).
11408 `copyright` | The copyright line for the library as string.
11409 `name` | The name of the library as string.
11410 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
11411 `url` | The URL of the project as string.
11412 `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).
11413
11414 @liveexample{The following code shows an example output of the `meta()`
11415 function.,meta}
11416
11417 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
11418 changes to any JSON value.
11419
11420 @complexity Constant.
11421
11422 @since 2.1.0
11423 */
meta()11424 static basic_json meta()
11425 {
11426 basic_json result;
11427
11428 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
11429 result["name"] = "JSON for Modern C++";
11430 result["url"] = "https://github.com/nlohmann/json";
11431 result["version"]["string"] =
11432 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
11433 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
11434 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
11435 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
11436 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
11437 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
11438
11439 #ifdef _WIN32
11440 result["platform"] = "win32";
11441 #elif defined __linux__
11442 result["platform"] = "linux";
11443 #elif defined __APPLE__
11444 result["platform"] = "apple";
11445 #elif defined __unix__
11446 result["platform"] = "unix";
11447 #else
11448 result["platform"] = "unknown";
11449 #endif
11450
11451 #if defined(__ICC) || defined(__INTEL_COMPILER)
11452 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
11453 #elif defined(__clang__)
11454 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
11455 #elif defined(__GNUC__) || defined(__GNUG__)
11456 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
11457 #elif defined(__HP_cc) || defined(__HP_aCC)
11458 result["compiler"] = "hp"
11459 #elif defined(__IBMCPP__)
11460 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
11461 #elif defined(_MSC_VER)
11462 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
11463 #elif defined(__PGI)
11464 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
11465 #elif defined(__SUNPRO_CC)
11466 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
11467 #else
11468 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
11469 #endif
11470
11471 #ifdef __cplusplus
11472 result["compiler"]["c++"] = std::to_string(__cplusplus);
11473 #else
11474 result["compiler"]["c++"] = "unknown";
11475 #endif
11476 return result;
11477 }
11478
11479
11480 ///////////////////////////
11481 // JSON value data types //
11482 ///////////////////////////
11483
11484 /// @name JSON value data types
11485 /// The data types to store a JSON value. These types are derived from
11486 /// the template arguments passed to class @ref basic_json.
11487 /// @{
11488
11489 #if defined(JSON_HAS_CPP_14)
11490 // Use transparent comparator if possible, combined with perfect forwarding
11491 // on find() and count() calls prevents unnecessary string construction.
11492 using object_comparator_t = std::less<>;
11493 #else
11494 using object_comparator_t = std::less<StringType>;
11495 #endif
11496
11497 /*!
11498 @brief a type for an object
11499
11500 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
11501 > An object is an unordered collection of zero or more name/value pairs,
11502 > where a name is a string and a value is a string, number, boolean, null,
11503 > object, or array.
11504
11505 To store objects in C++, a type is defined by the template parameters
11506 described below.
11507
11508 @tparam ObjectType the container to store objects (e.g., `std::map` or
11509 `std::unordered_map`)
11510 @tparam StringType the type of the keys or names (e.g., `std::string`).
11511 The comparison function `std::less<StringType>` is used to order elements
11512 inside the container.
11513 @tparam AllocatorType the allocator to use for objects (e.g.,
11514 `std::allocator`)
11515
11516 #### Default type
11517
11518 With the default values for @a ObjectType (`std::map`), @a StringType
11519 (`std::string`), and @a AllocatorType (`std::allocator`), the default
11520 value for @a object_t is:
11521
11522 @code {.cpp}
11523 std::map<
11524 std::string, // key_type
11525 basic_json, // value_type
11526 std::less<std::string>, // key_compare
11527 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
11528 >
11529 @endcode
11530
11531 #### Behavior
11532
11533 The choice of @a object_t influences the behavior of the JSON class. With
11534 the default type, objects have the following behavior:
11535
11536 - When all names are unique, objects will be interoperable in the sense
11537 that all software implementations receiving that object will agree on
11538 the name-value mappings.
11539 - When the names within an object are not unique, it is unspecified which
11540 one of the values for a given key will be chosen. For instance,
11541 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
11542 `{"key": 2}`.
11543 - Internally, name/value pairs are stored in lexicographical order of the
11544 names. Objects will also be serialized (see @ref dump) in this order.
11545 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
11546 and serialized as `{"a": 2, "b": 1}`.
11547 - When comparing objects, the order of the name/value pairs is irrelevant.
11548 This makes objects interoperable in the sense that they will not be
11549 affected by these differences. For instance, `{"b": 1, "a": 2}` and
11550 `{"a": 2, "b": 1}` will be treated as equal.
11551
11552 #### Limits
11553
11554 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11555 > An implementation may set limits on the maximum depth of nesting.
11556
11557 In this class, the object's limit of nesting is not explicitly constrained.
11558 However, a maximum depth of nesting may be introduced by the compiler or
11559 runtime environment. A theoretical limit can be queried by calling the
11560 @ref max_size function of a JSON object.
11561
11562 #### Storage
11563
11564 Objects are stored as pointers in a @ref basic_json type. That is, for any
11565 access to object values, a pointer of type `object_t*` must be
11566 dereferenced.
11567
11568 @sa @ref array_t -- type for an array value
11569
11570 @since version 1.0.0
11571
11572 @note The order name/value pairs are added to the object is *not*
11573 preserved by the library. Therefore, iterating an object may return
11574 name/value pairs in a different order than they were originally stored. In
11575 fact, keys will be traversed in alphabetical order as `std::map` with
11576 `std::less` is used by default. Please note this behavior conforms to [RFC
11577 7159](http://rfc7159.net/rfc7159), because any order implements the
11578 specified "unordered" nature of JSON objects.
11579 */
11580 using object_t = ObjectType<StringType,
11581 basic_json,
11582 object_comparator_t,
11583 AllocatorType<std::pair<const StringType,
11584 basic_json>>>;
11585
11586 /*!
11587 @brief a type for an array
11588
11589 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
11590 > An array is an ordered sequence of zero or more values.
11591
11592 To store objects in C++, a type is defined by the template parameters
11593 explained below.
11594
11595 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
11596 `std::list`)
11597 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
11598
11599 #### Default type
11600
11601 With the default values for @a ArrayType (`std::vector`) and @a
11602 AllocatorType (`std::allocator`), the default value for @a array_t is:
11603
11604 @code {.cpp}
11605 std::vector<
11606 basic_json, // value_type
11607 std::allocator<basic_json> // allocator_type
11608 >
11609 @endcode
11610
11611 #### Limits
11612
11613 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11614 > An implementation may set limits on the maximum depth of nesting.
11615
11616 In this class, the array's limit of nesting is not explicitly constrained.
11617 However, a maximum depth of nesting may be introduced by the compiler or
11618 runtime environment. A theoretical limit can be queried by calling the
11619 @ref max_size function of a JSON array.
11620
11621 #### Storage
11622
11623 Arrays are stored as pointers in a @ref basic_json type. That is, for any
11624 access to array values, a pointer of type `array_t*` must be dereferenced.
11625
11626 @sa @ref object_t -- type for an object value
11627
11628 @since version 1.0.0
11629 */
11630 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
11631
11632 /*!
11633 @brief a type for a string
11634
11635 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
11636 > A string is a sequence of zero or more Unicode characters.
11637
11638 To store objects in C++, a type is defined by the template parameter
11639 described below. Unicode values are split by the JSON class into
11640 byte-sized characters during deserialization.
11641
11642 @tparam StringType the container to store strings (e.g., `std::string`).
11643 Note this container is used for keys/names in objects, see @ref object_t.
11644
11645 #### Default type
11646
11647 With the default values for @a StringType (`std::string`), the default
11648 value for @a string_t is:
11649
11650 @code {.cpp}
11651 std::string
11652 @endcode
11653
11654 #### Encoding
11655
11656 Strings are stored in UTF-8 encoding. Therefore, functions like
11657 `std::string::size()` or `std::string::length()` return the number of
11658 bytes in the string rather than the number of characters or glyphs.
11659
11660 #### String comparison
11661
11662 [RFC 7159](http://rfc7159.net/rfc7159) states:
11663 > Software implementations are typically required to test names of object
11664 > members for equality. Implementations that transform the textual
11665 > representation into sequences of Unicode code units and then perform the
11666 > comparison numerically, code unit by code unit, are interoperable in the
11667 > sense that implementations will agree in all cases on equality or
11668 > inequality of two strings. For example, implementations that compare
11669 > strings with escaped characters unconverted may incorrectly find that
11670 > `"a\\b"` and `"a\u005Cb"` are not equal.
11671
11672 This implementation is interoperable as it does compare strings code unit
11673 by code unit.
11674
11675 #### Storage
11676
11677 String values are stored as pointers in a @ref basic_json type. That is,
11678 for any access to string values, a pointer of type `string_t*` must be
11679 dereferenced.
11680
11681 @since version 1.0.0
11682 */
11683 using string_t = StringType;
11684
11685 /*!
11686 @brief a type for a boolean
11687
11688 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
11689 type which differentiates the two literals `true` and `false`.
11690
11691 To store objects in C++, a type is defined by the template parameter @a
11692 BooleanType which chooses the type to use.
11693
11694 #### Default type
11695
11696 With the default values for @a BooleanType (`bool`), the default value for
11697 @a boolean_t is:
11698
11699 @code {.cpp}
11700 bool
11701 @endcode
11702
11703 #### Storage
11704
11705 Boolean values are stored directly inside a @ref basic_json type.
11706
11707 @since version 1.0.0
11708 */
11709 using boolean_t = BooleanType;
11710
11711 /*!
11712 @brief a type for a number (integer)
11713
11714 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11715 > The representation of numbers is similar to that used in most
11716 > programming languages. A number is represented in base 10 using decimal
11717 > digits. It contains an integer component that may be prefixed with an
11718 > optional minus sign, which may be followed by a fraction part and/or an
11719 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11720 > cannot be represented in the grammar below (such as Infinity and NaN)
11721 > are not permitted.
11722
11723 This description includes both integer and floating-point numbers.
11724 However, C++ allows more precise storage if it is known whether the number
11725 is a signed integer, an unsigned integer or a floating-point number.
11726 Therefore, three different types, @ref number_integer_t, @ref
11727 number_unsigned_t and @ref number_float_t are used.
11728
11729 To store integer numbers in C++, a type is defined by the template
11730 parameter @a NumberIntegerType which chooses the type to use.
11731
11732 #### Default type
11733
11734 With the default values for @a NumberIntegerType (`int64_t`), the default
11735 value for @a number_integer_t is:
11736
11737 @code {.cpp}
11738 int64_t
11739 @endcode
11740
11741 #### Default behavior
11742
11743 - The restrictions about leading zeros is not enforced in C++. Instead,
11744 leading zeros in integer literals lead to an interpretation as octal
11745 number. Internally, the value will be stored as decimal number. For
11746 instance, the C++ integer literal `010` will be serialized to `8`.
11747 During deserialization, leading zeros yield an error.
11748 - Not-a-number (NaN) values will be serialized to `null`.
11749
11750 #### Limits
11751
11752 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11753 > An implementation may set limits on the range and precision of numbers.
11754
11755 When the default type is used, the maximal integer number that can be
11756 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
11757 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
11758 that are out of range will yield over/underflow when used in a
11759 constructor. During deserialization, too large or small integer numbers
11760 will be automatically be stored as @ref number_unsigned_t or @ref
11761 number_float_t.
11762
11763 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11764 > Note that when such software is used, numbers that are integers and are
11765 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11766 > that implementations will agree exactly on their numeric values.
11767
11768 As this range is a subrange of the exactly supported range [INT64_MIN,
11769 INT64_MAX], this class's integer type is interoperable.
11770
11771 #### Storage
11772
11773 Integer number values are stored directly inside a @ref basic_json type.
11774
11775 @sa @ref number_float_t -- type for number values (floating-point)
11776
11777 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11778
11779 @since version 1.0.0
11780 */
11781 using number_integer_t = NumberIntegerType;
11782
11783 /*!
11784 @brief a type for a number (unsigned)
11785
11786 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11787 > The representation of numbers is similar to that used in most
11788 > programming languages. A number is represented in base 10 using decimal
11789 > digits. It contains an integer component that may be prefixed with an
11790 > optional minus sign, which may be followed by a fraction part and/or an
11791 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11792 > cannot be represented in the grammar below (such as Infinity and NaN)
11793 > are not permitted.
11794
11795 This description includes both integer and floating-point numbers.
11796 However, C++ allows more precise storage if it is known whether the number
11797 is a signed integer, an unsigned integer or a floating-point number.
11798 Therefore, three different types, @ref number_integer_t, @ref
11799 number_unsigned_t and @ref number_float_t are used.
11800
11801 To store unsigned integer numbers in C++, a type is defined by the
11802 template parameter @a NumberUnsignedType which chooses the type to use.
11803
11804 #### Default type
11805
11806 With the default values for @a NumberUnsignedType (`uint64_t`), the
11807 default value for @a number_unsigned_t is:
11808
11809 @code {.cpp}
11810 uint64_t
11811 @endcode
11812
11813 #### Default behavior
11814
11815 - The restrictions about leading zeros is not enforced in C++. Instead,
11816 leading zeros in integer literals lead to an interpretation as octal
11817 number. Internally, the value will be stored as decimal number. For
11818 instance, the C++ integer literal `010` will be serialized to `8`.
11819 During deserialization, leading zeros yield an error.
11820 - Not-a-number (NaN) values will be serialized to `null`.
11821
11822 #### Limits
11823
11824 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11825 > An implementation may set limits on the range and precision of numbers.
11826
11827 When the default type is used, the maximal integer number that can be
11828 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
11829 number that can be stored is `0`. Integer numbers that are out of range
11830 will yield over/underflow when used in a constructor. During
11831 deserialization, too large or small integer numbers will be automatically
11832 be stored as @ref number_integer_t or @ref number_float_t.
11833
11834 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11835 > Note that when such software is used, numbers that are integers and are
11836 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11837 > that implementations will agree exactly on their numeric values.
11838
11839 As this range is a subrange (when considered in conjunction with the
11840 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
11841 this class's integer type is interoperable.
11842
11843 #### Storage
11844
11845 Integer number values are stored directly inside a @ref basic_json type.
11846
11847 @sa @ref number_float_t -- type for number values (floating-point)
11848 @sa @ref number_integer_t -- type for number values (integer)
11849
11850 @since version 2.0.0
11851 */
11852 using number_unsigned_t = NumberUnsignedType;
11853
11854 /*!
11855 @brief a type for a number (floating-point)
11856
11857 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11858 > The representation of numbers is similar to that used in most
11859 > programming languages. A number is represented in base 10 using decimal
11860 > digits. It contains an integer component that may be prefixed with an
11861 > optional minus sign, which may be followed by a fraction part and/or an
11862 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11863 > cannot be represented in the grammar below (such as Infinity and NaN)
11864 > are not permitted.
11865
11866 This description includes both integer and floating-point numbers.
11867 However, C++ allows more precise storage if it is known whether the number
11868 is a signed integer, an unsigned integer or a floating-point number.
11869 Therefore, three different types, @ref number_integer_t, @ref
11870 number_unsigned_t and @ref number_float_t are used.
11871
11872 To store floating-point numbers in C++, a type is defined by the template
11873 parameter @a NumberFloatType which chooses the type to use.
11874
11875 #### Default type
11876
11877 With the default values for @a NumberFloatType (`double`), the default
11878 value for @a number_float_t is:
11879
11880 @code {.cpp}
11881 double
11882 @endcode
11883
11884 #### Default behavior
11885
11886 - The restrictions about leading zeros is not enforced in C++. Instead,
11887 leading zeros in floating-point literals will be ignored. Internally,
11888 the value will be stored as decimal number. For instance, the C++
11889 floating-point literal `01.2` will be serialized to `1.2`. During
11890 deserialization, leading zeros yield an error.
11891 - Not-a-number (NaN) values will be serialized to `null`.
11892
11893 #### Limits
11894
11895 [RFC 7159](http://rfc7159.net/rfc7159) states:
11896 > This specification allows implementations to set limits on the range and
11897 > precision of numbers accepted. Since software that implements IEEE
11898 > 754-2008 binary64 (double precision) numbers is generally available and
11899 > widely used, good interoperability can be achieved by implementations
11900 > that expect no more precision or range than these provide, in the sense
11901 > that implementations will approximate JSON numbers within the expected
11902 > precision.
11903
11904 This implementation does exactly follow this approach, as it uses double
11905 precision floating-point numbers. Note values smaller than
11906 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
11907 will be stored as NaN internally and be serialized to `null`.
11908
11909 #### Storage
11910
11911 Floating-point number values are stored directly inside a @ref basic_json
11912 type.
11913
11914 @sa @ref number_integer_t -- type for number values (integer)
11915
11916 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11917
11918 @since version 1.0.0
11919 */
11920 using number_float_t = NumberFloatType;
11921
11922 /// @}
11923
11924 private:
11925
11926 /// helper for exception-safe object creation
11927 template<typename T, typename... Args>
create(Args &&...args)11928 static T* create(Args&& ... args)
11929 {
11930 AllocatorType<T> alloc;
11931 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
11932
11933 auto deleter = [&](T * object)
11934 {
11935 AllocatorTraits::deallocate(alloc, object, 1);
11936 };
11937 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
11938 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
11939 assert(object != nullptr);
11940 return object.release();
11941 }
11942
11943 ////////////////////////
11944 // JSON value storage //
11945 ////////////////////////
11946
11947 /*!
11948 @brief a JSON value
11949
11950 The actual storage for a JSON value of the @ref basic_json class. This
11951 union combines the different storage types for the JSON value types
11952 defined in @ref value_t.
11953
11954 JSON type | value_t type | used type
11955 --------- | --------------- | ------------------------
11956 object | object | pointer to @ref object_t
11957 array | array | pointer to @ref array_t
11958 string | string | pointer to @ref string_t
11959 boolean | boolean | @ref boolean_t
11960 number | number_integer | @ref number_integer_t
11961 number | number_unsigned | @ref number_unsigned_t
11962 number | number_float | @ref number_float_t
11963 null | null | *no value is stored*
11964
11965 @note Variable-length types (objects, arrays, and strings) are stored as
11966 pointers. The size of the union should not exceed 64 bits if the default
11967 value types are used.
11968
11969 @since version 1.0.0
11970 */
11971 union json_value
11972 {
11973 /// object (stored with pointer to save storage)
11974 object_t* object;
11975 /// array (stored with pointer to save storage)
11976 array_t* array;
11977 /// string (stored with pointer to save storage)
11978 string_t* string;
11979 /// boolean
11980 boolean_t boolean;
11981 /// number (integer)
11982 number_integer_t number_integer;
11983 /// number (unsigned integer)
11984 number_unsigned_t number_unsigned;
11985 /// number (floating-point)
11986 number_float_t number_float;
11987
11988 /// default constructor (for null values)
11989 json_value() = default;
11990 /// constructor for booleans
json_value(boolean_t v)11991 json_value(boolean_t v) noexcept : boolean(v) {}
11992 /// constructor for numbers (integer)
json_value(number_integer_t v)11993 json_value(number_integer_t v) noexcept : number_integer(v) {}
11994 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)11995 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
11996 /// constructor for numbers (floating-point)
json_value(number_float_t v)11997 json_value(number_float_t v) noexcept : number_float(v) {}
11998 /// constructor for empty values of a given type
json_value(value_t t)11999 json_value(value_t t)
12000 {
12001 switch (t)
12002 {
12003 case value_t::object:
12004 {
12005 object = create<object_t>();
12006 break;
12007 }
12008
12009 case value_t::array:
12010 {
12011 array = create<array_t>();
12012 break;
12013 }
12014
12015 case value_t::string:
12016 {
12017 string = create<string_t>("");
12018 break;
12019 }
12020
12021 case value_t::boolean:
12022 {
12023 boolean = boolean_t(false);
12024 break;
12025 }
12026
12027 case value_t::number_integer:
12028 {
12029 number_integer = number_integer_t(0);
12030 break;
12031 }
12032
12033 case value_t::number_unsigned:
12034 {
12035 number_unsigned = number_unsigned_t(0);
12036 break;
12037 }
12038
12039 case value_t::number_float:
12040 {
12041 number_float = number_float_t(0.0);
12042 break;
12043 }
12044
12045 case value_t::null:
12046 {
12047 object = nullptr; // silence warning, see #821
12048 break;
12049 }
12050
12051 default:
12052 {
12053 object = nullptr; // silence warning, see #821
12054 if (JSON_UNLIKELY(t == value_t::null))
12055 {
12056 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.2.0")); // LCOV_EXCL_LINE
12057 }
12058 break;
12059 }
12060 }
12061 }
12062
12063 /// constructor for strings
json_value(const string_t & value)12064 json_value(const string_t& value)
12065 {
12066 string = create<string_t>(value);
12067 }
12068
12069 /// constructor for rvalue strings
json_value(string_t && value)12070 json_value(string_t&& value)
12071 {
12072 string = create<string_t>(std::move(value));
12073 }
12074
12075 /// constructor for objects
json_value(const object_t & value)12076 json_value(const object_t& value)
12077 {
12078 object = create<object_t>(value);
12079 }
12080
12081 /// constructor for rvalue objects
json_value(object_t && value)12082 json_value(object_t&& value)
12083 {
12084 object = create<object_t>(std::move(value));
12085 }
12086
12087 /// constructor for arrays
json_value(const array_t & value)12088 json_value(const array_t& value)
12089 {
12090 array = create<array_t>(value);
12091 }
12092
12093 /// constructor for rvalue arrays
json_value(array_t && value)12094 json_value(array_t&& value)
12095 {
12096 array = create<array_t>(std::move(value));
12097 }
12098
destroy(value_t t)12099 void destroy(value_t t) noexcept
12100 {
12101 switch (t)
12102 {
12103 case value_t::object:
12104 {
12105 AllocatorType<object_t> alloc;
12106 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
12107 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
12108 break;
12109 }
12110
12111 case value_t::array:
12112 {
12113 AllocatorType<array_t> alloc;
12114 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
12115 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
12116 break;
12117 }
12118
12119 case value_t::string:
12120 {
12121 AllocatorType<string_t> alloc;
12122 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
12123 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
12124 break;
12125 }
12126
12127 default:
12128 {
12129 break;
12130 }
12131 }
12132 }
12133 };
12134
12135 /*!
12136 @brief checks the class invariants
12137
12138 This function asserts the class invariants. It needs to be called at the
12139 end of every constructor to make sure that created objects respect the
12140 invariant. Furthermore, it has to be called each time the type of a JSON
12141 value is changed, because the invariant expresses a relationship between
12142 @a m_type and @a m_value.
12143 */
assert_invariant() const12144 void assert_invariant() const noexcept
12145 {
12146 assert(m_type != value_t::object or m_value.object != nullptr);
12147 assert(m_type != value_t::array or m_value.array != nullptr);
12148 assert(m_type != value_t::string or m_value.string != nullptr);
12149 }
12150
12151 public:
12152 //////////////////////////
12153 // JSON parser callback //
12154 //////////////////////////
12155
12156 /*!
12157 @brief parser event types
12158
12159 The parser callback distinguishes the following events:
12160 - `object_start`: the parser read `{` and started to process a JSON object
12161 - `key`: the parser read a key of a value in an object
12162 - `object_end`: the parser read `}` and finished processing a JSON object
12163 - `array_start`: the parser read `[` and started to process a JSON array
12164 - `array_end`: the parser read `]` and finished processing a JSON array
12165 - `value`: the parser finished reading a JSON value
12166
12167 @image html callback_events.png "Example when certain parse events are triggered"
12168
12169 @sa @ref parser_callback_t for more information and examples
12170 */
12171 using parse_event_t = typename parser::parse_event_t;
12172
12173 /*!
12174 @brief per-element parser callback type
12175
12176 With a parser callback function, the result of parsing a JSON text can be
12177 influenced. When passed to @ref parse, it is called on certain events
12178 (passed as @ref parse_event_t via parameter @a event) with a set recursion
12179 depth @a depth and context JSON value @a parsed. The return value of the
12180 callback function is a boolean indicating whether the element that emitted
12181 the callback shall be kept or not.
12182
12183 We distinguish six scenarios (determined by the event type) in which the
12184 callback function can be called. The following table describes the values
12185 of the parameters @a depth, @a event, and @a parsed.
12186
12187 parameter @a event | description | parameter @a depth | parameter @a parsed
12188 ------------------ | ----------- | ------------------ | -------------------
12189 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
12190 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
12191 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
12192 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
12193 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
12194 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
12195
12196 @image html callback_events.png "Example when certain parse events are triggered"
12197
12198 Discarding a value (i.e., returning `false`) has different effects
12199 depending on the context in which function was called:
12200
12201 - Discarded values in structured types are skipped. That is, the parser
12202 will behave as if the discarded value was never read.
12203 - In case a value outside a structured type is skipped, it is replaced
12204 with `null`. This case happens if the top-level element is skipped.
12205
12206 @param[in] depth the depth of the recursion during parsing
12207
12208 @param[in] event an event of type parse_event_t indicating the context in
12209 the callback function has been called
12210
12211 @param[in,out] parsed the current intermediate parse result; note that
12212 writing to this value has no effect for parse_event_t::key events
12213
12214 @return Whether the JSON value which called the function during parsing
12215 should be kept (`true`) or not (`false`). In the latter case, it is either
12216 skipped completely or replaced by an empty discarded object.
12217
12218 @sa @ref parse for examples
12219
12220 @since version 1.0.0
12221 */
12222 using parser_callback_t = typename parser::parser_callback_t;
12223
12224 //////////////////
12225 // constructors //
12226 //////////////////
12227
12228 /// @name constructors and destructors
12229 /// Constructors of class @ref basic_json, copy/move constructor, copy
12230 /// assignment, static functions creating objects, and the destructor.
12231 /// @{
12232
12233 /*!
12234 @brief create an empty value with a given type
12235
12236 Create an empty JSON value with a given type. The value will be default
12237 initialized with an empty value which depends on the type:
12238
12239 Value type | initial value
12240 ----------- | -------------
12241 null | `null`
12242 boolean | `false`
12243 string | `""`
12244 number | `0`
12245 object | `{}`
12246 array | `[]`
12247
12248 @param[in] v the type of the value to create
12249
12250 @complexity Constant.
12251
12252 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12253 changes to any JSON value.
12254
12255 @liveexample{The following code shows the constructor for different @ref
12256 value_t values,basic_json__value_t}
12257
12258 @sa @ref clear() -- restores the postcondition of this constructor
12259
12260 @since version 1.0.0
12261 */
basic_json(const value_t v)12262 basic_json(const value_t v)
12263 : m_type(v), m_value(v)
12264 {
12265 assert_invariant();
12266 }
12267
12268 /*!
12269 @brief create a null object
12270
12271 Create a `null` JSON value. It either takes a null pointer as parameter
12272 (explicitly creating `null`) or no parameter (implicitly creating `null`).
12273 The passed null pointer itself is not read -- it is only used to choose
12274 the right constructor.
12275
12276 @complexity Constant.
12277
12278 @exceptionsafety No-throw guarantee: this constructor never throws
12279 exceptions.
12280
12281 @liveexample{The following code shows the constructor with and without a
12282 null pointer parameter.,basic_json__nullptr_t}
12283
12284 @since version 1.0.0
12285 */
basic_json(std::nullptr_t=nullptr)12286 basic_json(std::nullptr_t = nullptr) noexcept
12287 : basic_json(value_t::null)
12288 {
12289 assert_invariant();
12290 }
12291
12292 /*!
12293 @brief create a JSON value
12294
12295 This is a "catch all" constructor for all compatible JSON types; that is,
12296 types for which a `to_json()` method exists. The constructor forwards the
12297 parameter @a val to that method (to `json_serializer<U>::to_json` method
12298 with `U = uncvref_t<CompatibleType>`, to be exact).
12299
12300 Template type @a CompatibleType includes, but is not limited to, the
12301 following types:
12302 - **arrays**: @ref array_t and all kinds of compatible containers such as
12303 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
12304 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
12305 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
12306 which a @ref basic_json value can be constructed.
12307 - **objects**: @ref object_t and all kinds of compatible associative
12308 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
12309 and `std::unordered_multimap` with a `key_type` compatible to
12310 @ref string_t and a `value_type` from which a @ref basic_json value can
12311 be constructed.
12312 - **strings**: @ref string_t, string literals, and all compatible string
12313 containers can be used.
12314 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
12315 @ref number_float_t, and all convertible number types such as `int`,
12316 `size_t`, `int64_t`, `float` or `double` can be used.
12317 - **boolean**: @ref boolean_t / `bool` can be used.
12318
12319 See the examples below.
12320
12321 @tparam CompatibleType a type such that:
12322 - @a CompatibleType is not derived from `std::istream`,
12323 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
12324 constructors),
12325 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
12326 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
12327 @ref json_pointer, @ref iterator, etc ...)
12328 - @ref @ref json_serializer<U> has a
12329 `to_json(basic_json_t&, CompatibleType&&)` method
12330
12331 @tparam U = `uncvref_t<CompatibleType>`
12332
12333 @param[in] val the value to be forwarded to the respective constructor
12334
12335 @complexity Usually linear in the size of the passed @a val, also
12336 depending on the implementation of the called `to_json()`
12337 method.
12338
12339 @exceptionsafety Depends on the called constructor. For types directly
12340 supported by the library (i.e., all types for which no `to_json()` function
12341 was provided), strong guarantee holds: if an exception is thrown, there are
12342 no changes to any JSON value.
12343
12344 @liveexample{The following code shows the constructor with several
12345 compatible types.,basic_json__CompatibleType}
12346
12347 @since version 2.1.0
12348 */
12349 template <typename CompatibleType,
12350 typename U = detail::uncvref_t<CompatibleType>,
12351 detail::enable_if_t<
12352 detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val)12353 basic_json(CompatibleType && val) noexcept(noexcept(
12354 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
12355 std::forward<CompatibleType>(val))))
12356 {
12357 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
12358 assert_invariant();
12359 }
12360
12361 /*!
12362 @brief create a JSON value from an existing one
12363
12364 This is a constructor for existing @ref basic_json types.
12365 It does not hijack copy/move constructors, since the parameter has different
12366 template arguments than the current ones.
12367
12368 The constructor tries to convert the internal @ref m_value of the parameter.
12369
12370 @tparam BasicJsonType a type such that:
12371 - @a BasicJsonType is a @ref basic_json type.
12372 - @a BasicJsonType has different template arguments than @ref basic_json_t.
12373
12374 @param[in] val the @ref basic_json value to be converted.
12375
12376 @complexity Usually linear in the size of the passed @a val, also
12377 depending on the implementation of the called `to_json()`
12378 method.
12379
12380 @exceptionsafety Depends on the called constructor. For types directly
12381 supported by the library (i.e., all types for which no `to_json()` function
12382 was provided), strong guarantee holds: if an exception is thrown, there are
12383 no changes to any JSON value.
12384
12385 @since version 3.2.0
12386 */
12387 template <typename BasicJsonType,
12388 detail::enable_if_t<
12389 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType & val)12390 basic_json(const BasicJsonType& val)
12391 {
12392 using other_boolean_t = typename BasicJsonType::boolean_t;
12393 using other_number_float_t = typename BasicJsonType::number_float_t;
12394 using other_number_integer_t = typename BasicJsonType::number_integer_t;
12395 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12396 using other_string_t = typename BasicJsonType::string_t;
12397 using other_object_t = typename BasicJsonType::object_t;
12398 using other_array_t = typename BasicJsonType::array_t;
12399
12400 switch (val.type())
12401 {
12402 case value_t::boolean:
12403 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
12404 break;
12405 case value_t::number_float:
12406 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
12407 break;
12408 case value_t::number_integer:
12409 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
12410 break;
12411 case value_t::number_unsigned:
12412 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
12413 break;
12414 case value_t::string:
12415 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
12416 break;
12417 case value_t::object:
12418 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
12419 break;
12420 case value_t::array:
12421 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
12422 break;
12423 case value_t::null:
12424 *this = nullptr;
12425 break;
12426 case value_t::discarded:
12427 m_type = value_t::discarded;
12428 break;
12429 }
12430 assert_invariant();
12431 }
12432
12433 /*!
12434 @brief create a container (array or object) from an initializer list
12435
12436 Creates a JSON value of type array or object from the passed initializer
12437 list @a init. In case @a type_deduction is `true` (default), the type of
12438 the JSON value to be created is deducted from the initializer list @a init
12439 according to the following rules:
12440
12441 1. If the list is empty, an empty JSON object value `{}` is created.
12442 2. If the list consists of pairs whose first element is a string, a JSON
12443 object value is created where the first elements of the pairs are
12444 treated as keys and the second elements are as values.
12445 3. In all other cases, an array is created.
12446
12447 The rules aim to create the best fit between a C++ initializer list and
12448 JSON values. The rationale is as follows:
12449
12450 1. The empty initializer list is written as `{}` which is exactly an empty
12451 JSON object.
12452 2. C++ has no way of describing mapped types other than to list a list of
12453 pairs. As JSON requires that keys must be of type string, rule 2 is the
12454 weakest constraint one can pose on initializer lists to interpret them
12455 as an object.
12456 3. In all other cases, the initializer list could not be interpreted as
12457 JSON object type, so interpreting it as JSON array type is safe.
12458
12459 With the rules described above, the following JSON values cannot be
12460 expressed by an initializer list:
12461
12462 - the empty array (`[]`): use @ref array(initializer_list_t)
12463 with an empty initializer list in this case
12464 - arrays whose elements satisfy rule 2: use @ref
12465 array(initializer_list_t) with the same initializer list
12466 in this case
12467
12468 @note When used without parentheses around an empty initializer list, @ref
12469 basic_json() is called instead of this function, yielding the JSON null
12470 value.
12471
12472 @param[in] init initializer list with JSON values
12473
12474 @param[in] type_deduction internal parameter; when set to `true`, the type
12475 of the JSON value is deducted from the initializer list @a init; when set
12476 to `false`, the type provided via @a manual_type is forced. This mode is
12477 used by the functions @ref array(initializer_list_t) and
12478 @ref object(initializer_list_t).
12479
12480 @param[in] manual_type internal parameter; when @a type_deduction is set
12481 to `false`, the created JSON value will use the provided type (only @ref
12482 value_t::array and @ref value_t::object are valid); when @a type_deduction
12483 is set to `true`, this parameter has no effect
12484
12485 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
12486 `value_t::object`, but @a init contains an element which is not a pair
12487 whose first element is a string. In this case, the constructor could not
12488 create an object. If @a type_deduction would have be `true`, an array
12489 would have been created. See @ref object(initializer_list_t)
12490 for an example.
12491
12492 @complexity Linear in the size of the initializer list @a init.
12493
12494 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12495 changes to any JSON value.
12496
12497 @liveexample{The example below shows how JSON values are created from
12498 initializer lists.,basic_json__list_init_t}
12499
12500 @sa @ref array(initializer_list_t) -- create a JSON array
12501 value from an initializer list
12502 @sa @ref object(initializer_list_t) -- create a JSON object
12503 value from an initializer list
12504
12505 @since version 1.0.0
12506 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)12507 basic_json(initializer_list_t init,
12508 bool type_deduction = true,
12509 value_t manual_type = value_t::array)
12510 {
12511 // check if each element is an array with two elements whose first
12512 // element is a string
12513 bool is_an_object = std::all_of(init.begin(), init.end(),
12514 [](const detail::json_ref<basic_json>& element_ref)
12515 {
12516 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
12517 });
12518
12519 // adjust type if type deduction is not wanted
12520 if (not type_deduction)
12521 {
12522 // if array is wanted, do not create an object though possible
12523 if (manual_type == value_t::array)
12524 {
12525 is_an_object = false;
12526 }
12527
12528 // if object is wanted but impossible, throw an exception
12529 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
12530 {
12531 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
12532 }
12533 }
12534
12535 if (is_an_object)
12536 {
12537 // the initializer list is a list of pairs -> create object
12538 m_type = value_t::object;
12539 m_value = value_t::object;
12540
12541 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
12542 {
12543 auto element = element_ref.moved_or_copied();
12544 m_value.object->emplace(
12545 std::move(*((*element.m_value.array)[0].m_value.string)),
12546 std::move((*element.m_value.array)[1]));
12547 });
12548 }
12549 else
12550 {
12551 // the initializer list describes an array -> create array
12552 m_type = value_t::array;
12553 m_value.array = create<array_t>(init.begin(), init.end());
12554 }
12555
12556 assert_invariant();
12557 }
12558
12559 /*!
12560 @brief explicitly create an array from an initializer list
12561
12562 Creates a JSON array value from a given initializer list. That is, given a
12563 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
12564 initializer list is empty, the empty array `[]` is created.
12565
12566 @note This function is only needed to express two edge cases that cannot
12567 be realized with the initializer list constructor (@ref
12568 basic_json(initializer_list_t, bool, value_t)). These cases
12569 are:
12570 1. creating an array whose elements are all pairs whose first element is a
12571 string -- in this case, the initializer list constructor would create an
12572 object, taking the first elements as keys
12573 2. creating an empty array -- passing the empty initializer list to the
12574 initializer list constructor yields an empty object
12575
12576 @param[in] init initializer list with JSON values to create an array from
12577 (optional)
12578
12579 @return JSON array value
12580
12581 @complexity Linear in the size of @a init.
12582
12583 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12584 changes to any JSON value.
12585
12586 @liveexample{The following code shows an example for the `array`
12587 function.,array}
12588
12589 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12590 create a JSON value from an initializer list
12591 @sa @ref object(initializer_list_t) -- create a JSON object
12592 value from an initializer list
12593
12594 @since version 1.0.0
12595 */
array(initializer_list_t init={})12596 static basic_json array(initializer_list_t init = {})
12597 {
12598 return basic_json(init, false, value_t::array);
12599 }
12600
12601 /*!
12602 @brief explicitly create an object from an initializer list
12603
12604 Creates a JSON object value from a given initializer list. The initializer
12605 lists elements must be pairs, and their first elements must be strings. If
12606 the initializer list is empty, the empty object `{}` is created.
12607
12608 @note This function is only added for symmetry reasons. In contrast to the
12609 related function @ref array(initializer_list_t), there are
12610 no cases which can only be expressed by this function. That is, any
12611 initializer list @a init can also be passed to the initializer list
12612 constructor @ref basic_json(initializer_list_t, bool, value_t).
12613
12614 @param[in] init initializer list to create an object from (optional)
12615
12616 @return JSON object value
12617
12618 @throw type_error.301 if @a init is not a list of pairs whose first
12619 elements are strings. In this case, no object can be created. When such a
12620 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
12621 an array would have been created from the passed initializer list @a init.
12622 See example below.
12623
12624 @complexity Linear in the size of @a init.
12625
12626 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12627 changes to any JSON value.
12628
12629 @liveexample{The following code shows an example for the `object`
12630 function.,object}
12631
12632 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12633 create a JSON value from an initializer list
12634 @sa @ref array(initializer_list_t) -- create a JSON array
12635 value from an initializer list
12636
12637 @since version 1.0.0
12638 */
object(initializer_list_t init={})12639 static basic_json object(initializer_list_t init = {})
12640 {
12641 return basic_json(init, false, value_t::object);
12642 }
12643
12644 /*!
12645 @brief construct an array with count copies of given value
12646
12647 Constructs a JSON array value by creating @a cnt copies of a passed value.
12648 In case @a cnt is `0`, an empty array is created.
12649
12650 @param[in] cnt the number of JSON copies of @a val to create
12651 @param[in] val the JSON value to copy
12652
12653 @post `std::distance(begin(),end()) == cnt` holds.
12654
12655 @complexity Linear in @a cnt.
12656
12657 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12658 changes to any JSON value.
12659
12660 @liveexample{The following code shows examples for the @ref
12661 basic_json(size_type\, const basic_json&)
12662 constructor.,basic_json__size_type_basic_json}
12663
12664 @since version 1.0.0
12665 */
basic_json(size_type cnt,const basic_json & val)12666 basic_json(size_type cnt, const basic_json& val)
12667 : m_type(value_t::array)
12668 {
12669 m_value.array = create<array_t>(cnt, val);
12670 assert_invariant();
12671 }
12672
12673 /*!
12674 @brief construct a JSON container given an iterator range
12675
12676 Constructs the JSON value with the contents of the range `[first, last)`.
12677 The semantics depends on the different types a JSON value can have:
12678 - In case of a null type, invalid_iterator.206 is thrown.
12679 - In case of other primitive types (number, boolean, or string), @a first
12680 must be `begin()` and @a last must be `end()`. In this case, the value is
12681 copied. Otherwise, invalid_iterator.204 is thrown.
12682 - In case of structured types (array, object), the constructor behaves as
12683 similar versions for `std::vector` or `std::map`; that is, a JSON array
12684 or object is constructed from the values in the range.
12685
12686 @tparam InputIT an input iterator type (@ref iterator or @ref
12687 const_iterator)
12688
12689 @param[in] first begin of the range to copy from (included)
12690 @param[in] last end of the range to copy from (excluded)
12691
12692 @pre Iterators @a first and @a last must be initialized. **This
12693 precondition is enforced with an assertion (see warning).** If
12694 assertions are switched off, a violation of this precondition yields
12695 undefined behavior.
12696
12697 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
12698 checked efficiently. Only certain edge cases are detected; see the
12699 description of the exceptions below. A violation of this precondition
12700 yields undefined behavior.
12701
12702 @warning A precondition is enforced with a runtime assertion that will
12703 result in calling `std::abort` if this precondition is not met.
12704 Assertions can be disabled by defining `NDEBUG` at compile time.
12705 See https://en.cppreference.com/w/cpp/error/assert for more
12706 information.
12707
12708 @throw invalid_iterator.201 if iterators @a first and @a last are not
12709 compatible (i.e., do not belong to the same JSON value). In this case,
12710 the range `[first, last)` is undefined.
12711 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
12712 primitive type (number, boolean, or string), but @a first does not point
12713 to the first element any more. In this case, the range `[first, last)` is
12714 undefined. See example code below.
12715 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
12716 null value. In this case, the range `[first, last)` is undefined.
12717
12718 @complexity Linear in distance between @a first and @a last.
12719
12720 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12721 changes to any JSON value.
12722
12723 @liveexample{The example below shows several ways to create JSON values by
12724 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
12725
12726 @since version 1.0.0
12727 */
12728 template<class InputIT, typename std::enable_if<
12729 std::is_same<InputIT, typename basic_json_t::iterator>::value or
12730 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)12731 basic_json(InputIT first, InputIT last)
12732 {
12733 assert(first.m_object != nullptr);
12734 assert(last.m_object != nullptr);
12735
12736 // make sure iterator fits the current value
12737 if (JSON_UNLIKELY(first.m_object != last.m_object))
12738 {
12739 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
12740 }
12741
12742 // copy type from first iterator
12743 m_type = first.m_object->m_type;
12744
12745 // check if iterator range is complete for primitive values
12746 switch (m_type)
12747 {
12748 case value_t::boolean:
12749 case value_t::number_float:
12750 case value_t::number_integer:
12751 case value_t::number_unsigned:
12752 case value_t::string:
12753 {
12754 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
12755 or not last.m_it.primitive_iterator.is_end()))
12756 {
12757 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
12758 }
12759 break;
12760 }
12761
12762 default:
12763 break;
12764 }
12765
12766 switch (m_type)
12767 {
12768 case value_t::number_integer:
12769 {
12770 m_value.number_integer = first.m_object->m_value.number_integer;
12771 break;
12772 }
12773
12774 case value_t::number_unsigned:
12775 {
12776 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
12777 break;
12778 }
12779
12780 case value_t::number_float:
12781 {
12782 m_value.number_float = first.m_object->m_value.number_float;
12783 break;
12784 }
12785
12786 case value_t::boolean:
12787 {
12788 m_value.boolean = first.m_object->m_value.boolean;
12789 break;
12790 }
12791
12792 case value_t::string:
12793 {
12794 m_value = *first.m_object->m_value.string;
12795 break;
12796 }
12797
12798 case value_t::object:
12799 {
12800 m_value.object = create<object_t>(first.m_it.object_iterator,
12801 last.m_it.object_iterator);
12802 break;
12803 }
12804
12805 case value_t::array:
12806 {
12807 m_value.array = create<array_t>(first.m_it.array_iterator,
12808 last.m_it.array_iterator);
12809 break;
12810 }
12811
12812 default:
12813 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
12814 std::string(first.m_object->type_name())));
12815 }
12816
12817 assert_invariant();
12818 }
12819
12820
12821 ///////////////////////////////////////
12822 // other constructors and destructor //
12823 ///////////////////////////////////////
12824
12825 /// @private
basic_json(const detail::json_ref<basic_json> & ref)12826 basic_json(const detail::json_ref<basic_json>& ref)
12827 : basic_json(ref.moved_or_copied())
12828 {}
12829
12830 /*!
12831 @brief copy constructor
12832
12833 Creates a copy of a given JSON value.
12834
12835 @param[in] other the JSON value to copy
12836
12837 @post `*this == other`
12838
12839 @complexity Linear in the size of @a other.
12840
12841 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12842 changes to any JSON value.
12843
12844 @requirement This function helps `basic_json` satisfying the
12845 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12846 requirements:
12847 - The complexity is linear.
12848 - As postcondition, it holds: `other == basic_json(other)`.
12849
12850 @liveexample{The following code shows an example for the copy
12851 constructor.,basic_json__basic_json}
12852
12853 @since version 1.0.0
12854 */
basic_json(const basic_json & other)12855 basic_json(const basic_json& other)
12856 : m_type(other.m_type)
12857 {
12858 // check of passed value is valid
12859 other.assert_invariant();
12860
12861 switch (m_type)
12862 {
12863 case value_t::object:
12864 {
12865 m_value = *other.m_value.object;
12866 break;
12867 }
12868
12869 case value_t::array:
12870 {
12871 m_value = *other.m_value.array;
12872 break;
12873 }
12874
12875 case value_t::string:
12876 {
12877 m_value = *other.m_value.string;
12878 break;
12879 }
12880
12881 case value_t::boolean:
12882 {
12883 m_value = other.m_value.boolean;
12884 break;
12885 }
12886
12887 case value_t::number_integer:
12888 {
12889 m_value = other.m_value.number_integer;
12890 break;
12891 }
12892
12893 case value_t::number_unsigned:
12894 {
12895 m_value = other.m_value.number_unsigned;
12896 break;
12897 }
12898
12899 case value_t::number_float:
12900 {
12901 m_value = other.m_value.number_float;
12902 break;
12903 }
12904
12905 default:
12906 break;
12907 }
12908
12909 assert_invariant();
12910 }
12911
12912 /*!
12913 @brief move constructor
12914
12915 Move constructor. Constructs a JSON value with the contents of the given
12916 value @a other using move semantics. It "steals" the resources from @a
12917 other and leaves it as JSON null value.
12918
12919 @param[in,out] other value to move to this object
12920
12921 @post `*this` has the same value as @a other before the call.
12922 @post @a other is a JSON null value.
12923
12924 @complexity Constant.
12925
12926 @exceptionsafety No-throw guarantee: this constructor never throws
12927 exceptions.
12928
12929 @requirement This function helps `basic_json` satisfying the
12930 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
12931 requirements.
12932
12933 @liveexample{The code below shows the move constructor explicitly called
12934 via std::move.,basic_json__moveconstructor}
12935
12936 @since version 1.0.0
12937 */
basic_json(basic_json && other)12938 basic_json(basic_json&& other) noexcept
12939 : m_type(std::move(other.m_type)),
12940 m_value(std::move(other.m_value))
12941 {
12942 // check that passed value is valid
12943 other.assert_invariant();
12944
12945 // invalidate payload
12946 other.m_type = value_t::null;
12947 other.m_value = {};
12948
12949 assert_invariant();
12950 }
12951
12952 /*!
12953 @brief copy assignment
12954
12955 Copy assignment operator. Copies a JSON value via the "copy and swap"
12956 strategy: It is expressed in terms of the copy constructor, destructor,
12957 and the `swap()` member function.
12958
12959 @param[in] other value to copy from
12960
12961 @complexity Linear.
12962
12963 @requirement This function helps `basic_json` satisfying the
12964 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12965 requirements:
12966 - The complexity is linear.
12967
12968 @liveexample{The code below shows and example for the copy assignment. It
12969 creates a copy of value `a` which is then swapped with `b`. Finally\, the
12970 copy of `a` (which is the null value after the swap) is
12971 destroyed.,basic_json__copyassignment}
12972
12973 @since version 1.0.0
12974 */
operator =(basic_json other)12975 reference& operator=(basic_json other) noexcept (
12976 std::is_nothrow_move_constructible<value_t>::value and
12977 std::is_nothrow_move_assignable<value_t>::value and
12978 std::is_nothrow_move_constructible<json_value>::value and
12979 std::is_nothrow_move_assignable<json_value>::value
12980 )
12981 {
12982 // check that passed value is valid
12983 other.assert_invariant();
12984
12985 using std::swap;
12986 swap(m_type, other.m_type);
12987 swap(m_value, other.m_value);
12988
12989 assert_invariant();
12990 return *this;
12991 }
12992
12993 /*!
12994 @brief destructor
12995
12996 Destroys the JSON value and frees all allocated memory.
12997
12998 @complexity Linear.
12999
13000 @requirement This function helps `basic_json` satisfying the
13001 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
13002 requirements:
13003 - The complexity is linear.
13004 - All stored elements are destroyed and all memory is freed.
13005
13006 @since version 1.0.0
13007 */
~basic_json()13008 ~basic_json() noexcept
13009 {
13010 assert_invariant();
13011 m_value.destroy(m_type);
13012 }
13013
13014 /// @}
13015
13016 public:
13017 ///////////////////////
13018 // object inspection //
13019 ///////////////////////
13020
13021 /// @name object inspection
13022 /// Functions to inspect the type of a JSON value.
13023 /// @{
13024
13025 /*!
13026 @brief serialization
13027
13028 Serialization function for JSON values. The function tries to mimic
13029 Python's `json.dumps()` function, and currently supports its @a indent
13030 and @a ensure_ascii parameters.
13031
13032 @param[in] indent If indent is nonnegative, then array elements and object
13033 members will be pretty-printed with that indent level. An indent level of
13034 `0` will only insert newlines. `-1` (the default) selects the most compact
13035 representation.
13036 @param[in] indent_char The character to use for indentation if @a indent is
13037 greater than `0`. The default is ` ` (space).
13038 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
13039 in the output are escaped with `\uXXXX` sequences, and the result consists
13040 of ASCII characters only.
13041
13042 @return string containing the serialization of the JSON value
13043
13044 @throw type_error.316 if a string stored inside the JSON value is not
13045 UTF-8 encoded
13046
13047 @complexity Linear.
13048
13049 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13050 changes in the JSON value.
13051
13052 @liveexample{The following example shows the effect of different @a indent\,
13053 @a indent_char\, and @a ensure_ascii parameters to the result of the
13054 serialization.,dump}
13055
13056 @see https://docs.python.org/2/library/json.html#json.dump
13057
13058 @since version 1.0.0; indentation character @a indent_char, option
13059 @a ensure_ascii and exceptions added in version 3.0.0
13060 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false) const13061 string_t dump(const int indent = -1, const char indent_char = ' ',
13062 const bool ensure_ascii = false) const
13063 {
13064 string_t result;
13065 serializer s(detail::output_adapter<char, string_t>(result), indent_char);
13066
13067 if (indent >= 0)
13068 {
13069 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
13070 }
13071 else
13072 {
13073 s.dump(*this, false, ensure_ascii, 0);
13074 }
13075
13076 return result;
13077 }
13078
13079 /*!
13080 @brief return the type of the JSON value (explicit)
13081
13082 Return the type of the JSON value as a value from the @ref value_t
13083 enumeration.
13084
13085 @return the type of the JSON value
13086 Value type | return value
13087 ------------------------- | -------------------------
13088 null | value_t::null
13089 boolean | value_t::boolean
13090 string | value_t::string
13091 number (integer) | value_t::number_integer
13092 number (unsigned integer) | value_t::number_unsigned
13093 number (floating-point) | value_t::number_float
13094 object | value_t::object
13095 array | value_t::array
13096 discarded | value_t::discarded
13097
13098 @complexity Constant.
13099
13100 @exceptionsafety No-throw guarantee: this member function never throws
13101 exceptions.
13102
13103 @liveexample{The following code exemplifies `type()` for all JSON
13104 types.,type}
13105
13106 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
13107 @sa @ref type_name() -- return the type as string
13108
13109 @since version 1.0.0
13110 */
type() const13111 constexpr value_t type() const noexcept
13112 {
13113 return m_type;
13114 }
13115
13116 /*!
13117 @brief return whether type is primitive
13118
13119 This function returns true if and only if the JSON type is primitive
13120 (string, number, boolean, or null).
13121
13122 @return `true` if type is primitive (string, number, boolean, or null),
13123 `false` otherwise.
13124
13125 @complexity Constant.
13126
13127 @exceptionsafety No-throw guarantee: this member function never throws
13128 exceptions.
13129
13130 @liveexample{The following code exemplifies `is_primitive()` for all JSON
13131 types.,is_primitive}
13132
13133 @sa @ref is_structured() -- returns whether JSON value is structured
13134 @sa @ref is_null() -- returns whether JSON value is `null`
13135 @sa @ref is_string() -- returns whether JSON value is a string
13136 @sa @ref is_boolean() -- returns whether JSON value is a boolean
13137 @sa @ref is_number() -- returns whether JSON value is a number
13138
13139 @since version 1.0.0
13140 */
is_primitive() const13141 constexpr bool is_primitive() const noexcept
13142 {
13143 return is_null() or is_string() or is_boolean() or is_number();
13144 }
13145
13146 /*!
13147 @brief return whether type is structured
13148
13149 This function returns true if and only if the JSON type is structured
13150 (array or object).
13151
13152 @return `true` if type is structured (array or object), `false` otherwise.
13153
13154 @complexity Constant.
13155
13156 @exceptionsafety No-throw guarantee: this member function never throws
13157 exceptions.
13158
13159 @liveexample{The following code exemplifies `is_structured()` for all JSON
13160 types.,is_structured}
13161
13162 @sa @ref is_primitive() -- returns whether value is primitive
13163 @sa @ref is_array() -- returns whether value is an array
13164 @sa @ref is_object() -- returns whether value is an object
13165
13166 @since version 1.0.0
13167 */
is_structured() const13168 constexpr bool is_structured() const noexcept
13169 {
13170 return is_array() or is_object();
13171 }
13172
13173 /*!
13174 @brief return whether value is null
13175
13176 This function returns true if and only if the JSON value is null.
13177
13178 @return `true` if type is null, `false` otherwise.
13179
13180 @complexity Constant.
13181
13182 @exceptionsafety No-throw guarantee: this member function never throws
13183 exceptions.
13184
13185 @liveexample{The following code exemplifies `is_null()` for all JSON
13186 types.,is_null}
13187
13188 @since version 1.0.0
13189 */
is_null() const13190 constexpr bool is_null() const noexcept
13191 {
13192 return (m_type == value_t::null);
13193 }
13194
13195 /*!
13196 @brief return whether value is a boolean
13197
13198 This function returns true if and only if the JSON value is a boolean.
13199
13200 @return `true` if type is boolean, `false` otherwise.
13201
13202 @complexity Constant.
13203
13204 @exceptionsafety No-throw guarantee: this member function never throws
13205 exceptions.
13206
13207 @liveexample{The following code exemplifies `is_boolean()` for all JSON
13208 types.,is_boolean}
13209
13210 @since version 1.0.0
13211 */
is_boolean() const13212 constexpr bool is_boolean() const noexcept
13213 {
13214 return (m_type == value_t::boolean);
13215 }
13216
13217 /*!
13218 @brief return whether value is a number
13219
13220 This function returns true if and only if the JSON value is a number. This
13221 includes both integer (signed and unsigned) and floating-point values.
13222
13223 @return `true` if type is number (regardless whether integer, unsigned
13224 integer or floating-type), `false` otherwise.
13225
13226 @complexity Constant.
13227
13228 @exceptionsafety No-throw guarantee: this member function never throws
13229 exceptions.
13230
13231 @liveexample{The following code exemplifies `is_number()` for all JSON
13232 types.,is_number}
13233
13234 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13235 integer number
13236 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13237 number
13238 @sa @ref is_number_float() -- check if value is a floating-point number
13239
13240 @since version 1.0.0
13241 */
is_number() const13242 constexpr bool is_number() const noexcept
13243 {
13244 return is_number_integer() or is_number_float();
13245 }
13246
13247 /*!
13248 @brief return whether value is an integer number
13249
13250 This function returns true if and only if the JSON value is a signed or
13251 unsigned integer number. This excludes floating-point values.
13252
13253 @return `true` if type is an integer or unsigned integer number, `false`
13254 otherwise.
13255
13256 @complexity Constant.
13257
13258 @exceptionsafety No-throw guarantee: this member function never throws
13259 exceptions.
13260
13261 @liveexample{The following code exemplifies `is_number_integer()` for all
13262 JSON types.,is_number_integer}
13263
13264 @sa @ref is_number() -- check if value is a number
13265 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13266 number
13267 @sa @ref is_number_float() -- check if value is a floating-point number
13268
13269 @since version 1.0.0
13270 */
is_number_integer() const13271 constexpr bool is_number_integer() const noexcept
13272 {
13273 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
13274 }
13275
13276 /*!
13277 @brief return whether value is an unsigned integer number
13278
13279 This function returns true if and only if the JSON value is an unsigned
13280 integer number. This excludes floating-point and signed integer values.
13281
13282 @return `true` if type is an unsigned integer number, `false` otherwise.
13283
13284 @complexity Constant.
13285
13286 @exceptionsafety No-throw guarantee: this member function never throws
13287 exceptions.
13288
13289 @liveexample{The following code exemplifies `is_number_unsigned()` for all
13290 JSON types.,is_number_unsigned}
13291
13292 @sa @ref is_number() -- check if value is a number
13293 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13294 integer number
13295 @sa @ref is_number_float() -- check if value is a floating-point number
13296
13297 @since version 2.0.0
13298 */
is_number_unsigned() const13299 constexpr bool is_number_unsigned() const noexcept
13300 {
13301 return (m_type == value_t::number_unsigned);
13302 }
13303
13304 /*!
13305 @brief return whether value is a floating-point number
13306
13307 This function returns true if and only if the JSON value is a
13308 floating-point number. This excludes signed and unsigned integer values.
13309
13310 @return `true` if type is a floating-point number, `false` otherwise.
13311
13312 @complexity Constant.
13313
13314 @exceptionsafety No-throw guarantee: this member function never throws
13315 exceptions.
13316
13317 @liveexample{The following code exemplifies `is_number_float()` for all
13318 JSON types.,is_number_float}
13319
13320 @sa @ref is_number() -- check if value is number
13321 @sa @ref is_number_integer() -- check if value is an integer number
13322 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13323 number
13324
13325 @since version 1.0.0
13326 */
is_number_float() const13327 constexpr bool is_number_float() const noexcept
13328 {
13329 return (m_type == value_t::number_float);
13330 }
13331
13332 /*!
13333 @brief return whether value is an object
13334
13335 This function returns true if and only if the JSON value is an object.
13336
13337 @return `true` if type is object, `false` otherwise.
13338
13339 @complexity Constant.
13340
13341 @exceptionsafety No-throw guarantee: this member function never throws
13342 exceptions.
13343
13344 @liveexample{The following code exemplifies `is_object()` for all JSON
13345 types.,is_object}
13346
13347 @since version 1.0.0
13348 */
is_object() const13349 constexpr bool is_object() const noexcept
13350 {
13351 return (m_type == value_t::object);
13352 }
13353
13354 /*!
13355 @brief return whether value is an array
13356
13357 This function returns true if and only if the JSON value is an array.
13358
13359 @return `true` if type is array, `false` otherwise.
13360
13361 @complexity Constant.
13362
13363 @exceptionsafety No-throw guarantee: this member function never throws
13364 exceptions.
13365
13366 @liveexample{The following code exemplifies `is_array()` for all JSON
13367 types.,is_array}
13368
13369 @since version 1.0.0
13370 */
is_array() const13371 constexpr bool is_array() const noexcept
13372 {
13373 return (m_type == value_t::array);
13374 }
13375
13376 /*!
13377 @brief return whether value is a string
13378
13379 This function returns true if and only if the JSON value is a string.
13380
13381 @return `true` if type is string, `false` otherwise.
13382
13383 @complexity Constant.
13384
13385 @exceptionsafety No-throw guarantee: this member function never throws
13386 exceptions.
13387
13388 @liveexample{The following code exemplifies `is_string()` for all JSON
13389 types.,is_string}
13390
13391 @since version 1.0.0
13392 */
is_string() const13393 constexpr bool is_string() const noexcept
13394 {
13395 return (m_type == value_t::string);
13396 }
13397
13398 /*!
13399 @brief return whether value is discarded
13400
13401 This function returns true if and only if the JSON value was discarded
13402 during parsing with a callback function (see @ref parser_callback_t).
13403
13404 @note This function will always be `false` for JSON values after parsing.
13405 That is, discarded values can only occur during parsing, but will be
13406 removed when inside a structured value or replaced by null in other cases.
13407
13408 @return `true` if type is discarded, `false` otherwise.
13409
13410 @complexity Constant.
13411
13412 @exceptionsafety No-throw guarantee: this member function never throws
13413 exceptions.
13414
13415 @liveexample{The following code exemplifies `is_discarded()` for all JSON
13416 types.,is_discarded}
13417
13418 @since version 1.0.0
13419 */
is_discarded() const13420 constexpr bool is_discarded() const noexcept
13421 {
13422 return (m_type == value_t::discarded);
13423 }
13424
13425 /*!
13426 @brief return the type of the JSON value (implicit)
13427
13428 Implicitly return the type of the JSON value as a value from the @ref
13429 value_t enumeration.
13430
13431 @return the type of the JSON value
13432
13433 @complexity Constant.
13434
13435 @exceptionsafety No-throw guarantee: this member function never throws
13436 exceptions.
13437
13438 @liveexample{The following code exemplifies the @ref value_t operator for
13439 all JSON types.,operator__value_t}
13440
13441 @sa @ref type() -- return the type of the JSON value (explicit)
13442 @sa @ref type_name() -- return the type as string
13443
13444 @since version 1.0.0
13445 */
operator value_t() const13446 constexpr operator value_t() const noexcept
13447 {
13448 return m_type;
13449 }
13450
13451 /// @}
13452
13453 private:
13454 //////////////////
13455 // value access //
13456 //////////////////
13457
13458 /// get a boolean (explicit)
get_impl(boolean_t *) const13459 boolean_t get_impl(boolean_t* /*unused*/) const
13460 {
13461 if (JSON_LIKELY(is_boolean()))
13462 {
13463 return m_value.boolean;
13464 }
13465
13466 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
13467 }
13468
13469 /// get a pointer to the value (object)
get_impl_ptr(object_t *)13470 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
13471 {
13472 return is_object() ? m_value.object : nullptr;
13473 }
13474
13475 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const13476 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
13477 {
13478 return is_object() ? m_value.object : nullptr;
13479 }
13480
13481 /// get a pointer to the value (array)
get_impl_ptr(array_t *)13482 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
13483 {
13484 return is_array() ? m_value.array : nullptr;
13485 }
13486
13487 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const13488 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
13489 {
13490 return is_array() ? m_value.array : nullptr;
13491 }
13492
13493 /// get a pointer to the value (string)
get_impl_ptr(string_t *)13494 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
13495 {
13496 return is_string() ? m_value.string : nullptr;
13497 }
13498
13499 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const13500 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
13501 {
13502 return is_string() ? m_value.string : nullptr;
13503 }
13504
13505 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)13506 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
13507 {
13508 return is_boolean() ? &m_value.boolean : nullptr;
13509 }
13510
13511 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const13512 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
13513 {
13514 return is_boolean() ? &m_value.boolean : nullptr;
13515 }
13516
13517 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)13518 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
13519 {
13520 return is_number_integer() ? &m_value.number_integer : nullptr;
13521 }
13522
13523 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const13524 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
13525 {
13526 return is_number_integer() ? &m_value.number_integer : nullptr;
13527 }
13528
13529 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)13530 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
13531 {
13532 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13533 }
13534
13535 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const13536 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
13537 {
13538 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13539 }
13540
13541 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)13542 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
13543 {
13544 return is_number_float() ? &m_value.number_float : nullptr;
13545 }
13546
13547 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const13548 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
13549 {
13550 return is_number_float() ? &m_value.number_float : nullptr;
13551 }
13552
13553 /*!
13554 @brief helper function to implement get_ref()
13555
13556 This function helps to implement get_ref() without code duplication for
13557 const and non-const overloads
13558
13559 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
13560
13561 @throw type_error.303 if ReferenceType does not match underlying value
13562 type of the current JSON
13563 */
13564 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)13565 static ReferenceType get_ref_impl(ThisType& obj)
13566 {
13567 // delegate the call to get_ptr<>()
13568 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
13569
13570 if (JSON_LIKELY(ptr != nullptr))
13571 {
13572 return *ptr;
13573 }
13574
13575 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
13576 }
13577
13578 public:
13579 /// @name value access
13580 /// Direct access to the stored value of a JSON value.
13581 /// @{
13582
13583 /*!
13584 @brief get special-case overload
13585
13586 This overloads avoids a lot of template boilerplate, it can be seen as the
13587 identity method
13588
13589 @tparam BasicJsonType == @ref basic_json
13590
13591 @return a copy of *this
13592
13593 @complexity Constant.
13594
13595 @since version 2.1.0
13596 */
13597 template<typename BasicJsonType, detail::enable_if_t<
13598 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
13599 int> = 0>
get() const13600 basic_json get() const
13601 {
13602 return *this;
13603 }
13604
13605 /*!
13606 @brief get special-case overload
13607
13608 This overloads converts the current @ref basic_json in a different
13609 @ref basic_json type
13610
13611 @tparam BasicJsonType == @ref basic_json
13612
13613 @return a copy of *this, converted into @tparam BasicJsonType
13614
13615 @complexity Depending on the implementation of the called `from_json()`
13616 method.
13617
13618 @since version 3.2.0
13619 */
13620 template<typename BasicJsonType, detail::enable_if_t<
13621 not std::is_same<BasicJsonType, basic_json>::value and
13622 detail::is_basic_json<BasicJsonType>::value, int> = 0>
13623 BasicJsonType get() const
13624 {
13625 return *this;
13626 }
13627
13628 /*!
13629 @brief get a value (explicit)
13630
13631 Explicit type conversion between the JSON value and a compatible value
13632 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13633 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13634 The value is converted by calling the @ref json_serializer<ValueType>
13635 `from_json()` method.
13636
13637 The function is equivalent to executing
13638 @code {.cpp}
13639 ValueType ret;
13640 JSONSerializer<ValueType>::from_json(*this, ret);
13641 return ret;
13642 @endcode
13643
13644 This overloads is chosen if:
13645 - @a ValueType is not @ref basic_json,
13646 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13647 `void from_json(const basic_json&, ValueType&)`, and
13648 - @ref json_serializer<ValueType> does not have a `from_json()` method of
13649 the form `ValueType from_json(const basic_json&)`
13650
13651 @tparam ValueTypeCV the provided value type
13652 @tparam ValueType the returned value type
13653
13654 @return copy of the JSON value, converted to @a ValueType
13655
13656 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13657
13658 @liveexample{The example below shows several conversions from JSON values
13659 to other types. There a few things to note: (1) Floating-point numbers can
13660 be converted to integers\, (2) A JSON array can be converted to a standard
13661 `std::vector<short>`\, (3) A JSON object can be converted to C++
13662 associative containers such as `std::unordered_map<std::string\,
13663 json>`.,get__ValueType_const}
13664
13665 @since version 2.1.0
13666 */
13667 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13668 detail::enable_if_t <
13669 not detail::is_basic_json<ValueType>::value and
13670 detail::has_from_json<basic_json_t, ValueType>::value and
13671 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13672 int> = 0>
13673 ValueType get() const noexcept(noexcept(
13674 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
13675 {
13676 // we cannot static_assert on ValueTypeCV being non-const, because
13677 // there is support for get<const basic_json_t>(), which is why we
13678 // still need the uncvref
13679 static_assert(not std::is_reference<ValueTypeCV>::value,
13680 "get() cannot be used with reference types, you might want to use get_ref()");
13681 static_assert(std::is_default_constructible<ValueType>::value,
13682 "types must be DefaultConstructible when used with get()");
13683
13684 ValueType ret;
13685 JSONSerializer<ValueType>::from_json(*this, ret);
13686 return ret;
13687 }
13688
13689 /*!
13690 @brief get a value (explicit); special case
13691
13692 Explicit type conversion between the JSON value and a compatible value
13693 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13694 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13695 The value is converted by calling the @ref json_serializer<ValueType>
13696 `from_json()` method.
13697
13698 The function is equivalent to executing
13699 @code {.cpp}
13700 return JSONSerializer<ValueTypeCV>::from_json(*this);
13701 @endcode
13702
13703 This overloads is chosen if:
13704 - @a ValueType is not @ref basic_json and
13705 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13706 `ValueType from_json(const basic_json&)`
13707
13708 @note If @ref json_serializer<ValueType> has both overloads of
13709 `from_json()`, this one is chosen.
13710
13711 @tparam ValueTypeCV the provided value type
13712 @tparam ValueType the returned value type
13713
13714 @return copy of the JSON value, converted to @a ValueType
13715
13716 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13717
13718 @since version 2.1.0
13719 */
13720 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13721 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
13722 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13723 int> = 0>
13724 ValueType get() const noexcept(noexcept(
13725 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
13726 {
13727 static_assert(not std::is_reference<ValueTypeCV>::value,
13728 "get() cannot be used with reference types, you might want to use get_ref()");
13729 return JSONSerializer<ValueTypeCV>::from_json(*this);
13730 }
13731
13732 /*!
13733 @brief get a pointer value (explicit)
13734
13735 Explicit pointer access to the internally stored JSON value. No copies are
13736 made.
13737
13738 @warning The pointer becomes invalid if the underlying JSON object
13739 changes.
13740
13741 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13742 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13743 @ref number_unsigned_t, or @ref number_float_t.
13744
13745 @return pointer to the internally stored JSON value if the requested
13746 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13747
13748 @complexity Constant.
13749
13750 @liveexample{The example below shows how pointers to internal values of a
13751 JSON value can be requested. Note that no type conversions are made and a
13752 `nullptr` is returned if the value and the requested pointer type does not
13753 match.,get__PointerType}
13754
13755 @sa @ref get_ptr() for explicit pointer-member access
13756
13757 @since version 1.0.0
13758 */
13759 template<typename PointerType, typename std::enable_if<
13760 std::is_pointer<PointerType>::value, int>::type = 0>
13761 PointerType get() noexcept
13762 {
13763 // delegate the call to get_ptr
13764 return get_ptr<PointerType>();
13765 }
13766
13767 /*!
13768 @brief get a pointer value (explicit)
13769 @copydoc get()
13770 */
13771 template<typename PointerType, typename std::enable_if<
13772 std::is_pointer<PointerType>::value, int>::type = 0>
get() const13773 constexpr const PointerType get() const noexcept
13774 {
13775 // delegate the call to get_ptr
13776 return get_ptr<PointerType>();
13777 }
13778
13779 /*!
13780 @brief get a pointer value (implicit)
13781
13782 Implicit pointer access to the internally stored JSON value. No copies are
13783 made.
13784
13785 @warning Writing data to the pointee of the result yields an undefined
13786 state.
13787
13788 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13789 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13790 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
13791 assertion.
13792
13793 @return pointer to the internally stored JSON value if the requested
13794 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13795
13796 @complexity Constant.
13797
13798 @liveexample{The example below shows how pointers to internal values of a
13799 JSON value can be requested. Note that no type conversions are made and a
13800 `nullptr` is returned if the value and the requested pointer type does not
13801 match.,get_ptr}
13802
13803 @since version 1.0.0
13804 */
13805 template<typename PointerType, typename std::enable_if<
13806 std::is_pointer<PointerType>::value, int>::type = 0>
13807 PointerType get_ptr() noexcept
13808 {
13809 // get the type of the PointerType (remove pointer and const)
13810 using pointee_t = typename std::remove_const<typename
13811 std::remove_pointer<typename
13812 std::remove_const<PointerType>::type>::type>::type;
13813 // make sure the type matches the allowed types
13814 static_assert(
13815 std::is_same<object_t, pointee_t>::value
13816 or std::is_same<array_t, pointee_t>::value
13817 or std::is_same<string_t, pointee_t>::value
13818 or std::is_same<boolean_t, pointee_t>::value
13819 or std::is_same<number_integer_t, pointee_t>::value
13820 or std::is_same<number_unsigned_t, pointee_t>::value
13821 or std::is_same<number_float_t, pointee_t>::value
13822 , "incompatible pointer type");
13823
13824 // delegate the call to get_impl_ptr<>()
13825 return get_impl_ptr(static_cast<PointerType>(nullptr));
13826 }
13827
13828 /*!
13829 @brief get a pointer value (implicit)
13830 @copydoc get_ptr()
13831 */
13832 template<typename PointerType, typename std::enable_if<
13833 std::is_pointer<PointerType>::value and
13834 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const13835 constexpr const PointerType get_ptr() const noexcept
13836 {
13837 // get the type of the PointerType (remove pointer and const)
13838 using pointee_t = typename std::remove_const<typename
13839 std::remove_pointer<typename
13840 std::remove_const<PointerType>::type>::type>::type;
13841 // make sure the type matches the allowed types
13842 static_assert(
13843 std::is_same<object_t, pointee_t>::value
13844 or std::is_same<array_t, pointee_t>::value
13845 or std::is_same<string_t, pointee_t>::value
13846 or std::is_same<boolean_t, pointee_t>::value
13847 or std::is_same<number_integer_t, pointee_t>::value
13848 or std::is_same<number_unsigned_t, pointee_t>::value
13849 or std::is_same<number_float_t, pointee_t>::value
13850 , "incompatible pointer type");
13851
13852 // delegate the call to get_impl_ptr<>() const
13853 return get_impl_ptr(static_cast<PointerType>(nullptr));
13854 }
13855
13856 /*!
13857 @brief get a reference value (implicit)
13858
13859 Implicit reference access to the internally stored JSON value. No copies
13860 are made.
13861
13862 @warning Writing data to the referee of the result yields an undefined
13863 state.
13864
13865 @tparam ReferenceType reference type; must be a reference to @ref array_t,
13866 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
13867 @ref number_float_t. Enforced by static assertion.
13868
13869 @return reference to the internally stored JSON value if the requested
13870 reference type @a ReferenceType fits to the JSON value; throws
13871 type_error.303 otherwise
13872
13873 @throw type_error.303 in case passed type @a ReferenceType is incompatible
13874 with the stored JSON value; see example below
13875
13876 @complexity Constant.
13877
13878 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
13879
13880 @since version 1.1.0
13881 */
13882 template<typename ReferenceType, typename std::enable_if<
13883 std::is_reference<ReferenceType>::value, int>::type = 0>
13884 ReferenceType get_ref()
13885 {
13886 // delegate call to get_ref_impl
13887 return get_ref_impl<ReferenceType>(*this);
13888 }
13889
13890 /*!
13891 @brief get a reference value (implicit)
13892 @copydoc get_ref()
13893 */
13894 template<typename ReferenceType, typename std::enable_if<
13895 std::is_reference<ReferenceType>::value and
13896 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
13897 ReferenceType get_ref() const
13898 {
13899 // delegate call to get_ref_impl
13900 return get_ref_impl<ReferenceType>(*this);
13901 }
13902
13903 /*!
13904 @brief get a value (implicit)
13905
13906 Implicit type conversion between the JSON value and a compatible value.
13907 The call is realized by calling @ref get() const.
13908
13909 @tparam ValueType non-pointer type compatible to the JSON value, for
13910 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
13911 `std::vector` types for JSON arrays. The character type of @ref string_t
13912 as well as an initializer list of this type is excluded to avoid
13913 ambiguities as these types implicitly convert to `std::string`.
13914
13915 @return copy of the JSON value, converted to type @a ValueType
13916
13917 @throw type_error.302 in case passed type @a ValueType is incompatible
13918 to the JSON value type (e.g., the JSON value is of type boolean, but a
13919 string is requested); see example below
13920
13921 @complexity Linear in the size of the JSON value.
13922
13923 @liveexample{The example below shows several conversions from JSON values
13924 to other types. There a few things to note: (1) Floating-point numbers can
13925 be converted to integers\, (2) A JSON array can be converted to a standard
13926 `std::vector<short>`\, (3) A JSON object can be converted to C++
13927 associative containers such as `std::unordered_map<std::string\,
13928 json>`.,operator__ValueType}
13929
13930 @since version 1.0.0
13931 */
13932 template < typename ValueType, typename std::enable_if <
13933 not std::is_pointer<ValueType>::value and
13934 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
13935 not std::is_same<ValueType, typename string_t::value_type>::value and
13936 not detail::is_basic_json<ValueType>::value
13937 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
13938 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
13939 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
13940 and not std::is_same<ValueType, typename std::string_view>::value
13941 #endif
13942 #endif
13943 , int >::type = 0 >
operator ValueType() const13944 operator ValueType() const
13945 {
13946 // delegate the call to get<>() const
13947 return get<ValueType>();
13948 }
13949
13950 /// @}
13951
13952
13953 ////////////////////
13954 // element access //
13955 ////////////////////
13956
13957 /// @name element access
13958 /// Access to the JSON value.
13959 /// @{
13960
13961 /*!
13962 @brief access specified array element with bounds checking
13963
13964 Returns a reference to the element at specified location @a idx, with
13965 bounds checking.
13966
13967 @param[in] idx index of the element to access
13968
13969 @return reference to the element at index @a idx
13970
13971 @throw type_error.304 if the JSON value is not an array; in this case,
13972 calling `at` with an index makes no sense. See example below.
13973 @throw out_of_range.401 if the index @a idx is out of range of the array;
13974 that is, `idx >= size()`. See example below.
13975
13976 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13977 changes in the JSON value.
13978
13979 @complexity Constant.
13980
13981 @since version 1.0.0
13982
13983 @liveexample{The example below shows how array elements can be read and
13984 written using `at()`. It also demonstrates the different exceptions that
13985 can be thrown.,at__size_type}
13986 */
at(size_type idx)13987 reference at(size_type idx)
13988 {
13989 // at only works for arrays
13990 if (JSON_LIKELY(is_array()))
13991 {
13992 JSON_TRY
13993 {
13994 return m_value.array->at(idx);
13995 }
13996 JSON_CATCH (std::out_of_range&)
13997 {
13998 // create better exception explanation
13999 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14000 }
14001 }
14002 else
14003 {
14004 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14005 }
14006 }
14007
14008 /*!
14009 @brief access specified array element with bounds checking
14010
14011 Returns a const reference to the element at specified location @a idx,
14012 with bounds checking.
14013
14014 @param[in] idx index of the element to access
14015
14016 @return const reference to the element at index @a idx
14017
14018 @throw type_error.304 if the JSON value is not an array; in this case,
14019 calling `at` with an index makes no sense. See example below.
14020 @throw out_of_range.401 if the index @a idx is out of range of the array;
14021 that is, `idx >= size()`. See example below.
14022
14023 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14024 changes in the JSON value.
14025
14026 @complexity Constant.
14027
14028 @since version 1.0.0
14029
14030 @liveexample{The example below shows how array elements can be read using
14031 `at()`. It also demonstrates the different exceptions that can be thrown.,
14032 at__size_type_const}
14033 */
at(size_type idx) const14034 const_reference at(size_type idx) const
14035 {
14036 // at only works for arrays
14037 if (JSON_LIKELY(is_array()))
14038 {
14039 JSON_TRY
14040 {
14041 return m_value.array->at(idx);
14042 }
14043 JSON_CATCH (std::out_of_range&)
14044 {
14045 // create better exception explanation
14046 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14047 }
14048 }
14049 else
14050 {
14051 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14052 }
14053 }
14054
14055 /*!
14056 @brief access specified object element with bounds checking
14057
14058 Returns a reference to the element at with specified key @a key, with
14059 bounds checking.
14060
14061 @param[in] key key of the element to access
14062
14063 @return reference to the element at key @a key
14064
14065 @throw type_error.304 if the JSON value is not an object; in this case,
14066 calling `at` with a key makes no sense. See example below.
14067 @throw out_of_range.403 if the key @a key is is not stored in the object;
14068 that is, `find(key) == end()`. See example below.
14069
14070 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14071 changes in the JSON value.
14072
14073 @complexity Logarithmic in the size of the container.
14074
14075 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14076 access by reference
14077 @sa @ref value() for access by value with a default value
14078
14079 @since version 1.0.0
14080
14081 @liveexample{The example below shows how object elements can be read and
14082 written using `at()`. It also demonstrates the different exceptions that
14083 can be thrown.,at__object_t_key_type}
14084 */
at(const typename object_t::key_type & key)14085 reference at(const typename object_t::key_type& key)
14086 {
14087 // at only works for objects
14088 if (JSON_LIKELY(is_object()))
14089 {
14090 JSON_TRY
14091 {
14092 return m_value.object->at(key);
14093 }
14094 JSON_CATCH (std::out_of_range&)
14095 {
14096 // create better exception explanation
14097 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14098 }
14099 }
14100 else
14101 {
14102 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14103 }
14104 }
14105
14106 /*!
14107 @brief access specified object element with bounds checking
14108
14109 Returns a const reference to the element at with specified key @a key,
14110 with bounds checking.
14111
14112 @param[in] key key of the element to access
14113
14114 @return const reference to the element at key @a key
14115
14116 @throw type_error.304 if the JSON value is not an object; in this case,
14117 calling `at` with a key makes no sense. See example below.
14118 @throw out_of_range.403 if the key @a key is is not stored in the object;
14119 that is, `find(key) == end()`. See example below.
14120
14121 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14122 changes in the JSON value.
14123
14124 @complexity Logarithmic in the size of the container.
14125
14126 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14127 access by reference
14128 @sa @ref value() for access by value with a default value
14129
14130 @since version 1.0.0
14131
14132 @liveexample{The example below shows how object elements can be read using
14133 `at()`. It also demonstrates the different exceptions that can be thrown.,
14134 at__object_t_key_type_const}
14135 */
at(const typename object_t::key_type & key) const14136 const_reference at(const typename object_t::key_type& key) const
14137 {
14138 // at only works for objects
14139 if (JSON_LIKELY(is_object()))
14140 {
14141 JSON_TRY
14142 {
14143 return m_value.object->at(key);
14144 }
14145 JSON_CATCH (std::out_of_range&)
14146 {
14147 // create better exception explanation
14148 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14149 }
14150 }
14151 else
14152 {
14153 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14154 }
14155 }
14156
14157 /*!
14158 @brief access specified array element
14159
14160 Returns a reference to the element at specified location @a idx.
14161
14162 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
14163 then the array is silently filled up with `null` values to make `idx` a
14164 valid reference to the last stored element.
14165
14166 @param[in] idx index of the element to access
14167
14168 @return reference to the element at index @a idx
14169
14170 @throw type_error.305 if the JSON value is not an array or null; in that
14171 cases, using the [] operator with an index makes no sense.
14172
14173 @complexity Constant if @a idx is in the range of the array. Otherwise
14174 linear in `idx - size()`.
14175
14176 @liveexample{The example below shows how array elements can be read and
14177 written using `[]` operator. Note the addition of `null`
14178 values.,operatorarray__size_type}
14179
14180 @since version 1.0.0
14181 */
operator [](size_type idx)14182 reference operator[](size_type idx)
14183 {
14184 // implicitly convert null value to an empty array
14185 if (is_null())
14186 {
14187 m_type = value_t::array;
14188 m_value.array = create<array_t>();
14189 assert_invariant();
14190 }
14191
14192 // operator[] only works for arrays
14193 if (JSON_LIKELY(is_array()))
14194 {
14195 // fill up array with null values if given idx is outside range
14196 if (idx >= m_value.array->size())
14197 {
14198 m_value.array->insert(m_value.array->end(),
14199 idx - m_value.array->size() + 1,
14200 basic_json());
14201 }
14202
14203 return m_value.array->operator[](idx);
14204 }
14205
14206 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14207 }
14208
14209 /*!
14210 @brief access specified array element
14211
14212 Returns a const reference to the element at specified location @a idx.
14213
14214 @param[in] idx index of the element to access
14215
14216 @return const reference to the element at index @a idx
14217
14218 @throw type_error.305 if the JSON value is not an array; in that case,
14219 using the [] operator with an index makes no sense.
14220
14221 @complexity Constant.
14222
14223 @liveexample{The example below shows how array elements can be read using
14224 the `[]` operator.,operatorarray__size_type_const}
14225
14226 @since version 1.0.0
14227 */
operator [](size_type idx) const14228 const_reference operator[](size_type idx) const
14229 {
14230 // const operator[] only works for arrays
14231 if (JSON_LIKELY(is_array()))
14232 {
14233 return at(idx);
14234 // return m_value.array->operator[](idx);
14235 }
14236
14237 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14238 }
14239
14240 /*!
14241 @brief access specified object element
14242
14243 Returns a reference to the element at with specified key @a key.
14244
14245 @note If @a key is not found in the object, then it is silently added to
14246 the object and filled with a `null` value to make `key` a valid reference.
14247 In case the value was `null` before, it is converted to an object.
14248
14249 @param[in] key key of the element to access
14250
14251 @return reference to the element at key @a key
14252
14253 @throw type_error.305 if the JSON value is not an object or null; in that
14254 cases, using the [] operator with a key makes no sense.
14255
14256 @complexity Logarithmic in the size of the container.
14257
14258 @liveexample{The example below shows how object elements can be read and
14259 written using the `[]` operator.,operatorarray__key_type}
14260
14261 @sa @ref at(const typename object_t::key_type&) for access by reference
14262 with range checking
14263 @sa @ref value() for access by value with a default value
14264
14265 @since version 1.0.0
14266 */
operator [](const typename object_t::key_type & key)14267 reference operator[](const typename object_t::key_type& key)
14268 {
14269 // implicitly convert null value to an empty object
14270 if (is_null())
14271 {
14272 m_type = value_t::object;
14273 m_value.object = create<object_t>();
14274 assert_invariant();
14275 }
14276
14277 // operator[] only works for objects
14278 if (JSON_LIKELY(is_object()))
14279 {
14280 return m_value.object->operator[](key);
14281 }
14282
14283 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14284 }
14285
14286 /*!
14287 @brief read-only access specified object element
14288
14289 Returns a const reference to the element at with specified key @a key. No
14290 bounds checking is performed.
14291
14292 @warning If the element with key @a key does not exist, the behavior is
14293 undefined.
14294
14295 @param[in] key key of the element to access
14296
14297 @return const reference to the element at key @a key
14298
14299 @pre The element with key @a key must exist. **This precondition is
14300 enforced with an assertion.**
14301
14302 @throw type_error.305 if the JSON value is not an object; in that case,
14303 using the [] operator with a key makes no sense.
14304
14305 @complexity Logarithmic in the size of the container.
14306
14307 @liveexample{The example below shows how object elements can be read using
14308 the `[]` operator.,operatorarray__key_type_const}
14309
14310 @sa @ref at(const typename object_t::key_type&) for access by reference
14311 with range checking
14312 @sa @ref value() for access by value with a default value
14313
14314 @since version 1.0.0
14315 */
operator [](const typename object_t::key_type & key) const14316 const_reference operator[](const typename object_t::key_type& key) const
14317 {
14318 // const operator[] only works for objects
14319 if (JSON_LIKELY(is_object()))
14320 {
14321 return at(key);
14322 // assert(m_value.object->find(key) != m_value.object->end());
14323 // return m_value.object->find(key)->second;
14324 }
14325
14326 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14327 }
14328
14329 /*!
14330 @brief access specified object element
14331
14332 Returns a reference to the element at with specified key @a key.
14333
14334 @note If @a key is not found in the object, then it is silently added to
14335 the object and filled with a `null` value to make `key` a valid reference.
14336 In case the value was `null` before, it is converted to an object.
14337
14338 @param[in] key key of the element to access
14339
14340 @return reference to the element at key @a key
14341
14342 @throw type_error.305 if the JSON value is not an object or null; in that
14343 cases, using the [] operator with a key makes no sense.
14344
14345 @complexity Logarithmic in the size of the container.
14346
14347 @liveexample{The example below shows how object elements can be read and
14348 written using the `[]` operator.,operatorarray__key_type}
14349
14350 @sa @ref at(const typename object_t::key_type&) for access by reference
14351 with range checking
14352 @sa @ref value() for access by value with a default value
14353
14354 @since version 1.1.0
14355 */
14356 template<typename T>
operator [](T * key)14357 reference operator[](T* key)
14358 {
14359 // implicitly convert null to object
14360 if (is_null())
14361 {
14362 m_type = value_t::object;
14363 m_value = value_t::object;
14364 assert_invariant();
14365 }
14366
14367 // at only works for objects
14368 if (JSON_LIKELY(is_object()))
14369 {
14370 return m_value.object->operator[](key);
14371 }
14372
14373 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14374 }
14375
14376 /*!
14377 @brief read-only access specified object element
14378
14379 Returns a const reference to the element at with specified key @a key. No
14380 bounds checking is performed.
14381
14382 @warning If the element with key @a key does not exist, the behavior is
14383 undefined.
14384
14385 @param[in] key key of the element to access
14386
14387 @return const reference to the element at key @a key
14388
14389 @pre The element with key @a key must exist. **This precondition is
14390 enforced with an assertion.**
14391
14392 @throw type_error.305 if the JSON value is not an object; in that case,
14393 using the [] operator with a key makes no sense.
14394
14395 @complexity Logarithmic in the size of the container.
14396
14397 @liveexample{The example below shows how object elements can be read using
14398 the `[]` operator.,operatorarray__key_type_const}
14399
14400 @sa @ref at(const typename object_t::key_type&) for access by reference
14401 with range checking
14402 @sa @ref value() for access by value with a default value
14403
14404 @since version 1.1.0
14405 */
14406 template<typename T>
operator [](T * key) const14407 const_reference operator[](T* key) const
14408 {
14409 // at only works for objects
14410 if (JSON_LIKELY(is_object()))
14411 {
14412 assert(m_value.object->find(key) != m_value.object->end());
14413 return m_value.object->find(key)->second;
14414 }
14415
14416 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
14417 }
14418
14419 /*!
14420 @brief access specified object element with default value
14421
14422 Returns either a copy of an object's element at the specified key @a key
14423 or a given default value if no element with key @a key exists.
14424
14425 The function is basically equivalent to executing
14426 @code {.cpp}
14427 try {
14428 return at(key);
14429 } catch(out_of_range) {
14430 return default_value;
14431 }
14432 @endcode
14433
14434 @note Unlike @ref at(const typename object_t::key_type&), this function
14435 does not throw if the given key @a key was not found.
14436
14437 @note Unlike @ref operator[](const typename object_t::key_type& key), this
14438 function does not implicitly add an element to the position defined by @a
14439 key. This function is furthermore also applicable to const objects.
14440
14441 @param[in] key key of the element to access
14442 @param[in] default_value the value to return if @a key is not found
14443
14444 @tparam ValueType type compatible to JSON values, for instance `int` for
14445 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14446 JSON arrays. Note the type of the expected value at @a key and the default
14447 value @a default_value must be compatible.
14448
14449 @return copy of the element at key @a key or @a default_value if @a key
14450 is not found
14451
14452 @throw type_error.306 if the JSON value is not an object; in that case,
14453 using `value()` with a key makes no sense.
14454
14455 @complexity Logarithmic in the size of the container.
14456
14457 @liveexample{The example below shows how object elements can be queried
14458 with a default value.,basic_json__value}
14459
14460 @sa @ref at(const typename object_t::key_type&) for access by reference
14461 with range checking
14462 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14463 access by reference
14464
14465 @since version 1.0.0
14466 */
14467 template<class ValueType, typename std::enable_if<
14468 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14469 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
14470 {
14471 // at only works for objects
14472 if (JSON_LIKELY(is_object()))
14473 {
14474 // if key is found, return value and given default value otherwise
14475 const auto it = find(key);
14476 if (it != end())
14477 {
14478 return *it;
14479 }
14480
14481 return default_value;
14482 }
14483
14484 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14485 }
14486
14487 /*!
14488 @brief overload for a default value of type const char*
14489 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
14490 */
value(const typename object_t::key_type & key,const char * default_value) const14491 string_t value(const typename object_t::key_type& key, const char* default_value) const
14492 {
14493 return value(key, string_t(default_value));
14494 }
14495
14496 /*!
14497 @brief access specified object element via JSON Pointer with default value
14498
14499 Returns either a copy of an object's element at the specified key @a key
14500 or a given default value if no element with key @a key exists.
14501
14502 The function is basically equivalent to executing
14503 @code {.cpp}
14504 try {
14505 return at(ptr);
14506 } catch(out_of_range) {
14507 return default_value;
14508 }
14509 @endcode
14510
14511 @note Unlike @ref at(const json_pointer&), this function does not throw
14512 if the given key @a key was not found.
14513
14514 @param[in] ptr a JSON pointer to the element to access
14515 @param[in] default_value the value to return if @a ptr found no value
14516
14517 @tparam ValueType type compatible to JSON values, for instance `int` for
14518 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14519 JSON arrays. Note the type of the expected value at @a key and the default
14520 value @a default_value must be compatible.
14521
14522 @return copy of the element at key @a key or @a default_value if @a key
14523 is not found
14524
14525 @throw type_error.306 if the JSON value is not an object; in that case,
14526 using `value()` with a key makes no sense.
14527
14528 @complexity Logarithmic in the size of the container.
14529
14530 @liveexample{The example below shows how object elements can be queried
14531 with a default value.,basic_json__value_ptr}
14532
14533 @sa @ref operator[](const json_pointer&) for unchecked access by reference
14534
14535 @since version 2.0.2
14536 */
14537 template<class ValueType, typename std::enable_if<
14538 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14539 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
14540 {
14541 // at only works for objects
14542 if (JSON_LIKELY(is_object()))
14543 {
14544 // if pointer resolves a value, return it or use default value
14545 JSON_TRY
14546 {
14547 return ptr.get_checked(this);
14548 }
14549 JSON_INTERNAL_CATCH (out_of_range&)
14550 {
14551 return default_value;
14552 }
14553 }
14554
14555 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14556 }
14557
14558 /*!
14559 @brief overload for a default value of type const char*
14560 @copydoc basic_json::value(const json_pointer&, ValueType) const
14561 */
value(const json_pointer & ptr,const char * default_value) const14562 string_t value(const json_pointer& ptr, const char* default_value) const
14563 {
14564 return value(ptr, string_t(default_value));
14565 }
14566
14567 /*!
14568 @brief access the first element
14569
14570 Returns a reference to the first element in the container. For a JSON
14571 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
14572
14573 @return In case of a structured type (array or object), a reference to the
14574 first element is returned. In case of number, string, or boolean values, a
14575 reference to the value is returned.
14576
14577 @complexity Constant.
14578
14579 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14580 or an empty array or object (undefined behavior, **guarded by
14581 assertions**).
14582 @post The JSON value remains unchanged.
14583
14584 @throw invalid_iterator.214 when called on `null` value
14585
14586 @liveexample{The following code shows an example for `front()`.,front}
14587
14588 @sa @ref back() -- access the last element
14589
14590 @since version 1.0.0
14591 */
front()14592 reference front()
14593 {
14594 return *begin();
14595 }
14596
14597 /*!
14598 @copydoc basic_json::front()
14599 */
front() const14600 const_reference front() const
14601 {
14602 return *cbegin();
14603 }
14604
14605 /*!
14606 @brief access the last element
14607
14608 Returns a reference to the last element in the container. For a JSON
14609 container `c`, the expression `c.back()` is equivalent to
14610 @code {.cpp}
14611 auto tmp = c.end();
14612 --tmp;
14613 return *tmp;
14614 @endcode
14615
14616 @return In case of a structured type (array or object), a reference to the
14617 last element is returned. In case of number, string, or boolean values, a
14618 reference to the value is returned.
14619
14620 @complexity Constant.
14621
14622 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14623 or an empty array or object (undefined behavior, **guarded by
14624 assertions**).
14625 @post The JSON value remains unchanged.
14626
14627 @throw invalid_iterator.214 when called on a `null` value. See example
14628 below.
14629
14630 @liveexample{The following code shows an example for `back()`.,back}
14631
14632 @sa @ref front() -- access the first element
14633
14634 @since version 1.0.0
14635 */
back()14636 reference back()
14637 {
14638 auto tmp = end();
14639 --tmp;
14640 return *tmp;
14641 }
14642
14643 /*!
14644 @copydoc basic_json::back()
14645 */
back() const14646 const_reference back() const
14647 {
14648 auto tmp = cend();
14649 --tmp;
14650 return *tmp;
14651 }
14652
14653 /*!
14654 @brief remove element given an iterator
14655
14656 Removes the element specified by iterator @a pos. The iterator @a pos must
14657 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
14658 but is not dereferenceable) cannot be used as a value for @a pos.
14659
14660 If called on a primitive type other than `null`, the resulting JSON value
14661 will be `null`.
14662
14663 @param[in] pos iterator to the element to remove
14664 @return Iterator following the last removed element. If the iterator @a
14665 pos refers to the last element, the `end()` iterator is returned.
14666
14667 @tparam IteratorType an @ref iterator or @ref const_iterator
14668
14669 @post Invalidates iterators and references at or after the point of the
14670 erase, including the `end()` iterator.
14671
14672 @throw type_error.307 if called on a `null` value; example: `"cannot use
14673 erase() with null"`
14674 @throw invalid_iterator.202 if called on an iterator which does not belong
14675 to the current JSON value; example: `"iterator does not fit current
14676 value"`
14677 @throw invalid_iterator.205 if called on a primitive type with invalid
14678 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
14679 out of range"`
14680
14681 @complexity The complexity depends on the type:
14682 - objects: amortized constant
14683 - arrays: linear in distance between @a pos and the end of the container
14684 - strings: linear in the length of the string
14685 - other types: constant
14686
14687 @liveexample{The example shows the result of `erase()` for different JSON
14688 types.,erase__IteratorType}
14689
14690 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14691 the given range
14692 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14693 from an object at the given key
14694 @sa @ref erase(const size_type) -- removes the element from an array at
14695 the given index
14696
14697 @since version 1.0.0
14698 */
14699 template<class IteratorType, typename std::enable_if<
14700 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14701 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14702 = 0>
14703 IteratorType erase(IteratorType pos)
14704 {
14705 // make sure iterator fits the current value
14706 if (JSON_UNLIKELY(this != pos.m_object))
14707 {
14708 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14709 }
14710
14711 IteratorType result = end();
14712
14713 switch (m_type)
14714 {
14715 case value_t::boolean:
14716 case value_t::number_float:
14717 case value_t::number_integer:
14718 case value_t::number_unsigned:
14719 case value_t::string:
14720 {
14721 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
14722 {
14723 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
14724 }
14725
14726 if (is_string())
14727 {
14728 AllocatorType<string_t> alloc;
14729 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14730 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14731 m_value.string = nullptr;
14732 }
14733
14734 m_type = value_t::null;
14735 assert_invariant();
14736 break;
14737 }
14738
14739 case value_t::object:
14740 {
14741 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
14742 break;
14743 }
14744
14745 case value_t::array:
14746 {
14747 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
14748 break;
14749 }
14750
14751 default:
14752 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14753 }
14754
14755 return result;
14756 }
14757
14758 /*!
14759 @brief remove elements given an iterator range
14760
14761 Removes the element specified by the range `[first; last)`. The iterator
14762 @a first does not need to be dereferenceable if `first == last`: erasing
14763 an empty range is a no-op.
14764
14765 If called on a primitive type other than `null`, the resulting JSON value
14766 will be `null`.
14767
14768 @param[in] first iterator to the beginning of the range to remove
14769 @param[in] last iterator past the end of the range to remove
14770 @return Iterator following the last removed element. If the iterator @a
14771 second refers to the last element, the `end()` iterator is returned.
14772
14773 @tparam IteratorType an @ref iterator or @ref const_iterator
14774
14775 @post Invalidates iterators and references at or after the point of the
14776 erase, including the `end()` iterator.
14777
14778 @throw type_error.307 if called on a `null` value; example: `"cannot use
14779 erase() with null"`
14780 @throw invalid_iterator.203 if called on iterators which does not belong
14781 to the current JSON value; example: `"iterators do not fit current value"`
14782 @throw invalid_iterator.204 if called on a primitive type with invalid
14783 iterators (i.e., if `first != begin()` and `last != end()`); example:
14784 `"iterators out of range"`
14785
14786 @complexity The complexity depends on the type:
14787 - objects: `log(size()) + std::distance(first, last)`
14788 - arrays: linear in the distance between @a first and @a last, plus linear
14789 in the distance between @a last and end of the container
14790 - strings: linear in the length of the string
14791 - other types: constant
14792
14793 @liveexample{The example shows the result of `erase()` for different JSON
14794 types.,erase__IteratorType_IteratorType}
14795
14796 @sa @ref erase(IteratorType) -- removes the element at a given position
14797 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14798 from an object at the given key
14799 @sa @ref erase(const size_type) -- removes the element from an array at
14800 the given index
14801
14802 @since version 1.0.0
14803 */
14804 template<class IteratorType, typename std::enable_if<
14805 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14806 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14807 = 0>
14808 IteratorType erase(IteratorType first, IteratorType last)
14809 {
14810 // make sure iterator fits the current value
14811 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
14812 {
14813 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
14814 }
14815
14816 IteratorType result = end();
14817
14818 switch (m_type)
14819 {
14820 case value_t::boolean:
14821 case value_t::number_float:
14822 case value_t::number_integer:
14823 case value_t::number_unsigned:
14824 case value_t::string:
14825 {
14826 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
14827 or not last.m_it.primitive_iterator.is_end()))
14828 {
14829 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14830 }
14831
14832 if (is_string())
14833 {
14834 AllocatorType<string_t> alloc;
14835 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14836 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14837 m_value.string = nullptr;
14838 }
14839
14840 m_type = value_t::null;
14841 assert_invariant();
14842 break;
14843 }
14844
14845 case value_t::object:
14846 {
14847 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
14848 last.m_it.object_iterator);
14849 break;
14850 }
14851
14852 case value_t::array:
14853 {
14854 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
14855 last.m_it.array_iterator);
14856 break;
14857 }
14858
14859 default:
14860 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14861 }
14862
14863 return result;
14864 }
14865
14866 /*!
14867 @brief remove element from a JSON object given a key
14868
14869 Removes elements from a JSON object with the key value @a key.
14870
14871 @param[in] key value of the elements to remove
14872
14873 @return Number of elements removed. If @a ObjectType is the default
14874 `std::map` type, the return value will always be `0` (@a key was not
14875 found) or `1` (@a key was found).
14876
14877 @post References and iterators to the erased elements are invalidated.
14878 Other references and iterators are not affected.
14879
14880 @throw type_error.307 when called on a type other than JSON object;
14881 example: `"cannot use erase() with null"`
14882
14883 @complexity `log(size()) + count(key)`
14884
14885 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
14886
14887 @sa @ref erase(IteratorType) -- removes the element at a given position
14888 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14889 the given range
14890 @sa @ref erase(const size_type) -- removes the element from an array at
14891 the given index
14892
14893 @since version 1.0.0
14894 */
erase(const typename object_t::key_type & key)14895 size_type erase(const typename object_t::key_type& key)
14896 {
14897 // this erase only works for objects
14898 if (JSON_LIKELY(is_object()))
14899 {
14900 return m_value.object->erase(key);
14901 }
14902
14903 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14904 }
14905
14906 /*!
14907 @brief remove element from a JSON array given an index
14908
14909 Removes element from a JSON array at the index @a idx.
14910
14911 @param[in] idx index of the element to remove
14912
14913 @throw type_error.307 when called on a type other than JSON object;
14914 example: `"cannot use erase() with null"`
14915 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
14916 is out of range"`
14917
14918 @complexity Linear in distance between @a idx and the end of the container.
14919
14920 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
14921
14922 @sa @ref erase(IteratorType) -- removes the element at a given position
14923 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14924 the given range
14925 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14926 from an object at the given key
14927
14928 @since version 1.0.0
14929 */
erase(const size_type idx)14930 void erase(const size_type idx)
14931 {
14932 // this erase only works for arrays
14933 if (JSON_LIKELY(is_array()))
14934 {
14935 if (JSON_UNLIKELY(idx >= size()))
14936 {
14937 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14938 }
14939
14940 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
14941 }
14942 else
14943 {
14944 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14945 }
14946 }
14947
14948 /// @}
14949
14950
14951 ////////////
14952 // lookup //
14953 ////////////
14954
14955 /// @name lookup
14956 /// @{
14957
14958 /*!
14959 @brief find an element in a JSON object
14960
14961 Finds an element in a JSON object with key equivalent to @a key. If the
14962 element is not found or the JSON value is not an object, end() is
14963 returned.
14964
14965 @note This method always returns @ref end() when executed on a JSON type
14966 that is not an object.
14967
14968 @param[in] key key value of the element to search for.
14969
14970 @return Iterator to an element with key equivalent to @a key. If no such
14971 element is found or the JSON value is not an object, past-the-end (see
14972 @ref end()) iterator is returned.
14973
14974 @complexity Logarithmic in the size of the JSON object.
14975
14976 @liveexample{The example shows how `find()` is used.,find__key_type}
14977
14978 @since version 1.0.0
14979 */
14980 template<typename KeyT>
find(KeyT && key)14981 iterator find(KeyT&& key)
14982 {
14983 auto result = end();
14984
14985 if (is_object())
14986 {
14987 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
14988 }
14989
14990 return result;
14991 }
14992
14993 /*!
14994 @brief find an element in a JSON object
14995 @copydoc find(KeyT&&)
14996 */
14997 template<typename KeyT>
find(KeyT && key) const14998 const_iterator find(KeyT&& key) const
14999 {
15000 auto result = cend();
15001
15002 if (is_object())
15003 {
15004 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
15005 }
15006
15007 return result;
15008 }
15009
15010 /*!
15011 @brief returns the number of occurrences of a key in a JSON object
15012
15013 Returns the number of elements with key @a key. If ObjectType is the
15014 default `std::map` type, the return value will always be `0` (@a key was
15015 not found) or `1` (@a key was found).
15016
15017 @note This method always returns `0` when executed on a JSON type that is
15018 not an object.
15019
15020 @param[in] key key value of the element to count
15021
15022 @return Number of elements with key @a key. If the JSON value is not an
15023 object, the return value will be `0`.
15024
15025 @complexity Logarithmic in the size of the JSON object.
15026
15027 @liveexample{The example shows how `count()` is used.,count}
15028
15029 @since version 1.0.0
15030 */
15031 template<typename KeyT>
count(KeyT && key) const15032 size_type count(KeyT&& key) const
15033 {
15034 // return 0 for all nonobject types
15035 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
15036 }
15037
15038 /// @}
15039
15040
15041 ///////////////
15042 // iterators //
15043 ///////////////
15044
15045 /// @name iterators
15046 /// @{
15047
15048 /*!
15049 @brief returns an iterator to the first element
15050
15051 Returns an iterator to the first element.
15052
15053 @image html range-begin-end.svg "Illustration from cppreference.com"
15054
15055 @return iterator to the first element
15056
15057 @complexity Constant.
15058
15059 @requirement This function helps `basic_json` satisfying the
15060 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15061 requirements:
15062 - The complexity is constant.
15063
15064 @liveexample{The following code shows an example for `begin()`.,begin}
15065
15066 @sa @ref cbegin() -- returns a const iterator to the beginning
15067 @sa @ref end() -- returns an iterator to the end
15068 @sa @ref cend() -- returns a const iterator to the end
15069
15070 @since version 1.0.0
15071 */
begin()15072 iterator begin() noexcept
15073 {
15074 iterator result(this);
15075 result.set_begin();
15076 return result;
15077 }
15078
15079 /*!
15080 @copydoc basic_json::cbegin()
15081 */
begin() const15082 const_iterator begin() const noexcept
15083 {
15084 return cbegin();
15085 }
15086
15087 /*!
15088 @brief returns a const iterator to the first element
15089
15090 Returns a const iterator to the first element.
15091
15092 @image html range-begin-end.svg "Illustration from cppreference.com"
15093
15094 @return const iterator to the first element
15095
15096 @complexity Constant.
15097
15098 @requirement This function helps `basic_json` satisfying the
15099 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15100 requirements:
15101 - The complexity is constant.
15102 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
15103
15104 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
15105
15106 @sa @ref begin() -- returns an iterator to the beginning
15107 @sa @ref end() -- returns an iterator to the end
15108 @sa @ref cend() -- returns a const iterator to the end
15109
15110 @since version 1.0.0
15111 */
cbegin() const15112 const_iterator cbegin() const noexcept
15113 {
15114 const_iterator result(this);
15115 result.set_begin();
15116 return result;
15117 }
15118
15119 /*!
15120 @brief returns an iterator to one past the last element
15121
15122 Returns an iterator to one past the last element.
15123
15124 @image html range-begin-end.svg "Illustration from cppreference.com"
15125
15126 @return iterator one past the last element
15127
15128 @complexity Constant.
15129
15130 @requirement This function helps `basic_json` satisfying the
15131 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15132 requirements:
15133 - The complexity is constant.
15134
15135 @liveexample{The following code shows an example for `end()`.,end}
15136
15137 @sa @ref cend() -- returns a const iterator to the end
15138 @sa @ref begin() -- returns an iterator to the beginning
15139 @sa @ref cbegin() -- returns a const iterator to the beginning
15140
15141 @since version 1.0.0
15142 */
end()15143 iterator end() noexcept
15144 {
15145 iterator result(this);
15146 result.set_end();
15147 return result;
15148 }
15149
15150 /*!
15151 @copydoc basic_json::cend()
15152 */
end() const15153 const_iterator end() const noexcept
15154 {
15155 return cend();
15156 }
15157
15158 /*!
15159 @brief returns a const iterator to one past the last element
15160
15161 Returns a const iterator to one past the last element.
15162
15163 @image html range-begin-end.svg "Illustration from cppreference.com"
15164
15165 @return const iterator one past the last element
15166
15167 @complexity Constant.
15168
15169 @requirement This function helps `basic_json` satisfying the
15170 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15171 requirements:
15172 - The complexity is constant.
15173 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
15174
15175 @liveexample{The following code shows an example for `cend()`.,cend}
15176
15177 @sa @ref end() -- returns an iterator to the end
15178 @sa @ref begin() -- returns an iterator to the beginning
15179 @sa @ref cbegin() -- returns a const iterator to the beginning
15180
15181 @since version 1.0.0
15182 */
cend() const15183 const_iterator cend() const noexcept
15184 {
15185 const_iterator result(this);
15186 result.set_end();
15187 return result;
15188 }
15189
15190 /*!
15191 @brief returns an iterator to the reverse-beginning
15192
15193 Returns an iterator to the reverse-beginning; that is, the last element.
15194
15195 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15196
15197 @complexity Constant.
15198
15199 @requirement This function helps `basic_json` satisfying the
15200 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15201 requirements:
15202 - The complexity is constant.
15203 - Has the semantics of `reverse_iterator(end())`.
15204
15205 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
15206
15207 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15208 @sa @ref rend() -- returns a reverse iterator to the end
15209 @sa @ref crend() -- returns a const reverse iterator to the end
15210
15211 @since version 1.0.0
15212 */
rbegin()15213 reverse_iterator rbegin() noexcept
15214 {
15215 return reverse_iterator(end());
15216 }
15217
15218 /*!
15219 @copydoc basic_json::crbegin()
15220 */
rbegin() const15221 const_reverse_iterator rbegin() const noexcept
15222 {
15223 return crbegin();
15224 }
15225
15226 /*!
15227 @brief returns an iterator to the reverse-end
15228
15229 Returns an iterator to the reverse-end; that is, one before the first
15230 element.
15231
15232 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15233
15234 @complexity Constant.
15235
15236 @requirement This function helps `basic_json` satisfying the
15237 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15238 requirements:
15239 - The complexity is constant.
15240 - Has the semantics of `reverse_iterator(begin())`.
15241
15242 @liveexample{The following code shows an example for `rend()`.,rend}
15243
15244 @sa @ref crend() -- returns a const reverse iterator to the end
15245 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15246 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15247
15248 @since version 1.0.0
15249 */
rend()15250 reverse_iterator rend() noexcept
15251 {
15252 return reverse_iterator(begin());
15253 }
15254
15255 /*!
15256 @copydoc basic_json::crend()
15257 */
rend() const15258 const_reverse_iterator rend() const noexcept
15259 {
15260 return crend();
15261 }
15262
15263 /*!
15264 @brief returns a const reverse iterator to the last element
15265
15266 Returns a const iterator to the reverse-beginning; that is, the last
15267 element.
15268
15269 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15270
15271 @complexity Constant.
15272
15273 @requirement This function helps `basic_json` satisfying the
15274 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15275 requirements:
15276 - The complexity is constant.
15277 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
15278
15279 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
15280
15281 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15282 @sa @ref rend() -- returns a reverse iterator to the end
15283 @sa @ref crend() -- returns a const reverse iterator to the end
15284
15285 @since version 1.0.0
15286 */
crbegin() const15287 const_reverse_iterator crbegin() const noexcept
15288 {
15289 return const_reverse_iterator(cend());
15290 }
15291
15292 /*!
15293 @brief returns a const reverse iterator to one before the first
15294
15295 Returns a const reverse iterator to the reverse-end; that is, one before
15296 the first element.
15297
15298 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15299
15300 @complexity Constant.
15301
15302 @requirement This function helps `basic_json` satisfying the
15303 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15304 requirements:
15305 - The complexity is constant.
15306 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
15307
15308 @liveexample{The following code shows an example for `crend()`.,crend}
15309
15310 @sa @ref rend() -- returns a reverse iterator to the end
15311 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15312 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15313
15314 @since version 1.0.0
15315 */
crend() const15316 const_reverse_iterator crend() const noexcept
15317 {
15318 return const_reverse_iterator(cbegin());
15319 }
15320
15321 public:
15322 /*!
15323 @brief wrapper to access iterator member functions in range-based for
15324
15325 This function allows to access @ref iterator::key() and @ref
15326 iterator::value() during range-based for loops. In these loops, a
15327 reference to the JSON values is returned, so there is no access to the
15328 underlying iterator.
15329
15330 For loop without iterator_wrapper:
15331
15332 @code{cpp}
15333 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15334 {
15335 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15336 }
15337 @endcode
15338
15339 Range-based for loop without iterator proxy:
15340
15341 @code{cpp}
15342 for (auto it : j_object)
15343 {
15344 // "it" is of type json::reference and has no key() member
15345 std::cout << "value: " << it << '\n';
15346 }
15347 @endcode
15348
15349 Range-based for loop with iterator proxy:
15350
15351 @code{cpp}
15352 for (auto it : json::iterator_wrapper(j_object))
15353 {
15354 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15355 }
15356 @endcode
15357
15358 @note When iterating over an array, `key()` will return the index of the
15359 element as string (see example).
15360
15361 @param[in] ref reference to a JSON value
15362 @return iteration proxy object wrapping @a ref with an interface to use in
15363 range-based for loops
15364
15365 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
15366
15367 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15368 changes in the JSON value.
15369
15370 @complexity Constant.
15371
15372 @note The name of this function is not yet final and may change in the
15373 future.
15374
15375 @deprecated This stream operator is deprecated and will be removed in
15376 future 4.0.0 of the library. Please use @ref items() instead;
15377 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
15378 */
15379 JSON_DEPRECATED
iterator_wrapper(reference ref)15380 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
15381 {
15382 return ref.items();
15383 }
15384
15385 /*!
15386 @copydoc iterator_wrapper(reference)
15387 */
15388 JSON_DEPRECATED
iterator_wrapper(const_reference ref)15389 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
15390 {
15391 return ref.items();
15392 }
15393
15394 /*!
15395 @brief helper to access iterator member functions in range-based for
15396
15397 This function allows to access @ref iterator::key() and @ref
15398 iterator::value() during range-based for loops. In these loops, a
15399 reference to the JSON values is returned, so there is no access to the
15400 underlying iterator.
15401
15402 For loop without `items()` function:
15403
15404 @code{cpp}
15405 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15406 {
15407 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15408 }
15409 @endcode
15410
15411 Range-based for loop without `items()` function:
15412
15413 @code{cpp}
15414 for (auto it : j_object)
15415 {
15416 // "it" is of type json::reference and has no key() member
15417 std::cout << "value: " << it << '\n';
15418 }
15419 @endcode
15420
15421 Range-based for loop with `items()` function:
15422
15423 @code{cpp}
15424 for (auto it : j_object.items())
15425 {
15426 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15427 }
15428 @endcode
15429
15430 @note When iterating over an array, `key()` will return the index of the
15431 element as string (see example). For primitive types (e.g., numbers),
15432 `key()` returns an empty string.
15433
15434 @return iteration proxy object wrapping @a ref with an interface to use in
15435 range-based for loops
15436
15437 @liveexample{The following code shows how the function is used.,items}
15438
15439 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15440 changes in the JSON value.
15441
15442 @complexity Constant.
15443
15444 @since version 3.1.0.
15445 */
items()15446 iteration_proxy<iterator> items() noexcept
15447 {
15448 return iteration_proxy<iterator>(*this);
15449 }
15450
15451 /*!
15452 @copydoc items()
15453 */
items() const15454 iteration_proxy<const_iterator> items() const noexcept
15455 {
15456 return iteration_proxy<const_iterator>(*this);
15457 }
15458
15459 /// @}
15460
15461
15462 //////////////
15463 // capacity //
15464 //////////////
15465
15466 /// @name capacity
15467 /// @{
15468
15469 /*!
15470 @brief checks whether the container is empty.
15471
15472 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
15473
15474 @return The return value depends on the different types and is
15475 defined as follows:
15476 Value type | return value
15477 ----------- | -------------
15478 null | `true`
15479 boolean | `false`
15480 string | `false`
15481 number | `false`
15482 object | result of function `object_t::empty()`
15483 array | result of function `array_t::empty()`
15484
15485 @liveexample{The following code uses `empty()` to check if a JSON
15486 object contains any elements.,empty}
15487
15488 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15489 the Container concept; that is, their `empty()` functions have constant
15490 complexity.
15491
15492 @iterators No changes.
15493
15494 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15495
15496 @note This function does not return whether a string stored as JSON value
15497 is empty - it returns whether the JSON container itself is empty which is
15498 false in the case of a string.
15499
15500 @requirement This function helps `basic_json` satisfying the
15501 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15502 requirements:
15503 - The complexity is constant.
15504 - Has the semantics of `begin() == end()`.
15505
15506 @sa @ref size() -- returns the number of elements
15507
15508 @since version 1.0.0
15509 */
empty() const15510 bool empty() const noexcept
15511 {
15512 switch (m_type)
15513 {
15514 case value_t::null:
15515 {
15516 // null values are empty
15517 return true;
15518 }
15519
15520 case value_t::array:
15521 {
15522 // delegate call to array_t::empty()
15523 return m_value.array->empty();
15524 }
15525
15526 case value_t::object:
15527 {
15528 // delegate call to object_t::empty()
15529 return m_value.object->empty();
15530 }
15531
15532 default:
15533 {
15534 // all other types are nonempty
15535 return false;
15536 }
15537 }
15538 }
15539
15540 /*!
15541 @brief returns the number of elements
15542
15543 Returns the number of elements in a JSON value.
15544
15545 @return The return value depends on the different types and is
15546 defined as follows:
15547 Value type | return value
15548 ----------- | -------------
15549 null | `0`
15550 boolean | `1`
15551 string | `1`
15552 number | `1`
15553 object | result of function object_t::size()
15554 array | result of function array_t::size()
15555
15556 @liveexample{The following code calls `size()` on the different value
15557 types.,size}
15558
15559 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15560 the Container concept; that is, their size() functions have constant
15561 complexity.
15562
15563 @iterators No changes.
15564
15565 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15566
15567 @note This function does not return the length of a string stored as JSON
15568 value - it returns the number of elements in the JSON value which is 1 in
15569 the case of a string.
15570
15571 @requirement This function helps `basic_json` satisfying the
15572 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15573 requirements:
15574 - The complexity is constant.
15575 - Has the semantics of `std::distance(begin(), end())`.
15576
15577 @sa @ref empty() -- checks whether the container is empty
15578 @sa @ref max_size() -- returns the maximal number of elements
15579
15580 @since version 1.0.0
15581 */
size() const15582 size_type size() const noexcept
15583 {
15584 switch (m_type)
15585 {
15586 case value_t::null:
15587 {
15588 // null values are empty
15589 return 0;
15590 }
15591
15592 case value_t::array:
15593 {
15594 // delegate call to array_t::size()
15595 return m_value.array->size();
15596 }
15597
15598 case value_t::object:
15599 {
15600 // delegate call to object_t::size()
15601 return m_value.object->size();
15602 }
15603
15604 default:
15605 {
15606 // all other types have size 1
15607 return 1;
15608 }
15609 }
15610 }
15611
15612 /*!
15613 @brief returns the maximum possible number of elements
15614
15615 Returns the maximum number of elements a JSON value is able to hold due to
15616 system or library implementation limitations, i.e. `std::distance(begin(),
15617 end())` for the JSON value.
15618
15619 @return The return value depends on the different types and is
15620 defined as follows:
15621 Value type | return value
15622 ----------- | -------------
15623 null | `0` (same as `size()`)
15624 boolean | `1` (same as `size()`)
15625 string | `1` (same as `size()`)
15626 number | `1` (same as `size()`)
15627 object | result of function `object_t::max_size()`
15628 array | result of function `array_t::max_size()`
15629
15630 @liveexample{The following code calls `max_size()` on the different value
15631 types. Note the output is implementation specific.,max_size}
15632
15633 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15634 the Container concept; that is, their `max_size()` functions have constant
15635 complexity.
15636
15637 @iterators No changes.
15638
15639 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15640
15641 @requirement This function helps `basic_json` satisfying the
15642 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15643 requirements:
15644 - The complexity is constant.
15645 - Has the semantics of returning `b.size()` where `b` is the largest
15646 possible JSON value.
15647
15648 @sa @ref size() -- returns the number of elements
15649
15650 @since version 1.0.0
15651 */
max_size() const15652 size_type max_size() const noexcept
15653 {
15654 switch (m_type)
15655 {
15656 case value_t::array:
15657 {
15658 // delegate call to array_t::max_size()
15659 return m_value.array->max_size();
15660 }
15661
15662 case value_t::object:
15663 {
15664 // delegate call to object_t::max_size()
15665 return m_value.object->max_size();
15666 }
15667
15668 default:
15669 {
15670 // all other types have max_size() == size()
15671 return size();
15672 }
15673 }
15674 }
15675
15676 /// @}
15677
15678
15679 ///////////////
15680 // modifiers //
15681 ///////////////
15682
15683 /// @name modifiers
15684 /// @{
15685
15686 /*!
15687 @brief clears the contents
15688
15689 Clears the content of a JSON value and resets it to the default value as
15690 if @ref basic_json(value_t) would have been called with the current value
15691 type from @ref type():
15692
15693 Value type | initial value
15694 ----------- | -------------
15695 null | `null`
15696 boolean | `false`
15697 string | `""`
15698 number | `0`
15699 object | `{}`
15700 array | `[]`
15701
15702 @post Has the same effect as calling
15703 @code {.cpp}
15704 *this = basic_json(type());
15705 @endcode
15706
15707 @liveexample{The example below shows the effect of `clear()` to different
15708 JSON types.,clear}
15709
15710 @complexity Linear in the size of the JSON value.
15711
15712 @iterators All iterators, pointers and references related to this container
15713 are invalidated.
15714
15715 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15716
15717 @sa @ref basic_json(value_t) -- constructor that creates an object with the
15718 same value than calling `clear()`
15719
15720 @since version 1.0.0
15721 */
clear()15722 void clear() noexcept
15723 {
15724 switch (m_type)
15725 {
15726 case value_t::number_integer:
15727 {
15728 m_value.number_integer = 0;
15729 break;
15730 }
15731
15732 case value_t::number_unsigned:
15733 {
15734 m_value.number_unsigned = 0;
15735 break;
15736 }
15737
15738 case value_t::number_float:
15739 {
15740 m_value.number_float = 0.0;
15741 break;
15742 }
15743
15744 case value_t::boolean:
15745 {
15746 m_value.boolean = false;
15747 break;
15748 }
15749
15750 case value_t::string:
15751 {
15752 m_value.string->clear();
15753 break;
15754 }
15755
15756 case value_t::array:
15757 {
15758 m_value.array->clear();
15759 break;
15760 }
15761
15762 case value_t::object:
15763 {
15764 m_value.object->clear();
15765 break;
15766 }
15767
15768 default:
15769 break;
15770 }
15771 }
15772
15773 /*!
15774 @brief add an object to an array
15775
15776 Appends the given element @a val to the end of the JSON value. If the
15777 function is called on a JSON null value, an empty array is created before
15778 appending @a val.
15779
15780 @param[in] val the value to add to the JSON array
15781
15782 @throw type_error.308 when called on a type other than JSON array or
15783 null; example: `"cannot use push_back() with number"`
15784
15785 @complexity Amortized constant.
15786
15787 @liveexample{The example shows how `push_back()` and `+=` can be used to
15788 add elements to a JSON array. Note how the `null` value was silently
15789 converted to a JSON array.,push_back}
15790
15791 @since version 1.0.0
15792 */
push_back(basic_json && val)15793 void push_back(basic_json&& val)
15794 {
15795 // push_back only works for null objects or arrays
15796 if (JSON_UNLIKELY(not(is_null() or is_array())))
15797 {
15798 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15799 }
15800
15801 // transform null object into an array
15802 if (is_null())
15803 {
15804 m_type = value_t::array;
15805 m_value = value_t::array;
15806 assert_invariant();
15807 }
15808
15809 // add element to array (move semantics)
15810 m_value.array->push_back(std::move(val));
15811 // invalidate object
15812 val.m_type = value_t::null;
15813 }
15814
15815 /*!
15816 @brief add an object to an array
15817 @copydoc push_back(basic_json&&)
15818 */
operator +=(basic_json && val)15819 reference operator+=(basic_json&& val)
15820 {
15821 push_back(std::move(val));
15822 return *this;
15823 }
15824
15825 /*!
15826 @brief add an object to an array
15827 @copydoc push_back(basic_json&&)
15828 */
push_back(const basic_json & val)15829 void push_back(const basic_json& val)
15830 {
15831 // push_back only works for null objects or arrays
15832 if (JSON_UNLIKELY(not(is_null() or is_array())))
15833 {
15834 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15835 }
15836
15837 // transform null object into an array
15838 if (is_null())
15839 {
15840 m_type = value_t::array;
15841 m_value = value_t::array;
15842 assert_invariant();
15843 }
15844
15845 // add element to array
15846 m_value.array->push_back(val);
15847 }
15848
15849 /*!
15850 @brief add an object to an array
15851 @copydoc push_back(basic_json&&)
15852 */
operator +=(const basic_json & val)15853 reference operator+=(const basic_json& val)
15854 {
15855 push_back(val);
15856 return *this;
15857 }
15858
15859 /*!
15860 @brief add an object to an object
15861
15862 Inserts the given element @a val to the JSON object. If the function is
15863 called on a JSON null value, an empty object is created before inserting
15864 @a val.
15865
15866 @param[in] val the value to add to the JSON object
15867
15868 @throw type_error.308 when called on a type other than JSON object or
15869 null; example: `"cannot use push_back() with number"`
15870
15871 @complexity Logarithmic in the size of the container, O(log(`size()`)).
15872
15873 @liveexample{The example shows how `push_back()` and `+=` can be used to
15874 add elements to a JSON object. Note how the `null` value was silently
15875 converted to a JSON object.,push_back__object_t__value}
15876
15877 @since version 1.0.0
15878 */
push_back(const typename object_t::value_type & val)15879 void push_back(const typename object_t::value_type& val)
15880 {
15881 // push_back only works for null objects or objects
15882 if (JSON_UNLIKELY(not(is_null() or is_object())))
15883 {
15884 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15885 }
15886
15887 // transform null object into an object
15888 if (is_null())
15889 {
15890 m_type = value_t::object;
15891 m_value = value_t::object;
15892 assert_invariant();
15893 }
15894
15895 // add element to array
15896 m_value.object->insert(val);
15897 }
15898
15899 /*!
15900 @brief add an object to an object
15901 @copydoc push_back(const typename object_t::value_type&)
15902 */
operator +=(const typename object_t::value_type & val)15903 reference operator+=(const typename object_t::value_type& val)
15904 {
15905 push_back(val);
15906 return *this;
15907 }
15908
15909 /*!
15910 @brief add an object to an object
15911
15912 This function allows to use `push_back` with an initializer list. In case
15913
15914 1. the current value is an object,
15915 2. the initializer list @a init contains only two elements, and
15916 3. the first element of @a init is a string,
15917
15918 @a init is converted into an object element and added using
15919 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
15920 is converted to a JSON value and added using @ref push_back(basic_json&&).
15921
15922 @param[in] init an initializer list
15923
15924 @complexity Linear in the size of the initializer list @a init.
15925
15926 @note This function is required to resolve an ambiguous overload error,
15927 because pairs like `{"key", "value"}` can be both interpreted as
15928 `object_t::value_type` or `std::initializer_list<basic_json>`, see
15929 https://github.com/nlohmann/json/issues/235 for more information.
15930
15931 @liveexample{The example shows how initializer lists are treated as
15932 objects when possible.,push_back__initializer_list}
15933 */
push_back(initializer_list_t init)15934 void push_back(initializer_list_t init)
15935 {
15936 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
15937 {
15938 basic_json&& key = init.begin()->moved_or_copied();
15939 push_back(typename object_t::value_type(
15940 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
15941 }
15942 else
15943 {
15944 push_back(basic_json(init));
15945 }
15946 }
15947
15948 /*!
15949 @brief add an object to an object
15950 @copydoc push_back(initializer_list_t)
15951 */
operator +=(initializer_list_t init)15952 reference operator+=(initializer_list_t init)
15953 {
15954 push_back(init);
15955 return *this;
15956 }
15957
15958 /*!
15959 @brief add an object to an array
15960
15961 Creates a JSON value from the passed parameters @a args to the end of the
15962 JSON value. If the function is called on a JSON null value, an empty array
15963 is created before appending the value created from @a args.
15964
15965 @param[in] args arguments to forward to a constructor of @ref basic_json
15966 @tparam Args compatible types to create a @ref basic_json object
15967
15968 @throw type_error.311 when called on a type other than JSON array or
15969 null; example: `"cannot use emplace_back() with number"`
15970
15971 @complexity Amortized constant.
15972
15973 @liveexample{The example shows how `push_back()` can be used to add
15974 elements to a JSON array. Note how the `null` value was silently converted
15975 to a JSON array.,emplace_back}
15976
15977 @since version 2.0.8
15978 */
15979 template<class... Args>
emplace_back(Args &&...args)15980 void emplace_back(Args&& ... args)
15981 {
15982 // emplace_back only works for null objects or arrays
15983 if (JSON_UNLIKELY(not(is_null() or is_array())))
15984 {
15985 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
15986 }
15987
15988 // transform null object into an array
15989 if (is_null())
15990 {
15991 m_type = value_t::array;
15992 m_value = value_t::array;
15993 assert_invariant();
15994 }
15995
15996 // add element to array (perfect forwarding)
15997 m_value.array->emplace_back(std::forward<Args>(args)...);
15998 }
15999
16000 /*!
16001 @brief add an object to an object if key does not exist
16002
16003 Inserts a new element into a JSON object constructed in-place with the
16004 given @a args if there is no element with the key in the container. If the
16005 function is called on a JSON null value, an empty object is created before
16006 appending the value created from @a args.
16007
16008 @param[in] args arguments to forward to a constructor of @ref basic_json
16009 @tparam Args compatible types to create a @ref basic_json object
16010
16011 @return a pair consisting of an iterator to the inserted element, or the
16012 already-existing element if no insertion happened, and a bool
16013 denoting whether the insertion took place.
16014
16015 @throw type_error.311 when called on a type other than JSON object or
16016 null; example: `"cannot use emplace() with number"`
16017
16018 @complexity Logarithmic in the size of the container, O(log(`size()`)).
16019
16020 @liveexample{The example shows how `emplace()` can be used to add elements
16021 to a JSON object. Note how the `null` value was silently converted to a
16022 JSON object. Further note how no value is added if there was already one
16023 value stored with the same key.,emplace}
16024
16025 @since version 2.0.8
16026 */
16027 template<class... Args>
emplace(Args &&...args)16028 std::pair<iterator, bool> emplace(Args&& ... args)
16029 {
16030 // emplace only works for null objects or arrays
16031 if (JSON_UNLIKELY(not(is_null() or is_object())))
16032 {
16033 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
16034 }
16035
16036 // transform null object into an object
16037 if (is_null())
16038 {
16039 m_type = value_t::object;
16040 m_value = value_t::object;
16041 assert_invariant();
16042 }
16043
16044 // add element to array (perfect forwarding)
16045 auto res = m_value.object->emplace(std::forward<Args>(args)...);
16046 // create result iterator and set iterator to the result of emplace
16047 auto it = begin();
16048 it.m_it.object_iterator = res.first;
16049
16050 // return pair of iterator and boolean
16051 return {it, res.second};
16052 }
16053
16054 /*!
16055 @brief inserts element
16056
16057 Inserts element @a val before iterator @a pos.
16058
16059 @param[in] pos iterator before which the content will be inserted; may be
16060 the end() iterator
16061 @param[in] val element to insert
16062 @return iterator pointing to the inserted @a val.
16063
16064 @throw type_error.309 if called on JSON values other than arrays;
16065 example: `"cannot use insert() with string"`
16066 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16067 example: `"iterator does not fit current value"`
16068
16069 @complexity Constant plus linear in the distance between @a pos and end of
16070 the container.
16071
16072 @liveexample{The example shows how `insert()` is used.,insert}
16073
16074 @since version 1.0.0
16075 */
insert(const_iterator pos,const basic_json & val)16076 iterator insert(const_iterator pos, const basic_json& val)
16077 {
16078 // insert only works for arrays
16079 if (JSON_LIKELY(is_array()))
16080 {
16081 // check if iterator pos fits to this JSON value
16082 if (JSON_UNLIKELY(pos.m_object != this))
16083 {
16084 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16085 }
16086
16087 // insert to array and return iterator
16088 iterator result(this);
16089 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
16090 return result;
16091 }
16092
16093 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16094 }
16095
16096 /*!
16097 @brief inserts element
16098 @copydoc insert(const_iterator, const basic_json&)
16099 */
insert(const_iterator pos,basic_json && val)16100 iterator insert(const_iterator pos, basic_json&& val)
16101 {
16102 return insert(pos, val);
16103 }
16104
16105 /*!
16106 @brief inserts elements
16107
16108 Inserts @a cnt copies of @a val before iterator @a pos.
16109
16110 @param[in] pos iterator before which the content will be inserted; may be
16111 the end() iterator
16112 @param[in] cnt number of copies of @a val to insert
16113 @param[in] val element to insert
16114 @return iterator pointing to the first element inserted, or @a pos if
16115 `cnt==0`
16116
16117 @throw type_error.309 if called on JSON values other than arrays; example:
16118 `"cannot use insert() with string"`
16119 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16120 example: `"iterator does not fit current value"`
16121
16122 @complexity Linear in @a cnt plus linear in the distance between @a pos
16123 and end of the container.
16124
16125 @liveexample{The example shows how `insert()` is used.,insert__count}
16126
16127 @since version 1.0.0
16128 */
insert(const_iterator pos,size_type cnt,const basic_json & val)16129 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
16130 {
16131 // insert only works for arrays
16132 if (JSON_LIKELY(is_array()))
16133 {
16134 // check if iterator pos fits to this JSON value
16135 if (JSON_UNLIKELY(pos.m_object != this))
16136 {
16137 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16138 }
16139
16140 // insert to array and return iterator
16141 iterator result(this);
16142 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
16143 return result;
16144 }
16145
16146 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16147 }
16148
16149 /*!
16150 @brief inserts elements
16151
16152 Inserts elements from range `[first, last)` before iterator @a pos.
16153
16154 @param[in] pos iterator before which the content will be inserted; may be
16155 the end() iterator
16156 @param[in] first begin of the range of elements to insert
16157 @param[in] last end of the range of elements to insert
16158
16159 @throw type_error.309 if called on JSON values other than arrays; example:
16160 `"cannot use insert() with string"`
16161 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16162 example: `"iterator does not fit current value"`
16163 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16164 same JSON value; example: `"iterators do not fit"`
16165 @throw invalid_iterator.211 if @a first or @a last are iterators into
16166 container for which insert is called; example: `"passed iterators may not
16167 belong to container"`
16168
16169 @return iterator pointing to the first element inserted, or @a pos if
16170 `first==last`
16171
16172 @complexity Linear in `std::distance(first, last)` plus linear in the
16173 distance between @a pos and end of the container.
16174
16175 @liveexample{The example shows how `insert()` is used.,insert__range}
16176
16177 @since version 1.0.0
16178 */
insert(const_iterator pos,const_iterator first,const_iterator last)16179 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
16180 {
16181 // insert only works for arrays
16182 if (JSON_UNLIKELY(not is_array()))
16183 {
16184 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16185 }
16186
16187 // check if iterator pos fits to this JSON value
16188 if (JSON_UNLIKELY(pos.m_object != this))
16189 {
16190 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16191 }
16192
16193 // check if range iterators belong to the same JSON object
16194 if (JSON_UNLIKELY(first.m_object != last.m_object))
16195 {
16196 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16197 }
16198
16199 if (JSON_UNLIKELY(first.m_object == this))
16200 {
16201 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
16202 }
16203
16204 // insert to array and return iterator
16205 iterator result(this);
16206 result.m_it.array_iterator = m_value.array->insert(
16207 pos.m_it.array_iterator,
16208 first.m_it.array_iterator,
16209 last.m_it.array_iterator);
16210 return result;
16211 }
16212
16213 /*!
16214 @brief inserts elements
16215
16216 Inserts elements from initializer list @a ilist before iterator @a pos.
16217
16218 @param[in] pos iterator before which the content will be inserted; may be
16219 the end() iterator
16220 @param[in] ilist initializer list to insert the values from
16221
16222 @throw type_error.309 if called on JSON values other than arrays; example:
16223 `"cannot use insert() with string"`
16224 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16225 example: `"iterator does not fit current value"`
16226
16227 @return iterator pointing to the first element inserted, or @a pos if
16228 `ilist` is empty
16229
16230 @complexity Linear in `ilist.size()` plus linear in the distance between
16231 @a pos and end of the container.
16232
16233 @liveexample{The example shows how `insert()` is used.,insert__ilist}
16234
16235 @since version 1.0.0
16236 */
insert(const_iterator pos,initializer_list_t ilist)16237 iterator insert(const_iterator pos, initializer_list_t ilist)
16238 {
16239 // insert only works for arrays
16240 if (JSON_UNLIKELY(not is_array()))
16241 {
16242 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16243 }
16244
16245 // check if iterator pos fits to this JSON value
16246 if (JSON_UNLIKELY(pos.m_object != this))
16247 {
16248 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16249 }
16250
16251 // insert to array and return iterator
16252 iterator result(this);
16253 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
16254 return result;
16255 }
16256
16257 /*!
16258 @brief inserts elements
16259
16260 Inserts elements from range `[first, last)`.
16261
16262 @param[in] first begin of the range of elements to insert
16263 @param[in] last end of the range of elements to insert
16264
16265 @throw type_error.309 if called on JSON values other than objects; example:
16266 `"cannot use insert() with string"`
16267 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16268 point to an object; example: `"iterators first and last must point to
16269 objects"`
16270 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16271 same JSON value; example: `"iterators do not fit"`
16272
16273 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
16274 of elements to insert.
16275
16276 @liveexample{The example shows how `insert()` is used.,insert__range_object}
16277
16278 @since version 3.0.0
16279 */
insert(const_iterator first,const_iterator last)16280 void insert(const_iterator first, const_iterator last)
16281 {
16282 // insert only works for objects
16283 if (JSON_UNLIKELY(not is_object()))
16284 {
16285 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16286 }
16287
16288 // check if range iterators belong to the same JSON object
16289 if (JSON_UNLIKELY(first.m_object != last.m_object))
16290 {
16291 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16292 }
16293
16294 // passed iterators must belong to objects
16295 if (JSON_UNLIKELY(not first.m_object->is_object()))
16296 {
16297 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16298 }
16299
16300 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
16301 }
16302
16303 /*!
16304 @brief updates a JSON object from another object, overwriting existing keys
16305
16306 Inserts all values from JSON object @a j and overwrites existing keys.
16307
16308 @param[in] j JSON object to read values from
16309
16310 @throw type_error.312 if called on JSON values other than objects; example:
16311 `"cannot use update() with string"`
16312
16313 @complexity O(N*log(size() + N)), where N is the number of elements to
16314 insert.
16315
16316 @liveexample{The example shows how `update()` is used.,update}
16317
16318 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16319
16320 @since version 3.0.0
16321 */
update(const_reference j)16322 void update(const_reference j)
16323 {
16324 // implicitly convert null value to an empty object
16325 if (is_null())
16326 {
16327 m_type = value_t::object;
16328 m_value.object = create<object_t>();
16329 assert_invariant();
16330 }
16331
16332 if (JSON_UNLIKELY(not is_object()))
16333 {
16334 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16335 }
16336 if (JSON_UNLIKELY(not j.is_object()))
16337 {
16338 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
16339 }
16340
16341 for (auto it = j.cbegin(); it != j.cend(); ++it)
16342 {
16343 m_value.object->operator[](it.key()) = it.value();
16344 }
16345 }
16346
16347 /*!
16348 @brief updates a JSON object from another object, overwriting existing keys
16349
16350 Inserts all values from from range `[first, last)` and overwrites existing
16351 keys.
16352
16353 @param[in] first begin of the range of elements to insert
16354 @param[in] last end of the range of elements to insert
16355
16356 @throw type_error.312 if called on JSON values other than objects; example:
16357 `"cannot use update() with string"`
16358 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16359 point to an object; example: `"iterators first and last must point to
16360 objects"`
16361 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16362 same JSON value; example: `"iterators do not fit"`
16363
16364 @complexity O(N*log(size() + N)), where N is the number of elements to
16365 insert.
16366
16367 @liveexample{The example shows how `update()` is used__range.,update}
16368
16369 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16370
16371 @since version 3.0.0
16372 */
update(const_iterator first,const_iterator last)16373 void update(const_iterator first, const_iterator last)
16374 {
16375 // implicitly convert null value to an empty object
16376 if (is_null())
16377 {
16378 m_type = value_t::object;
16379 m_value.object = create<object_t>();
16380 assert_invariant();
16381 }
16382
16383 if (JSON_UNLIKELY(not is_object()))
16384 {
16385 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16386 }
16387
16388 // check if range iterators belong to the same JSON object
16389 if (JSON_UNLIKELY(first.m_object != last.m_object))
16390 {
16391 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16392 }
16393
16394 // passed iterators must belong to objects
16395 if (JSON_UNLIKELY(not first.m_object->is_object()
16396 or not last.m_object->is_object()))
16397 {
16398 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16399 }
16400
16401 for (auto it = first; it != last; ++it)
16402 {
16403 m_value.object->operator[](it.key()) = it.value();
16404 }
16405 }
16406
16407 /*!
16408 @brief exchanges the values
16409
16410 Exchanges the contents of the JSON value with those of @a other. Does not
16411 invoke any move, copy, or swap operations on individual elements. All
16412 iterators and references remain valid. The past-the-end iterator is
16413 invalidated.
16414
16415 @param[in,out] other JSON value to exchange the contents with
16416
16417 @complexity Constant.
16418
16419 @liveexample{The example below shows how JSON values can be swapped with
16420 `swap()`.,swap__reference}
16421
16422 @since version 1.0.0
16423 */
swap(reference other)16424 void swap(reference other) noexcept (
16425 std::is_nothrow_move_constructible<value_t>::value and
16426 std::is_nothrow_move_assignable<value_t>::value and
16427 std::is_nothrow_move_constructible<json_value>::value and
16428 std::is_nothrow_move_assignable<json_value>::value
16429 )
16430 {
16431 std::swap(m_type, other.m_type);
16432 std::swap(m_value, other.m_value);
16433 assert_invariant();
16434 }
16435
16436 /*!
16437 @brief exchanges the values
16438
16439 Exchanges the contents of a JSON array with those of @a other. Does not
16440 invoke any move, copy, or swap operations on individual elements. All
16441 iterators and references remain valid. The past-the-end iterator is
16442 invalidated.
16443
16444 @param[in,out] other array to exchange the contents with
16445
16446 @throw type_error.310 when JSON value is not an array; example: `"cannot
16447 use swap() with string"`
16448
16449 @complexity Constant.
16450
16451 @liveexample{The example below shows how arrays can be swapped with
16452 `swap()`.,swap__array_t}
16453
16454 @since version 1.0.0
16455 */
swap(array_t & other)16456 void swap(array_t& other)
16457 {
16458 // swap only works for arrays
16459 if (JSON_LIKELY(is_array()))
16460 {
16461 std::swap(*(m_value.array), other);
16462 }
16463 else
16464 {
16465 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16466 }
16467 }
16468
16469 /*!
16470 @brief exchanges the values
16471
16472 Exchanges the contents of a JSON object with those of @a other. Does not
16473 invoke any move, copy, or swap operations on individual elements. All
16474 iterators and references remain valid. The past-the-end iterator is
16475 invalidated.
16476
16477 @param[in,out] other object to exchange the contents with
16478
16479 @throw type_error.310 when JSON value is not an object; example:
16480 `"cannot use swap() with string"`
16481
16482 @complexity Constant.
16483
16484 @liveexample{The example below shows how objects can be swapped with
16485 `swap()`.,swap__object_t}
16486
16487 @since version 1.0.0
16488 */
swap(object_t & other)16489 void swap(object_t& other)
16490 {
16491 // swap only works for objects
16492 if (JSON_LIKELY(is_object()))
16493 {
16494 std::swap(*(m_value.object), other);
16495 }
16496 else
16497 {
16498 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16499 }
16500 }
16501
16502 /*!
16503 @brief exchanges the values
16504
16505 Exchanges the contents of a JSON string with those of @a other. Does not
16506 invoke any move, copy, or swap operations on individual elements. All
16507 iterators and references remain valid. The past-the-end iterator is
16508 invalidated.
16509
16510 @param[in,out] other string to exchange the contents with
16511
16512 @throw type_error.310 when JSON value is not a string; example: `"cannot
16513 use swap() with boolean"`
16514
16515 @complexity Constant.
16516
16517 @liveexample{The example below shows how strings can be swapped with
16518 `swap()`.,swap__string_t}
16519
16520 @since version 1.0.0
16521 */
swap(string_t & other)16522 void swap(string_t& other)
16523 {
16524 // swap only works for strings
16525 if (JSON_LIKELY(is_string()))
16526 {
16527 std::swap(*(m_value.string), other);
16528 }
16529 else
16530 {
16531 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16532 }
16533 }
16534
16535 /// @}
16536
16537 public:
16538 //////////////////////////////////////////
16539 // lexicographical comparison operators //
16540 //////////////////////////////////////////
16541
16542 /// @name lexicographical comparison operators
16543 /// @{
16544
16545 /*!
16546 @brief comparison: equal
16547
16548 Compares two JSON values for equality according to the following rules:
16549 - Two JSON values are equal if (1) they are from the same type and (2)
16550 their stored values are the same according to their respective
16551 `operator==`.
16552 - Integer and floating-point numbers are automatically converted before
16553 comparison. Note than two NaN values are always treated as unequal.
16554 - Two JSON null values are equal.
16555
16556 @note Floating-point inside JSON values numbers are compared with
16557 `json::number_float_t::operator==` which is `double::operator==` by
16558 default. To compare floating-point while respecting an epsilon, an alternative
16559 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
16560 could be used, for instance
16561 @code {.cpp}
16562 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
16563 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
16564 {
16565 return std::abs(a - b) <= epsilon;
16566 }
16567 @endcode
16568
16569 @note NaN values never compare equal to themselves or to other NaN values.
16570
16571 @param[in] lhs first JSON value to consider
16572 @param[in] rhs second JSON value to consider
16573 @return whether the values @a lhs and @a rhs are equal
16574
16575 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16576
16577 @complexity Linear.
16578
16579 @liveexample{The example demonstrates comparing several JSON
16580 types.,operator__equal}
16581
16582 @since version 1.0.0
16583 */
operator ==(const_reference lhs,const_reference rhs)16584 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
16585 {
16586 const auto lhs_type = lhs.type();
16587 const auto rhs_type = rhs.type();
16588
16589 if (lhs_type == rhs_type)
16590 {
16591 switch (lhs_type)
16592 {
16593 case value_t::array:
16594 return (*lhs.m_value.array == *rhs.m_value.array);
16595
16596 case value_t::object:
16597 return (*lhs.m_value.object == *rhs.m_value.object);
16598
16599 case value_t::null:
16600 return true;
16601
16602 case value_t::string:
16603 return (*lhs.m_value.string == *rhs.m_value.string);
16604
16605 case value_t::boolean:
16606 return (lhs.m_value.boolean == rhs.m_value.boolean);
16607
16608 case value_t::number_integer:
16609 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
16610
16611 case value_t::number_unsigned:
16612 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
16613
16614 case value_t::number_float:
16615 return (lhs.m_value.number_float == rhs.m_value.number_float);
16616
16617 default:
16618 return false;
16619 }
16620 }
16621 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16622 {
16623 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
16624 }
16625 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16626 {
16627 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
16628 }
16629 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16630 {
16631 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
16632 }
16633 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16634 {
16635 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
16636 }
16637 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16638 {
16639 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
16640 }
16641 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16642 {
16643 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
16644 }
16645
16646 return false;
16647 }
16648
16649 /*!
16650 @brief comparison: equal
16651 @copydoc operator==(const_reference, const_reference)
16652 */
16653 template<typename ScalarType, typename std::enable_if<
16654 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)16655 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
16656 {
16657 return (lhs == basic_json(rhs));
16658 }
16659
16660 /*!
16661 @brief comparison: equal
16662 @copydoc operator==(const_reference, const_reference)
16663 */
16664 template<typename ScalarType, typename std::enable_if<
16665 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)16666 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
16667 {
16668 return (basic_json(lhs) == rhs);
16669 }
16670
16671 /*!
16672 @brief comparison: not equal
16673
16674 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
16675
16676 @param[in] lhs first JSON value to consider
16677 @param[in] rhs second JSON value to consider
16678 @return whether the values @a lhs and @a rhs are not equal
16679
16680 @complexity Linear.
16681
16682 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16683
16684 @liveexample{The example demonstrates comparing several JSON
16685 types.,operator__notequal}
16686
16687 @since version 1.0.0
16688 */
operator !=(const_reference lhs,const_reference rhs)16689 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
16690 {
16691 return not (lhs == rhs);
16692 }
16693
16694 /*!
16695 @brief comparison: not equal
16696 @copydoc operator!=(const_reference, const_reference)
16697 */
16698 template<typename ScalarType, typename std::enable_if<
16699 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)16700 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
16701 {
16702 return (lhs != basic_json(rhs));
16703 }
16704
16705 /*!
16706 @brief comparison: not equal
16707 @copydoc operator!=(const_reference, const_reference)
16708 */
16709 template<typename ScalarType, typename std::enable_if<
16710 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)16711 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
16712 {
16713 return (basic_json(lhs) != rhs);
16714 }
16715
16716 /*!
16717 @brief comparison: less than
16718
16719 Compares whether one JSON value @a lhs is less than another JSON value @a
16720 rhs according to the following rules:
16721 - If @a lhs and @a rhs have the same type, the values are compared using
16722 the default `<` operator.
16723 - Integer and floating-point numbers are automatically converted before
16724 comparison
16725 - In case @a lhs and @a rhs have different types, the values are ignored
16726 and the order of the types is considered, see
16727 @ref operator<(const value_t, const value_t).
16728
16729 @param[in] lhs first JSON value to consider
16730 @param[in] rhs second JSON value to consider
16731 @return whether @a lhs is less than @a rhs
16732
16733 @complexity Linear.
16734
16735 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16736
16737 @liveexample{The example demonstrates comparing several JSON
16738 types.,operator__less}
16739
16740 @since version 1.0.0
16741 */
operator <(const_reference lhs,const_reference rhs)16742 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
16743 {
16744 const auto lhs_type = lhs.type();
16745 const auto rhs_type = rhs.type();
16746
16747 if (lhs_type == rhs_type)
16748 {
16749 switch (lhs_type)
16750 {
16751 case value_t::array:
16752 return (*lhs.m_value.array) < (*rhs.m_value.array);
16753
16754 case value_t::object:
16755 return *lhs.m_value.object < *rhs.m_value.object;
16756
16757 case value_t::null:
16758 return false;
16759
16760 case value_t::string:
16761 return *lhs.m_value.string < *rhs.m_value.string;
16762
16763 case value_t::boolean:
16764 return lhs.m_value.boolean < rhs.m_value.boolean;
16765
16766 case value_t::number_integer:
16767 return lhs.m_value.number_integer < rhs.m_value.number_integer;
16768
16769 case value_t::number_unsigned:
16770 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
16771
16772 case value_t::number_float:
16773 return lhs.m_value.number_float < rhs.m_value.number_float;
16774
16775 default:
16776 return false;
16777 }
16778 }
16779 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16780 {
16781 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
16782 }
16783 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16784 {
16785 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
16786 }
16787 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16788 {
16789 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
16790 }
16791 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16792 {
16793 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
16794 }
16795 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16796 {
16797 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
16798 }
16799 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16800 {
16801 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
16802 }
16803
16804 // We only reach this line if we cannot compare values. In that case,
16805 // we compare types. Note we have to call the operator explicitly,
16806 // because MSVC has problems otherwise.
16807 return operator<(lhs_type, rhs_type);
16808 }
16809
16810 /*!
16811 @brief comparison: less than
16812 @copydoc operator<(const_reference, const_reference)
16813 */
16814 template<typename ScalarType, typename std::enable_if<
16815 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)16816 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
16817 {
16818 return (lhs < basic_json(rhs));
16819 }
16820
16821 /*!
16822 @brief comparison: less than
16823 @copydoc operator<(const_reference, const_reference)
16824 */
16825 template<typename ScalarType, typename std::enable_if<
16826 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)16827 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
16828 {
16829 return (basic_json(lhs) < rhs);
16830 }
16831
16832 /*!
16833 @brief comparison: less than or equal
16834
16835 Compares whether one JSON value @a lhs is less than or equal to another
16836 JSON value by calculating `not (rhs < lhs)`.
16837
16838 @param[in] lhs first JSON value to consider
16839 @param[in] rhs second JSON value to consider
16840 @return whether @a lhs is less than or equal to @a rhs
16841
16842 @complexity Linear.
16843
16844 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16845
16846 @liveexample{The example demonstrates comparing several JSON
16847 types.,operator__greater}
16848
16849 @since version 1.0.0
16850 */
operator <=(const_reference lhs,const_reference rhs)16851 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
16852 {
16853 return not (rhs < lhs);
16854 }
16855
16856 /*!
16857 @brief comparison: less than or equal
16858 @copydoc operator<=(const_reference, const_reference)
16859 */
16860 template<typename ScalarType, typename std::enable_if<
16861 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)16862 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
16863 {
16864 return (lhs <= basic_json(rhs));
16865 }
16866
16867 /*!
16868 @brief comparison: less than or equal
16869 @copydoc operator<=(const_reference, const_reference)
16870 */
16871 template<typename ScalarType, typename std::enable_if<
16872 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)16873 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
16874 {
16875 return (basic_json(lhs) <= rhs);
16876 }
16877
16878 /*!
16879 @brief comparison: greater than
16880
16881 Compares whether one JSON value @a lhs is greater than another
16882 JSON value by calculating `not (lhs <= rhs)`.
16883
16884 @param[in] lhs first JSON value to consider
16885 @param[in] rhs second JSON value to consider
16886 @return whether @a lhs is greater than to @a rhs
16887
16888 @complexity Linear.
16889
16890 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16891
16892 @liveexample{The example demonstrates comparing several JSON
16893 types.,operator__lessequal}
16894
16895 @since version 1.0.0
16896 */
operator >(const_reference lhs,const_reference rhs)16897 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
16898 {
16899 return not (lhs <= rhs);
16900 }
16901
16902 /*!
16903 @brief comparison: greater than
16904 @copydoc operator>(const_reference, const_reference)
16905 */
16906 template<typename ScalarType, typename std::enable_if<
16907 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)16908 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
16909 {
16910 return (lhs > basic_json(rhs));
16911 }
16912
16913 /*!
16914 @brief comparison: greater than
16915 @copydoc operator>(const_reference, const_reference)
16916 */
16917 template<typename ScalarType, typename std::enable_if<
16918 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)16919 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
16920 {
16921 return (basic_json(lhs) > rhs);
16922 }
16923
16924 /*!
16925 @brief comparison: greater than or equal
16926
16927 Compares whether one JSON value @a lhs is greater than or equal to another
16928 JSON value by calculating `not (lhs < rhs)`.
16929
16930 @param[in] lhs first JSON value to consider
16931 @param[in] rhs second JSON value to consider
16932 @return whether @a lhs is greater than or equal to @a rhs
16933
16934 @complexity Linear.
16935
16936 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16937
16938 @liveexample{The example demonstrates comparing several JSON
16939 types.,operator__greaterequal}
16940
16941 @since version 1.0.0
16942 */
operator >=(const_reference lhs,const_reference rhs)16943 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
16944 {
16945 return not (lhs < rhs);
16946 }
16947
16948 /*!
16949 @brief comparison: greater than or equal
16950 @copydoc operator>=(const_reference, const_reference)
16951 */
16952 template<typename ScalarType, typename std::enable_if<
16953 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)16954 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
16955 {
16956 return (lhs >= basic_json(rhs));
16957 }
16958
16959 /*!
16960 @brief comparison: greater than or equal
16961 @copydoc operator>=(const_reference, const_reference)
16962 */
16963 template<typename ScalarType, typename std::enable_if<
16964 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)16965 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
16966 {
16967 return (basic_json(lhs) >= rhs);
16968 }
16969
16970 /// @}
16971
16972 ///////////////////
16973 // serialization //
16974 ///////////////////
16975
16976 /// @name serialization
16977 /// @{
16978
16979 /*!
16980 @brief serialize to stream
16981
16982 Serialize the given JSON value @a j to the output stream @a o. The JSON
16983 value will be serialized using the @ref dump member function.
16984
16985 - The indentation of the output can be controlled with the member variable
16986 `width` of the output stream @a o. For instance, using the manipulator
16987 `std::setw(4)` on @a o sets the indentation level to `4` and the
16988 serialization result is the same as calling `dump(4)`.
16989
16990 - The indentation character can be controlled with the member variable
16991 `fill` of the output stream @a o. For instance, the manipulator
16992 `std::setfill('\\t')` sets indentation to use a tab character rather than
16993 the default space character.
16994
16995 @param[in,out] o stream to serialize to
16996 @param[in] j JSON value to serialize
16997
16998 @return the stream @a o
16999
17000 @throw type_error.316 if a string stored inside the JSON value is not
17001 UTF-8 encoded
17002
17003 @complexity Linear.
17004
17005 @liveexample{The example below shows the serialization with different
17006 parameters to `width` to adjust the indentation level.,operator_serialize}
17007
17008 @since version 1.0.0; indentation character added in version 3.0.0
17009 */
operator <<(std::ostream & o,const basic_json & j)17010 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
17011 {
17012 // read width member and use it as indentation parameter if nonzero
17013 const bool pretty_print = (o.width() > 0);
17014 const auto indentation = (pretty_print ? o.width() : 0);
17015
17016 // reset width to 0 for subsequent calls to this stream
17017 o.width(0);
17018
17019 // do the actual serialization
17020 serializer s(detail::output_adapter<char>(o), o.fill());
17021 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
17022 return o;
17023 }
17024
17025 /*!
17026 @brief serialize to stream
17027 @deprecated This stream operator is deprecated and will be removed in
17028 future 4.0.0 of the library. Please use
17029 @ref operator<<(std::ostream&, const basic_json&)
17030 instead; that is, replace calls like `j >> o;` with `o << j;`.
17031 @since version 1.0.0; deprecated since version 3.0.0
17032 */
17033 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)17034 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
17035 {
17036 return o << j;
17037 }
17038
17039 /// @}
17040
17041
17042 /////////////////////
17043 // deserialization //
17044 /////////////////////
17045
17046 /// @name deserialization
17047 /// @{
17048
17049 /*!
17050 @brief deserialize from a compatible input
17051
17052 This function reads from a compatible input. Examples are:
17053 - an array of 1-byte values
17054 - strings with character/literal type with size of 1 byte
17055 - input streams
17056 - container with contiguous storage of 1-byte values. Compatible container
17057 types include `std::vector`, `std::string`, `std::array`,
17058 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17059 arrays can be used with `std::begin()`/`std::end()`. User-defined
17060 containers can be used as long as they implement random-access iterators
17061 and a contiguous storage.
17062
17063 @pre Each element of the container has a size of 1 byte. Violating this
17064 precondition yields undefined behavior. **This precondition is enforced
17065 with a static assertion.**
17066
17067 @pre The container storage is contiguous. Violating this precondition
17068 yields undefined behavior. **This precondition is enforced with an
17069 assertion.**
17070 @pre Each element of the container has a size of 1 byte. Violating this
17071 precondition yields undefined behavior. **This precondition is enforced
17072 with a static assertion.**
17073
17074 @warning There is no way to enforce all preconditions at compile-time. If
17075 the function is called with a noncompliant container and with
17076 assertions switched off, the behavior is undefined and will most
17077 likely yield segmentation violation.
17078
17079 @param[in] i input to read from
17080 @param[in] cb a parser callback function of type @ref parser_callback_t
17081 which is used to control the deserialization by filtering unwanted values
17082 (optional)
17083
17084 @return result of the deserialization
17085
17086 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17087 of input; expected string literal""`
17088 @throw parse_error.102 if to_unicode fails or surrogate error
17089 @throw parse_error.103 if to_unicode fails
17090
17091 @complexity Linear in the length of the input. The parser is a predictive
17092 LL(1) parser. The complexity can be higher if the parser callback function
17093 @a cb has a super-linear complexity.
17094
17095 @note A UTF-8 byte order mark is silently ignored.
17096
17097 @liveexample{The example below demonstrates the `parse()` function reading
17098 from an array.,parse__array__parser_callback_t}
17099
17100 @liveexample{The example below demonstrates the `parse()` function with
17101 and without callback function.,parse__string__parser_callback_t}
17102
17103 @liveexample{The example below demonstrates the `parse()` function with
17104 and without callback function.,parse__istream__parser_callback_t}
17105
17106 @liveexample{The example below demonstrates the `parse()` function reading
17107 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
17108
17109 @since version 2.0.3 (contiguous containers)
17110 */
parse(detail::input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)17111 static basic_json parse(detail::input_adapter&& i,
17112 const parser_callback_t cb = nullptr,
17113 const bool allow_exceptions = true)
17114 {
17115 basic_json result;
17116 parser(i, cb, allow_exceptions).parse(true, result);
17117 return result;
17118 }
17119
accept(detail::input_adapter && i)17120 static bool accept(detail::input_adapter&& i)
17121 {
17122 return parser(i).accept(true);
17123 }
17124
17125 /*!
17126 @brief generate SAX events
17127
17128 The SAX event lister must follow the interface of @ref json_sax.
17129
17130 This function reads from a compatible input. Examples are:
17131 - an array of 1-byte values
17132 - strings with character/literal type with size of 1 byte
17133 - input streams
17134 - container with contiguous storage of 1-byte values. Compatible container
17135 types include `std::vector`, `std::string`, `std::array`,
17136 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17137 arrays can be used with `std::begin()`/`std::end()`. User-defined
17138 containers can be used as long as they implement random-access iterators
17139 and a contiguous storage.
17140
17141 @pre Each element of the container has a size of 1 byte. Violating this
17142 precondition yields undefined behavior. **This precondition is enforced
17143 with a static assertion.**
17144
17145 @pre The container storage is contiguous. Violating this precondition
17146 yields undefined behavior. **This precondition is enforced with an
17147 assertion.**
17148 @pre Each element of the container has a size of 1 byte. Violating this
17149 precondition yields undefined behavior. **This precondition is enforced
17150 with a static assertion.**
17151
17152 @warning There is no way to enforce all preconditions at compile-time. If
17153 the function is called with a noncompliant container and with
17154 assertions switched off, the behavior is undefined and will most
17155 likely yield segmentation violation.
17156
17157 @param[in] i input to read from
17158 @param[in,out] sax SAX event listener
17159 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
17160 @param[in] strict whether the input has to be consumed completely
17161
17162 @return return value of the last processed SAX event
17163
17164 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17165 of input; expected string literal""`
17166 @throw parse_error.102 if to_unicode fails or surrogate error
17167 @throw parse_error.103 if to_unicode fails
17168
17169 @complexity Linear in the length of the input. The parser is a predictive
17170 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
17171 a super-linear complexity.
17172
17173 @note A UTF-8 byte order mark is silently ignored.
17174
17175 @liveexample{The example below demonstrates the `sax_parse()` function
17176 reading from string and processing the events with a user-defined SAX
17177 event consumer.,sax_parse}
17178
17179 @since version 3.2.0
17180 */
17181 template <typename SAX>
sax_parse(detail::input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true)17182 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
17183 input_format_t format = input_format_t::json,
17184 const bool strict = true)
17185 {
17186 assert(sax);
17187 switch (format)
17188 {
17189 case input_format_t::json:
17190 return parser(std::move(i)).sax_parse(sax, strict);
17191 default:
17192 return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
17193 }
17194 }
17195
17196 /*!
17197 @brief deserialize from an iterator range with contiguous storage
17198
17199 This function reads from an iterator range of a container with contiguous
17200 storage of 1-byte values. Compatible container types include
17201 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
17202 `std::initializer_list`. Furthermore, C-style arrays can be used with
17203 `std::begin()`/`std::end()`. User-defined containers can be used as long
17204 as they implement random-access iterators and a contiguous storage.
17205
17206 @pre The iterator range is contiguous. Violating this precondition yields
17207 undefined behavior. **This precondition is enforced with an assertion.**
17208 @pre Each element in the range has a size of 1 byte. Violating this
17209 precondition yields undefined behavior. **This precondition is enforced
17210 with a static assertion.**
17211
17212 @warning There is no way to enforce all preconditions at compile-time. If
17213 the function is called with noncompliant iterators and with
17214 assertions switched off, the behavior is undefined and will most
17215 likely yield segmentation violation.
17216
17217 @tparam IteratorType iterator of container with contiguous storage
17218 @param[in] first begin of the range to parse (included)
17219 @param[in] last end of the range to parse (excluded)
17220 @param[in] cb a parser callback function of type @ref parser_callback_t
17221 which is used to control the deserialization by filtering unwanted values
17222 (optional)
17223 @param[in] allow_exceptions whether to throw exceptions in case of a
17224 parse error (optional, true by default)
17225
17226 @return result of the deserialization
17227
17228 @throw parse_error.101 in case of an unexpected token
17229 @throw parse_error.102 if to_unicode fails or surrogate error
17230 @throw parse_error.103 if to_unicode fails
17231
17232 @complexity Linear in the length of the input. The parser is a predictive
17233 LL(1) parser. The complexity can be higher if the parser callback function
17234 @a cb has a super-linear complexity.
17235
17236 @note A UTF-8 byte order mark is silently ignored.
17237
17238 @liveexample{The example below demonstrates the `parse()` function reading
17239 from an iterator range.,parse__iteratortype__parser_callback_t}
17240
17241 @since version 2.0.3
17242 */
17243 template<class IteratorType, typename std::enable_if<
17244 std::is_base_of<
17245 std::random_access_iterator_tag,
17246 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)17247 static basic_json parse(IteratorType first, IteratorType last,
17248 const parser_callback_t cb = nullptr,
17249 const bool allow_exceptions = true)
17250 {
17251 basic_json result;
17252 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
17253 return result;
17254 }
17255
17256 template<class IteratorType, typename std::enable_if<
17257 std::is_base_of<
17258 std::random_access_iterator_tag,
17259 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)17260 static bool accept(IteratorType first, IteratorType last)
17261 {
17262 return parser(detail::input_adapter(first, last)).accept(true);
17263 }
17264
17265 template<class IteratorType, class SAX, typename std::enable_if<
17266 std::is_base_of<
17267 std::random_access_iterator_tag,
17268 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
sax_parse(IteratorType first,IteratorType last,SAX * sax)17269 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
17270 {
17271 return parser(detail::input_adapter(first, last)).sax_parse(sax);
17272 }
17273
17274 /*!
17275 @brief deserialize from stream
17276 @deprecated This stream operator is deprecated and will be removed in
17277 version 4.0.0 of the library. Please use
17278 @ref operator>>(std::istream&, basic_json&)
17279 instead; that is, replace calls like `j << i;` with `i >> j;`.
17280 @since version 1.0.0; deprecated since version 3.0.0
17281 */
17282 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)17283 friend std::istream& operator<<(basic_json& j, std::istream& i)
17284 {
17285 return operator>>(i, j);
17286 }
17287
17288 /*!
17289 @brief deserialize from stream
17290
17291 Deserializes an input stream to a JSON value.
17292
17293 @param[in,out] i input stream to read a serialized JSON value from
17294 @param[in,out] j JSON value to write the deserialized input to
17295
17296 @throw parse_error.101 in case of an unexpected token
17297 @throw parse_error.102 if to_unicode fails or surrogate error
17298 @throw parse_error.103 if to_unicode fails
17299
17300 @complexity Linear in the length of the input. The parser is a predictive
17301 LL(1) parser.
17302
17303 @note A UTF-8 byte order mark is silently ignored.
17304
17305 @liveexample{The example below shows how a JSON value is constructed by
17306 reading a serialization from a stream.,operator_deserialize}
17307
17308 @sa parse(std::istream&, const parser_callback_t) for a variant with a
17309 parser callback function to filter values while parsing
17310
17311 @since version 1.0.0
17312 */
operator >>(std::istream & i,basic_json & j)17313 friend std::istream& operator>>(std::istream& i, basic_json& j)
17314 {
17315 parser(detail::input_adapter(i)).parse(false, j);
17316 return i;
17317 }
17318
17319 /// @}
17320
17321 ///////////////////////////
17322 // convenience functions //
17323 ///////////////////////////
17324
17325 /*!
17326 @brief return the type as string
17327
17328 Returns the type name as string to be used in error messages - usually to
17329 indicate that a function was called on a wrong JSON type.
17330
17331 @return a string representation of a the @a m_type member:
17332 Value type | return value
17333 ----------- | -------------
17334 null | `"null"`
17335 boolean | `"boolean"`
17336 string | `"string"`
17337 number | `"number"` (for all number types)
17338 object | `"object"`
17339 array | `"array"`
17340 discarded | `"discarded"`
17341
17342 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17343
17344 @complexity Constant.
17345
17346 @liveexample{The following code exemplifies `type_name()` for all JSON
17347 types.,type_name}
17348
17349 @sa @ref type() -- return the type of the JSON value
17350 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
17351
17352 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
17353 since 3.0.0
17354 */
type_name() const17355 const char* type_name() const noexcept
17356 {
17357 {
17358 switch (m_type)
17359 {
17360 case value_t::null:
17361 return "null";
17362 case value_t::object:
17363 return "object";
17364 case value_t::array:
17365 return "array";
17366 case value_t::string:
17367 return "string";
17368 case value_t::boolean:
17369 return "boolean";
17370 case value_t::discarded:
17371 return "discarded";
17372 default:
17373 return "number";
17374 }
17375 }
17376 }
17377
17378
17379 private:
17380 //////////////////////
17381 // member variables //
17382 //////////////////////
17383
17384 /// the type of the current element
17385 value_t m_type = value_t::null;
17386
17387 /// the value of the current element
17388 json_value m_value = {};
17389
17390 //////////////////////////////////////////
17391 // binary serialization/deserialization //
17392 //////////////////////////////////////////
17393
17394 /// @name binary serialization/deserialization support
17395 /// @{
17396
17397 public:
17398 /*!
17399 @brief create a CBOR serialization of a given JSON value
17400
17401 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
17402 Binary Object Representation) serialization format. CBOR is a binary
17403 serialization format which aims to be more compact than JSON itself, yet
17404 more efficient to parse.
17405
17406 The library uses the following mapping from JSON values types to
17407 CBOR types according to the CBOR specification (RFC 7049):
17408
17409 JSON value type | value/range | CBOR type | first byte
17410 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
17411 null | `null` | Null | 0xF6
17412 boolean | `true` | True | 0xF5
17413 boolean | `false` | False | 0xF4
17414 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
17415 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
17416 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
17417 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
17418 number_integer | -24..-1 | Negative integer | 0x20..0x37
17419 number_integer | 0..23 | Integer | 0x00..0x17
17420 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
17421 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17422 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17423 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17424 number_unsigned | 0..23 | Integer | 0x00..0x17
17425 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
17426 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17427 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17428 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17429 number_float | *any value* | Double-Precision Float | 0xFB
17430 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
17431 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
17432 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
17433 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
17434 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
17435 array | *size*: 0..23 | array | 0x80..0x97
17436 array | *size*: 23..255 | array (1 byte follow) | 0x98
17437 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
17438 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
17439 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
17440 object | *size*: 0..23 | map | 0xA0..0xB7
17441 object | *size*: 23..255 | map (1 byte follow) | 0xB8
17442 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
17443 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
17444 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
17445
17446 @note The mapping is **complete** in the sense that any JSON value type
17447 can be converted to a CBOR value.
17448
17449 @note If NaN or Infinity are stored inside a JSON number, they are
17450 serialized properly. This behavior differs from the @ref dump()
17451 function which serializes NaN or Infinity to `null`.
17452
17453 @note The following CBOR types are not used in the conversion:
17454 - byte strings (0x40..0x5F)
17455 - UTF-8 strings terminated by "break" (0x7F)
17456 - arrays terminated by "break" (0x9F)
17457 - maps terminated by "break" (0xBF)
17458 - date/time (0xC0..0xC1)
17459 - bignum (0xC2..0xC3)
17460 - decimal fraction (0xC4)
17461 - bigfloat (0xC5)
17462 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17463 - expected conversions (0xD5..0xD7)
17464 - simple values (0xE0..0xF3, 0xF8)
17465 - undefined (0xF7)
17466 - half and single-precision floats (0xF9-0xFA)
17467 - break (0xFF)
17468
17469 @param[in] j JSON value to serialize
17470 @return MessagePack serialization as byte vector
17471
17472 @complexity Linear in the size of the JSON value @a j.
17473
17474 @liveexample{The example shows the serialization of a JSON value to a byte
17475 vector in CBOR format.,to_cbor}
17476
17477 @sa http://cbor.io
17478 @sa @ref from_cbor(detail::input_adapter, const bool strict) for the
17479 analogous deserialization
17480 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17481 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17482 related UBJSON format
17483
17484 @since version 2.0.9
17485 */
to_cbor(const basic_json & j)17486 static std::vector<uint8_t> to_cbor(const basic_json& j)
17487 {
17488 std::vector<uint8_t> result;
17489 to_cbor(j, result);
17490 return result;
17491 }
17492
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)17493 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
17494 {
17495 binary_writer<uint8_t>(o).write_cbor(j);
17496 }
17497
to_cbor(const basic_json & j,detail::output_adapter<char> o)17498 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
17499 {
17500 binary_writer<char>(o).write_cbor(j);
17501 }
17502
17503 /*!
17504 @brief create a MessagePack serialization of a given JSON value
17505
17506 Serializes a given JSON value @a j to a byte vector using the MessagePack
17507 serialization format. MessagePack is a binary serialization format which
17508 aims to be more compact than JSON itself, yet more efficient to parse.
17509
17510 The library uses the following mapping from JSON values types to
17511 MessagePack types according to the MessagePack specification:
17512
17513 JSON value type | value/range | MessagePack type | first byte
17514 --------------- | --------------------------------- | ---------------- | ----------
17515 null | `null` | nil | 0xC0
17516 boolean | `true` | true | 0xC3
17517 boolean | `false` | false | 0xC2
17518 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
17519 number_integer | -2147483648..-32769 | int32 | 0xD2
17520 number_integer | -32768..-129 | int16 | 0xD1
17521 number_integer | -128..-33 | int8 | 0xD0
17522 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
17523 number_integer | 0..127 | positive fixint | 0x00..0x7F
17524 number_integer | 128..255 | uint 8 | 0xCC
17525 number_integer | 256..65535 | uint 16 | 0xCD
17526 number_integer | 65536..4294967295 | uint 32 | 0xCE
17527 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
17528 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
17529 number_unsigned | 128..255 | uint 8 | 0xCC
17530 number_unsigned | 256..65535 | uint 16 | 0xCD
17531 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
17532 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
17533 number_float | *any value* | float 64 | 0xCB
17534 string | *length*: 0..31 | fixstr | 0xA0..0xBF
17535 string | *length*: 32..255 | str 8 | 0xD9
17536 string | *length*: 256..65535 | str 16 | 0xDA
17537 string | *length*: 65536..4294967295 | str 32 | 0xDB
17538 array | *size*: 0..15 | fixarray | 0x90..0x9F
17539 array | *size*: 16..65535 | array 16 | 0xDC
17540 array | *size*: 65536..4294967295 | array 32 | 0xDD
17541 object | *size*: 0..15 | fix map | 0x80..0x8F
17542 object | *size*: 16..65535 | map 16 | 0xDE
17543 object | *size*: 65536..4294967295 | map 32 | 0xDF
17544
17545 @note The mapping is **complete** in the sense that any JSON value type
17546 can be converted to a MessagePack value.
17547
17548 @note The following values can **not** be converted to a MessagePack value:
17549 - strings with more than 4294967295 bytes
17550 - arrays with more than 4294967295 elements
17551 - objects with more than 4294967295 elements
17552
17553 @note The following MessagePack types are not used in the conversion:
17554 - bin 8 - bin 32 (0xC4..0xC6)
17555 - ext 8 - ext 32 (0xC7..0xC9)
17556 - float 32 (0xCA)
17557 - fixext 1 - fixext 16 (0xD4..0xD8)
17558
17559 @note Any MessagePack output created @ref to_msgpack can be successfully
17560 parsed by @ref from_msgpack.
17561
17562 @note If NaN or Infinity are stored inside a JSON number, they are
17563 serialized properly. This behavior differs from the @ref dump()
17564 function which serializes NaN or Infinity to `null`.
17565
17566 @param[in] j JSON value to serialize
17567 @return MessagePack serialization as byte vector
17568
17569 @complexity Linear in the size of the JSON value @a j.
17570
17571 @liveexample{The example shows the serialization of a JSON value to a byte
17572 vector in MessagePack format.,to_msgpack}
17573
17574 @sa http://msgpack.org
17575 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
17576 analogous deserialization
17577 @sa @ref to_cbor(const basic_json& for the related CBOR format
17578 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17579 related UBJSON format
17580
17581 @since version 2.0.9
17582 */
to_msgpack(const basic_json & j)17583 static std::vector<uint8_t> to_msgpack(const basic_json& j)
17584 {
17585 std::vector<uint8_t> result;
17586 to_msgpack(j, result);
17587 return result;
17588 }
17589
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)17590 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
17591 {
17592 binary_writer<uint8_t>(o).write_msgpack(j);
17593 }
17594
to_msgpack(const basic_json & j,detail::output_adapter<char> o)17595 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
17596 {
17597 binary_writer<char>(o).write_msgpack(j);
17598 }
17599
17600 /*!
17601 @brief create a UBJSON serialization of a given JSON value
17602
17603 Serializes a given JSON value @a j to a byte vector using the UBJSON
17604 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
17605 than JSON itself, yet more efficient to parse.
17606
17607 The library uses the following mapping from JSON values types to
17608 UBJSON types according to the UBJSON specification:
17609
17610 JSON value type | value/range | UBJSON type | marker
17611 --------------- | --------------------------------- | ----------- | ------
17612 null | `null` | null | `Z`
17613 boolean | `true` | true | `T`
17614 boolean | `false` | false | `F`
17615 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
17616 number_integer | -2147483648..-32769 | int32 | `l`
17617 number_integer | -32768..-129 | int16 | `I`
17618 number_integer | -128..127 | int8 | `i`
17619 number_integer | 128..255 | uint8 | `U`
17620 number_integer | 256..32767 | int16 | `I`
17621 number_integer | 32768..2147483647 | int32 | `l`
17622 number_integer | 2147483648..9223372036854775807 | int64 | `L`
17623 number_unsigned | 0..127 | int8 | `i`
17624 number_unsigned | 128..255 | uint8 | `U`
17625 number_unsigned | 256..32767 | int16 | `I`
17626 number_unsigned | 32768..2147483647 | int32 | `l`
17627 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
17628 number_float | *any value* | float64 | `D`
17629 string | *with shortest length indicator* | string | `S`
17630 array | *see notes on optimized format* | array | `[`
17631 object | *see notes on optimized format* | map | `{`
17632
17633 @note The mapping is **complete** in the sense that any JSON value type
17634 can be converted to a UBJSON value.
17635
17636 @note The following values can **not** be converted to a UBJSON value:
17637 - strings with more than 9223372036854775807 bytes (theoretical)
17638 - unsigned integer numbers above 9223372036854775807
17639
17640 @note The following markers are not used in the conversion:
17641 - `Z`: no-op values are not created.
17642 - `C`: single-byte strings are serialized with `S` markers.
17643
17644 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
17645 by @ref from_ubjson.
17646
17647 @note If NaN or Infinity are stored inside a JSON number, they are
17648 serialized properly. This behavior differs from the @ref dump()
17649 function which serializes NaN or Infinity to `null`.
17650
17651 @note The optimized formats for containers are supported: Parameter
17652 @a use_size adds size information to the beginning of a container and
17653 removes the closing marker. Parameter @a use_type further checks
17654 whether all elements of a container have the same type and adds the
17655 type marker to the beginning of the container. The @a use_type
17656 parameter must only be used together with @a use_size = true. Note
17657 that @a use_size = true alone may result in larger representations -
17658 the benefit of this parameter is that the receiving side is
17659 immediately informed on the number of elements of the container.
17660
17661 @param[in] j JSON value to serialize
17662 @param[in] use_size whether to add size annotations to container types
17663 @param[in] use_type whether to add type annotations to container types
17664 (must be combined with @a use_size = true)
17665 @return UBJSON serialization as byte vector
17666
17667 @complexity Linear in the size of the JSON value @a j.
17668
17669 @liveexample{The example shows the serialization of a JSON value to a byte
17670 vector in UBJSON format.,to_ubjson}
17671
17672 @sa http://ubjson.org
17673 @sa @ref from_ubjson(detail::input_adapter, const bool strict) for the
17674 analogous deserialization
17675 @sa @ref to_cbor(const basic_json& for the related CBOR format
17676 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17677
17678 @since version 3.1.0
17679 */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)17680 static std::vector<uint8_t> to_ubjson(const basic_json& j,
17681 const bool use_size = false,
17682 const bool use_type = false)
17683 {
17684 std::vector<uint8_t> result;
17685 to_ubjson(j, result, use_size, use_type);
17686 return result;
17687 }
17688
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)17689 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
17690 const bool use_size = false, const bool use_type = false)
17691 {
17692 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
17693 }
17694
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)17695 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
17696 const bool use_size = false, const bool use_type = false)
17697 {
17698 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
17699 }
17700
17701 /*!
17702 @brief create a JSON value from an input in CBOR format
17703
17704 Deserializes a given input @a i to a JSON value using the CBOR (Concise
17705 Binary Object Representation) serialization format.
17706
17707 The library maps CBOR types to JSON value types as follows:
17708
17709 CBOR type | JSON value type | first byte
17710 ---------------------- | --------------- | ----------
17711 Integer | number_unsigned | 0x00..0x17
17712 Unsigned integer | number_unsigned | 0x18
17713 Unsigned integer | number_unsigned | 0x19
17714 Unsigned integer | number_unsigned | 0x1A
17715 Unsigned integer | number_unsigned | 0x1B
17716 Negative integer | number_integer | 0x20..0x37
17717 Negative integer | number_integer | 0x38
17718 Negative integer | number_integer | 0x39
17719 Negative integer | number_integer | 0x3A
17720 Negative integer | number_integer | 0x3B
17721 Negative integer | number_integer | 0x40..0x57
17722 UTF-8 string | string | 0x60..0x77
17723 UTF-8 string | string | 0x78
17724 UTF-8 string | string | 0x79
17725 UTF-8 string | string | 0x7A
17726 UTF-8 string | string | 0x7B
17727 UTF-8 string | string | 0x7F
17728 array | array | 0x80..0x97
17729 array | array | 0x98
17730 array | array | 0x99
17731 array | array | 0x9A
17732 array | array | 0x9B
17733 array | array | 0x9F
17734 map | object | 0xA0..0xB7
17735 map | object | 0xB8
17736 map | object | 0xB9
17737 map | object | 0xBA
17738 map | object | 0xBB
17739 map | object | 0xBF
17740 False | `false` | 0xF4
17741 True | `true` | 0xF5
17742 Nill | `null` | 0xF6
17743 Half-Precision Float | number_float | 0xF9
17744 Single-Precision Float | number_float | 0xFA
17745 Double-Precision Float | number_float | 0xFB
17746
17747 @warning The mapping is **incomplete** in the sense that not all CBOR
17748 types can be converted to a JSON value. The following CBOR types
17749 are not supported and will yield parse errors (parse_error.112):
17750 - byte strings (0x40..0x5F)
17751 - date/time (0xC0..0xC1)
17752 - bignum (0xC2..0xC3)
17753 - decimal fraction (0xC4)
17754 - bigfloat (0xC5)
17755 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17756 - expected conversions (0xD5..0xD7)
17757 - simple values (0xE0..0xF3, 0xF8)
17758 - undefined (0xF7)
17759
17760 @warning CBOR allows map keys of any type, whereas JSON only allows
17761 strings as keys in object values. Therefore, CBOR maps with keys
17762 other than UTF-8 strings are rejected (parse_error.113).
17763
17764 @note Any CBOR output created @ref to_cbor can be successfully parsed by
17765 @ref from_cbor.
17766
17767 @param[in] i an input in CBOR format convertible to an input adapter
17768 @param[in] strict whether to expect the input to be consumed until EOF
17769 (true by default)
17770 @param[in] allow_exceptions whether to throw exceptions in case of a
17771 parse error (optional, true by default)
17772
17773 @return deserialized JSON value
17774
17775 @throw parse_error.110 if the given input ends prematurely or the end of
17776 file was not reached when @a strict was set to true
17777 @throw parse_error.112 if unsupported features from CBOR were
17778 used in the given input @a v or if the input is not valid CBOR
17779 @throw parse_error.113 if a string was expected as map key, but not found
17780
17781 @complexity Linear in the size of the input @a i.
17782
17783 @liveexample{The example shows the deserialization of a byte vector in CBOR
17784 format to a JSON value.,from_cbor}
17785
17786 @sa http://cbor.io
17787 @sa @ref to_cbor(const basic_json&) for the analogous serialization
17788 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for the
17789 related MessagePack format
17790 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for the
17791 related UBJSON format
17792
17793 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17794 consume input adapters, removed start_index parameter, and added
17795 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17796 since 3.2.0
17797 */
from_cbor(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17798 static basic_json from_cbor(detail::input_adapter&& i,
17799 const bool strict = true,
17800 const bool allow_exceptions = true)
17801 {
17802 basic_json result;
17803 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17804 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
17805 return res ? result : basic_json(value_t::discarded);
17806 }
17807
17808 /*!
17809 @copydoc from_cbor(detail::input_adapter, const bool, const bool)
17810 */
17811 template<typename A1, typename A2,
17812 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_cbor(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)17813 static basic_json from_cbor(A1 && a1, A2 && a2,
17814 const bool strict = true,
17815 const bool allow_exceptions = true)
17816 {
17817 basic_json result;
17818 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17819 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
17820 return res ? result : basic_json(value_t::discarded);
17821 }
17822
17823 /*!
17824 @brief create a JSON value from an input in MessagePack format
17825
17826 Deserializes a given input @a i to a JSON value using the MessagePack
17827 serialization format.
17828
17829 The library maps MessagePack types to JSON value types as follows:
17830
17831 MessagePack type | JSON value type | first byte
17832 ---------------- | --------------- | ----------
17833 positive fixint | number_unsigned | 0x00..0x7F
17834 fixmap | object | 0x80..0x8F
17835 fixarray | array | 0x90..0x9F
17836 fixstr | string | 0xA0..0xBF
17837 nil | `null` | 0xC0
17838 false | `false` | 0xC2
17839 true | `true` | 0xC3
17840 float 32 | number_float | 0xCA
17841 float 64 | number_float | 0xCB
17842 uint 8 | number_unsigned | 0xCC
17843 uint 16 | number_unsigned | 0xCD
17844 uint 32 | number_unsigned | 0xCE
17845 uint 64 | number_unsigned | 0xCF
17846 int 8 | number_integer | 0xD0
17847 int 16 | number_integer | 0xD1
17848 int 32 | number_integer | 0xD2
17849 int 64 | number_integer | 0xD3
17850 str 8 | string | 0xD9
17851 str 16 | string | 0xDA
17852 str 32 | string | 0xDB
17853 array 16 | array | 0xDC
17854 array 32 | array | 0xDD
17855 map 16 | object | 0xDE
17856 map 32 | object | 0xDF
17857 negative fixint | number_integer | 0xE0-0xFF
17858
17859 @warning The mapping is **incomplete** in the sense that not all
17860 MessagePack types can be converted to a JSON value. The following
17861 MessagePack types are not supported and will yield parse errors:
17862 - bin 8 - bin 32 (0xC4..0xC6)
17863 - ext 8 - ext 32 (0xC7..0xC9)
17864 - fixext 1 - fixext 16 (0xD4..0xD8)
17865
17866 @note Any MessagePack output created @ref to_msgpack can be successfully
17867 parsed by @ref from_msgpack.
17868
17869 @param[in] i an input in MessagePack format convertible to an input
17870 adapter
17871 @param[in] strict whether to expect the input to be consumed until EOF
17872 (true by default)
17873 @param[in] allow_exceptions whether to throw exceptions in case of a
17874 parse error (optional, true by default)
17875
17876 @return deserialized JSON value
17877
17878 @throw parse_error.110 if the given input ends prematurely or the end of
17879 file was not reached when @a strict was set to true
17880 @throw parse_error.112 if unsupported features from MessagePack were
17881 used in the given input @a i or if the input is not valid MessagePack
17882 @throw parse_error.113 if a string was expected as map key, but not found
17883
17884 @complexity Linear in the size of the input @a i.
17885
17886 @liveexample{The example shows the deserialization of a byte vector in
17887 MessagePack format to a JSON value.,from_msgpack}
17888
17889 @sa http://msgpack.org
17890 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
17891 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17892 related CBOR format
17893 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for
17894 the related UBJSON format
17895
17896 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17897 consume input adapters, removed start_index parameter, and added
17898 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17899 since 3.2.0
17900 */
from_msgpack(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17901 static basic_json from_msgpack(detail::input_adapter&& i,
17902 const bool strict = true,
17903 const bool allow_exceptions = true)
17904 {
17905 basic_json result;
17906 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17907 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
17908 return res ? result : basic_json(value_t::discarded);
17909 }
17910
17911 /*!
17912 @copydoc from_msgpack(detail::input_adapter, const bool, const bool)
17913 */
17914 template<typename A1, typename A2,
17915 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_msgpack(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)17916 static basic_json from_msgpack(A1 && a1, A2 && a2,
17917 const bool strict = true,
17918 const bool allow_exceptions = true)
17919 {
17920 basic_json result;
17921 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17922 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
17923 return res ? result : basic_json(value_t::discarded);
17924 }
17925
17926 /*!
17927 @brief create a JSON value from an input in UBJSON format
17928
17929 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
17930 Binary JSON) serialization format.
17931
17932 The library maps UBJSON types to JSON value types as follows:
17933
17934 UBJSON type | JSON value type | marker
17935 ----------- | --------------------------------------- | ------
17936 no-op | *no value, next value is read* | `N`
17937 null | `null` | `Z`
17938 false | `false` | `F`
17939 true | `true` | `T`
17940 float32 | number_float | `d`
17941 float64 | number_float | `D`
17942 uint8 | number_unsigned | `U`
17943 int8 | number_integer | `i`
17944 int16 | number_integer | `I`
17945 int32 | number_integer | `l`
17946 int64 | number_integer | `L`
17947 string | string | `S`
17948 char | string | `C`
17949 array | array (optimized values are supported) | `[`
17950 object | object (optimized values are supported) | `{`
17951
17952 @note The mapping is **complete** in the sense that any UBJSON value can
17953 be converted to a JSON value.
17954
17955 @param[in] i an input in UBJSON format convertible to an input adapter
17956 @param[in] strict whether to expect the input to be consumed until EOF
17957 (true by default)
17958 @param[in] allow_exceptions whether to throw exceptions in case of a
17959 parse error (optional, true by default)
17960
17961 @return deserialized JSON value
17962
17963 @throw parse_error.110 if the given input ends prematurely or the end of
17964 file was not reached when @a strict was set to true
17965 @throw parse_error.112 if a parse error occurs
17966 @throw parse_error.113 if a string could not be parsed successfully
17967
17968 @complexity Linear in the size of the input @a i.
17969
17970 @liveexample{The example shows the deserialization of a byte vector in
17971 UBJSON format to a JSON value.,from_ubjson}
17972
17973 @sa http://ubjson.org
17974 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17975 analogous serialization
17976 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17977 related CBOR format
17978 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for
17979 the related MessagePack format
17980
17981 @since version 3.1.0; added @allow_exceptions parameter since 3.2.0
17982 */
from_ubjson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17983 static basic_json from_ubjson(detail::input_adapter&& i,
17984 const bool strict = true,
17985 const bool allow_exceptions = true)
17986 {
17987 basic_json result;
17988 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17989 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
17990 return res ? result : basic_json(value_t::discarded);
17991 }
17992
17993 /*!
17994 @copydoc from_ubjson(detail::input_adapter, const bool, const bool)
17995 */
17996 template<typename A1, typename A2,
17997 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_ubjson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)17998 static basic_json from_ubjson(A1 && a1, A2 && a2,
17999 const bool strict = true,
18000 const bool allow_exceptions = true)
18001 {
18002 basic_json result;
18003 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
18004 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
18005 return res ? result : basic_json(value_t::discarded);
18006 }
18007
18008 /// @}
18009
18010 //////////////////////////
18011 // JSON Pointer support //
18012 //////////////////////////
18013
18014 /// @name JSON Pointer functions
18015 /// @{
18016
18017 /*!
18018 @brief access specified element via JSON Pointer
18019
18020 Uses a JSON pointer to retrieve a reference to the respective JSON value.
18021 No bound checking is performed. Similar to @ref operator[](const typename
18022 object_t::key_type&), `null` values are created in arrays and objects if
18023 necessary.
18024
18025 In particular:
18026 - If the JSON pointer points to an object key that does not exist, it
18027 is created an filled with a `null` value before a reference to it
18028 is returned.
18029 - If the JSON pointer points to an array index that does not exist, it
18030 is created an filled with a `null` value before a reference to it
18031 is returned. All indices between the current maximum and the given
18032 index are also filled with `null`.
18033 - The special value `-` is treated as a synonym for the index past the
18034 end.
18035
18036 @param[in] ptr a JSON pointer
18037
18038 @return reference to the element pointed to by @a ptr
18039
18040 @complexity Constant.
18041
18042 @throw parse_error.106 if an array index begins with '0'
18043 @throw parse_error.109 if an array index was not a number
18044 @throw out_of_range.404 if the JSON pointer can not be resolved
18045
18046 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
18047
18048 @since version 2.0.0
18049 */
operator [](const json_pointer & ptr)18050 reference operator[](const json_pointer& ptr)
18051 {
18052 return ptr.get_unchecked(this);
18053 }
18054
18055 /*!
18056 @brief access specified element via JSON Pointer
18057
18058 Uses a JSON pointer to retrieve a reference to the respective JSON value.
18059 No bound checking is performed. The function does not change the JSON
18060 value; no `null` values are created. In particular, the the special value
18061 `-` yields an exception.
18062
18063 @param[in] ptr JSON pointer to the desired element
18064
18065 @return const reference to the element pointed to by @a ptr
18066
18067 @complexity Constant.
18068
18069 @throw parse_error.106 if an array index begins with '0'
18070 @throw parse_error.109 if an array index was not a number
18071 @throw out_of_range.402 if the array index '-' is used
18072 @throw out_of_range.404 if the JSON pointer can not be resolved
18073
18074 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
18075
18076 @since version 2.0.0
18077 */
operator [](const json_pointer & ptr) const18078 const_reference operator[](const json_pointer& ptr) const
18079 {
18080 return ptr.get_unchecked(this);
18081 }
18082
18083 /*!
18084 @brief access specified element via JSON Pointer
18085
18086 Returns a reference to the element at with specified JSON pointer @a ptr,
18087 with bounds checking.
18088
18089 @param[in] ptr JSON pointer to the desired element
18090
18091 @return reference to the element pointed to by @a ptr
18092
18093 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18094 begins with '0'. See example below.
18095
18096 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18097 is not a number. See example below.
18098
18099 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18100 is out of range. See example below.
18101
18102 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18103 pointer @a ptr. As `at` provides checked access (and no elements are
18104 implicitly inserted), the index '-' is always invalid. See example below.
18105
18106 @throw out_of_range.403 if the JSON pointer describes a key of an object
18107 which cannot be found. See example below.
18108
18109 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18110 See example below.
18111
18112 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18113 changes in the JSON value.
18114
18115 @complexity Constant.
18116
18117 @since version 2.0.0
18118
18119 @liveexample{The behavior is shown in the example.,at_json_pointer}
18120 */
at(const json_pointer & ptr)18121 reference at(const json_pointer& ptr)
18122 {
18123 return ptr.get_checked(this);
18124 }
18125
18126 /*!
18127 @brief access specified element via JSON Pointer
18128
18129 Returns a const reference to the element at with specified JSON pointer @a
18130 ptr, with bounds checking.
18131
18132 @param[in] ptr JSON pointer to the desired element
18133
18134 @return reference to the element pointed to by @a ptr
18135
18136 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18137 begins with '0'. See example below.
18138
18139 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18140 is not a number. See example below.
18141
18142 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18143 is out of range. See example below.
18144
18145 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18146 pointer @a ptr. As `at` provides checked access (and no elements are
18147 implicitly inserted), the index '-' is always invalid. See example below.
18148
18149 @throw out_of_range.403 if the JSON pointer describes a key of an object
18150 which cannot be found. See example below.
18151
18152 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18153 See example below.
18154
18155 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18156 changes in the JSON value.
18157
18158 @complexity Constant.
18159
18160 @since version 2.0.0
18161
18162 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
18163 */
at(const json_pointer & ptr) const18164 const_reference at(const json_pointer& ptr) const
18165 {
18166 return ptr.get_checked(this);
18167 }
18168
18169 /*!
18170 @brief return flattened JSON value
18171
18172 The function creates a JSON object whose keys are JSON pointers (see [RFC
18173 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
18174 primitive. The original JSON value can be restored using the @ref
18175 unflatten() function.
18176
18177 @return an object that maps JSON pointers to primitive values
18178
18179 @note Empty objects and arrays are flattened to `null` and will not be
18180 reconstructed correctly by the @ref unflatten() function.
18181
18182 @complexity Linear in the size the JSON value.
18183
18184 @liveexample{The following code shows how a JSON object is flattened to an
18185 object whose keys consist of JSON pointers.,flatten}
18186
18187 @sa @ref unflatten() for the reverse function
18188
18189 @since version 2.0.0
18190 */
flatten() const18191 basic_json flatten() const
18192 {
18193 basic_json result(value_t::object);
18194 json_pointer::flatten("", *this, result);
18195 return result;
18196 }
18197
18198 /*!
18199 @brief unflatten a previously flattened JSON value
18200
18201 The function restores the arbitrary nesting of a JSON value that has been
18202 flattened before using the @ref flatten() function. The JSON value must
18203 meet certain constraints:
18204 1. The value must be an object.
18205 2. The keys must be JSON pointers (see
18206 [RFC 6901](https://tools.ietf.org/html/rfc6901))
18207 3. The mapped values must be primitive JSON types.
18208
18209 @return the original JSON from a flattened version
18210
18211 @note Empty objects and arrays are flattened by @ref flatten() to `null`
18212 values and can not unflattened to their original type. Apart from
18213 this example, for a JSON value `j`, the following is always true:
18214 `j == j.flatten().unflatten()`.
18215
18216 @complexity Linear in the size the JSON value.
18217
18218 @throw type_error.314 if value is not an object
18219 @throw type_error.315 if object values are not primitive
18220
18221 @liveexample{The following code shows how a flattened JSON object is
18222 unflattened into the original nested JSON object.,unflatten}
18223
18224 @sa @ref flatten() for the reverse function
18225
18226 @since version 2.0.0
18227 */
unflatten() const18228 basic_json unflatten() const
18229 {
18230 return json_pointer::unflatten(*this);
18231 }
18232
18233 /// @}
18234
18235 //////////////////////////
18236 // JSON Patch functions //
18237 //////////////////////////
18238
18239 /// @name JSON Patch functions
18240 /// @{
18241
18242 /*!
18243 @brief applies a JSON patch
18244
18245 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
18246 expressing a sequence of operations to apply to a JSON) document. With
18247 this function, a JSON Patch is applied to the current JSON value by
18248 executing all operations from the patch.
18249
18250 @param[in] json_patch JSON patch document
18251 @return patched document
18252
18253 @note The application of a patch is atomic: Either all operations succeed
18254 and the patched document is returned or an exception is thrown. In
18255 any case, the original value is not changed: the patch is applied
18256 to a copy of the value.
18257
18258 @throw parse_error.104 if the JSON patch does not consist of an array of
18259 objects
18260
18261 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
18262 attributes are missing); example: `"operation add must have member path"`
18263
18264 @throw out_of_range.401 if an array index is out of range.
18265
18266 @throw out_of_range.403 if a JSON pointer inside the patch could not be
18267 resolved successfully in the current JSON value; example: `"key baz not
18268 found"`
18269
18270 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
18271 "move")
18272
18273 @throw other_error.501 if "test" operation was unsuccessful
18274
18275 @complexity Linear in the size of the JSON value and the length of the
18276 JSON patch. As usually only a fraction of the JSON value is affected by
18277 the patch, the complexity can usually be neglected.
18278
18279 @liveexample{The following code shows how a JSON patch is applied to a
18280 value.,patch}
18281
18282 @sa @ref diff -- create a JSON patch by comparing two JSON values
18283
18284 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18285 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
18286
18287 @since version 2.0.0
18288 */
patch(const basic_json & json_patch) const18289 basic_json patch(const basic_json& json_patch) const
18290 {
18291 // make a working copy to apply the patch to
18292 basic_json result = *this;
18293
18294 // the valid JSON Patch operations
18295 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
18296
18297 const auto get_op = [](const std::string & op)
18298 {
18299 if (op == "add")
18300 {
18301 return patch_operations::add;
18302 }
18303 if (op == "remove")
18304 {
18305 return patch_operations::remove;
18306 }
18307 if (op == "replace")
18308 {
18309 return patch_operations::replace;
18310 }
18311 if (op == "move")
18312 {
18313 return patch_operations::move;
18314 }
18315 if (op == "copy")
18316 {
18317 return patch_operations::copy;
18318 }
18319 if (op == "test")
18320 {
18321 return patch_operations::test;
18322 }
18323
18324 return patch_operations::invalid;
18325 };
18326
18327 // wrapper for "add" operation; add value at ptr
18328 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
18329 {
18330 // adding to the root of the target document means replacing it
18331 if (ptr.is_root())
18332 {
18333 result = val;
18334 }
18335 else
18336 {
18337 // make sure the top element of the pointer exists
18338 json_pointer top_pointer = ptr.top();
18339 if (top_pointer != ptr)
18340 {
18341 result.at(top_pointer);
18342 }
18343
18344 // get reference to parent of JSON pointer ptr
18345 const auto last_path = ptr.pop_back();
18346 basic_json& parent = result[ptr];
18347
18348 switch (parent.m_type)
18349 {
18350 case value_t::null:
18351 case value_t::object:
18352 {
18353 // use operator[] to add value
18354 parent[last_path] = val;
18355 break;
18356 }
18357
18358 case value_t::array:
18359 {
18360 if (last_path == "-")
18361 {
18362 // special case: append to back
18363 parent.push_back(val);
18364 }
18365 else
18366 {
18367 const auto idx = json_pointer::array_index(last_path);
18368 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
18369 {
18370 // avoid undefined behavior
18371 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
18372 }
18373 else
18374 {
18375 // default case: insert add offset
18376 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
18377 }
18378 }
18379 break;
18380 }
18381
18382 // LCOV_EXCL_START
18383 default:
18384 {
18385 // if there exists a parent it cannot be primitive
18386 assert(false);
18387 }
18388 // LCOV_EXCL_STOP
18389 }
18390 }
18391 };
18392
18393 // wrapper for "remove" operation; remove value at ptr
18394 const auto operation_remove = [&result](json_pointer & ptr)
18395 {
18396 // get reference to parent of JSON pointer ptr
18397 const auto last_path = ptr.pop_back();
18398 basic_json& parent = result.at(ptr);
18399
18400 // remove child
18401 if (parent.is_object())
18402 {
18403 // perform range check
18404 auto it = parent.find(last_path);
18405 if (JSON_LIKELY(it != parent.end()))
18406 {
18407 parent.erase(it);
18408 }
18409 else
18410 {
18411 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
18412 }
18413 }
18414 else if (parent.is_array())
18415 {
18416 // note erase performs range check
18417 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
18418 }
18419 };
18420
18421 // type check: top level value must be an array
18422 if (JSON_UNLIKELY(not json_patch.is_array()))
18423 {
18424 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18425 }
18426
18427 // iterate and apply the operations
18428 for (const auto& val : json_patch)
18429 {
18430 // wrapper to get a value for an operation
18431 const auto get_value = [&val](const std::string & op,
18432 const std::string & member,
18433 bool string_type) -> basic_json &
18434 {
18435 // find value
18436 auto it = val.m_value.object->find(member);
18437
18438 // context-sensitive error message
18439 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
18440
18441 // check if desired value is present
18442 if (JSON_UNLIKELY(it == val.m_value.object->end()))
18443 {
18444 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
18445 }
18446
18447 // check if result is of type string
18448 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
18449 {
18450 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
18451 }
18452
18453 // no error: return value
18454 return it->second;
18455 };
18456
18457 // type check: every element of the array must be an object
18458 if (JSON_UNLIKELY(not val.is_object()))
18459 {
18460 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18461 }
18462
18463 // collect mandatory members
18464 const std::string op = get_value("op", "op", true);
18465 const std::string path = get_value(op, "path", true);
18466 json_pointer ptr(path);
18467
18468 switch (get_op(op))
18469 {
18470 case patch_operations::add:
18471 {
18472 operation_add(ptr, get_value("add", "value", false));
18473 break;
18474 }
18475
18476 case patch_operations::remove:
18477 {
18478 operation_remove(ptr);
18479 break;
18480 }
18481
18482 case patch_operations::replace:
18483 {
18484 // the "path" location must exist - use at()
18485 result.at(ptr) = get_value("replace", "value", false);
18486 break;
18487 }
18488
18489 case patch_operations::move:
18490 {
18491 const std::string from_path = get_value("move", "from", true);
18492 json_pointer from_ptr(from_path);
18493
18494 // the "from" location must exist - use at()
18495 basic_json v = result.at(from_ptr);
18496
18497 // The move operation is functionally identical to a
18498 // "remove" operation on the "from" location, followed
18499 // immediately by an "add" operation at the target
18500 // location with the value that was just removed.
18501 operation_remove(from_ptr);
18502 operation_add(ptr, v);
18503 break;
18504 }
18505
18506 case patch_operations::copy:
18507 {
18508 const std::string from_path = get_value("copy", "from", true);
18509 const json_pointer from_ptr(from_path);
18510
18511 // the "from" location must exist - use at()
18512 basic_json v = result.at(from_ptr);
18513
18514 // The copy is functionally identical to an "add"
18515 // operation at the target location using the value
18516 // specified in the "from" member.
18517 operation_add(ptr, v);
18518 break;
18519 }
18520
18521 case patch_operations::test:
18522 {
18523 bool success = false;
18524 JSON_TRY
18525 {
18526 // check if "value" matches the one at "path"
18527 // the "path" location must exist - use at()
18528 success = (result.at(ptr) == get_value("test", "value", false));
18529 }
18530 JSON_INTERNAL_CATCH (out_of_range&)
18531 {
18532 // ignore out of range errors: success remains false
18533 }
18534
18535 // throw an exception if test fails
18536 if (JSON_UNLIKELY(not success))
18537 {
18538 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
18539 }
18540
18541 break;
18542 }
18543
18544 case patch_operations::invalid:
18545 {
18546 // op must be "add", "remove", "replace", "move", "copy", or
18547 // "test"
18548 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
18549 }
18550 }
18551 }
18552
18553 return result;
18554 }
18555
18556 /*!
18557 @brief creates a diff as a JSON patch
18558
18559 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
18560 be changed into the value @a target by calling @ref patch function.
18561
18562 @invariant For two JSON values @a source and @a target, the following code
18563 yields always `true`:
18564 @code {.cpp}
18565 source.patch(diff(source, target)) == target;
18566 @endcode
18567
18568 @note Currently, only `remove`, `add`, and `replace` operations are
18569 generated.
18570
18571 @param[in] source JSON value to compare from
18572 @param[in] target JSON value to compare against
18573 @param[in] path helper value to create JSON pointers
18574
18575 @return a JSON patch to convert the @a source to @a target
18576
18577 @complexity Linear in the lengths of @a source and @a target.
18578
18579 @liveexample{The following code shows how a JSON patch is created as a
18580 diff for two JSON values.,diff}
18581
18582 @sa @ref patch -- apply a JSON patch
18583 @sa @ref merge_patch -- apply a JSON Merge Patch
18584
18585 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18586
18587 @since version 2.0.0
18588 */
diff(const basic_json & source,const basic_json & target,const std::string & path="")18589 static basic_json diff(const basic_json& source, const basic_json& target,
18590 const std::string& path = "")
18591 {
18592 // the patch
18593 basic_json result(value_t::array);
18594
18595 // if the values are the same, return empty patch
18596 if (source == target)
18597 {
18598 return result;
18599 }
18600
18601 if (source.type() != target.type())
18602 {
18603 // different types: replace value
18604 result.push_back(
18605 {
18606 {"op", "replace"}, {"path", path}, {"value", target}
18607 });
18608 }
18609 else
18610 {
18611 switch (source.type())
18612 {
18613 case value_t::array:
18614 {
18615 // first pass: traverse common elements
18616 std::size_t i = 0;
18617 while (i < source.size() and i < target.size())
18618 {
18619 // recursive call to compare array values at index i
18620 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
18621 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18622 ++i;
18623 }
18624
18625 // i now reached the end of at least one array
18626 // in a second pass, traverse the remaining elements
18627
18628 // remove my remaining elements
18629 const auto end_index = static_cast<difference_type>(result.size());
18630 while (i < source.size())
18631 {
18632 // add operations in reverse order to avoid invalid
18633 // indices
18634 result.insert(result.begin() + end_index, object(
18635 {
18636 {"op", "remove"},
18637 {"path", path + "/" + std::to_string(i)}
18638 }));
18639 ++i;
18640 }
18641
18642 // add other remaining elements
18643 while (i < target.size())
18644 {
18645 result.push_back(
18646 {
18647 {"op", "add"},
18648 {"path", path + "/" + std::to_string(i)},
18649 {"value", target[i]}
18650 });
18651 ++i;
18652 }
18653
18654 break;
18655 }
18656
18657 case value_t::object:
18658 {
18659 // first pass: traverse this object's elements
18660 for (auto it = source.cbegin(); it != source.cend(); ++it)
18661 {
18662 // escape the key name to be used in a JSON patch
18663 const auto key = json_pointer::escape(it.key());
18664
18665 if (target.find(it.key()) != target.end())
18666 {
18667 // recursive call to compare object values at key it
18668 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
18669 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18670 }
18671 else
18672 {
18673 // found a key that is not in o -> remove it
18674 result.push_back(object(
18675 {
18676 {"op", "remove"}, {"path", path + "/" + key}
18677 }));
18678 }
18679 }
18680
18681 // second pass: traverse other object's elements
18682 for (auto it = target.cbegin(); it != target.cend(); ++it)
18683 {
18684 if (source.find(it.key()) == source.end())
18685 {
18686 // found a key that is not in this -> add it
18687 const auto key = json_pointer::escape(it.key());
18688 result.push_back(
18689 {
18690 {"op", "add"}, {"path", path + "/" + key},
18691 {"value", it.value()}
18692 });
18693 }
18694 }
18695
18696 break;
18697 }
18698
18699 default:
18700 {
18701 // both primitive type: replace value
18702 result.push_back(
18703 {
18704 {"op", "replace"}, {"path", path}, {"value", target}
18705 });
18706 break;
18707 }
18708 }
18709 }
18710
18711 return result;
18712 }
18713
18714 /// @}
18715
18716 ////////////////////////////////
18717 // JSON Merge Patch functions //
18718 ////////////////////////////////
18719
18720 /// @name JSON Merge Patch functions
18721 /// @{
18722
18723 /*!
18724 @brief applies a JSON Merge Patch
18725
18726 The merge patch format is primarily intended for use with the HTTP PATCH
18727 method as a means of describing a set of modifications to a target
18728 resource's content. This function applies a merge patch to the current
18729 JSON value.
18730
18731 The function implements the following algorithm from Section 2 of
18732 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
18733
18734 ```
18735 define MergePatch(Target, Patch):
18736 if Patch is an Object:
18737 if Target is not an Object:
18738 Target = {} // Ignore the contents and set it to an empty Object
18739 for each Name/Value pair in Patch:
18740 if Value is null:
18741 if Name exists in Target:
18742 remove the Name/Value pair from Target
18743 else:
18744 Target[Name] = MergePatch(Target[Name], Value)
18745 return Target
18746 else:
18747 return Patch
18748 ```
18749
18750 Thereby, `Target` is the current object; that is, the patch is applied to
18751 the current value.
18752
18753 @param[in] patch the patch to apply
18754
18755 @complexity Linear in the lengths of @a patch.
18756
18757 @liveexample{The following code shows how a JSON Merge Patch is applied to
18758 a JSON document.,merge_patch}
18759
18760 @sa @ref patch -- apply a JSON patch
18761 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
18762
18763 @since version 3.0.0
18764 */
merge_patch(const basic_json & patch)18765 void merge_patch(const basic_json& patch)
18766 {
18767 if (patch.is_object())
18768 {
18769 if (not is_object())
18770 {
18771 *this = object();
18772 }
18773 for (auto it = patch.begin(); it != patch.end(); ++it)
18774 {
18775 if (it.value().is_null())
18776 {
18777 erase(it.key());
18778 }
18779 else
18780 {
18781 operator[](it.key()).merge_patch(it.value());
18782 }
18783 }
18784 }
18785 else
18786 {
18787 *this = patch;
18788 }
18789 }
18790
18791 /// @}
18792 };
18793 } // namespace nlohmann
18794
18795 ///////////////////////
18796 // nonmember support //
18797 ///////////////////////
18798
18799 // specialization of std::swap, and std::hash
18800 namespace std
18801 {
18802 /*!
18803 @brief exchanges the values of two JSON objects
18804
18805 @since version 1.0.0
18806 */
18807 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)18808 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
18809 is_nothrow_move_constructible<nlohmann::json>::value and
18810 is_nothrow_move_assignable<nlohmann::json>::value
18811 )
18812 {
18813 j1.swap(j2);
18814 }
18815
18816 /// hash value for JSON objects
18817 template<>
18818 struct hash<nlohmann::json>
18819 {
18820 /*!
18821 @brief return a hash value for a JSON object
18822
18823 @since version 1.0.0
18824 */
operator ()std::hash18825 std::size_t operator()(const nlohmann::json& j) const
18826 {
18827 // a naive hashing via the string representation
18828 const auto& h = hash<nlohmann::json::string_t>();
18829 return h(j.dump());
18830 }
18831 };
18832
18833 /// specialization for std::less<value_t>
18834 /// @note: do not remove the space after '<',
18835 /// see https://github.com/nlohmann/json/pull/679
18836 template<>
18837 struct less< ::nlohmann::detail::value_t>
18838 {
18839 /*!
18840 @brief compare two value_t enum values
18841 @since version 3.0.0
18842 */
operator ()std::less18843 bool operator()(nlohmann::detail::value_t lhs,
18844 nlohmann::detail::value_t rhs) const noexcept
18845 {
18846 return nlohmann::detail::operator<(lhs, rhs);
18847 }
18848 };
18849
18850 } // namespace std
18851
18852 /*!
18853 @brief user-defined string literal for JSON values
18854
18855 This operator implements a user-defined string literal for JSON objects. It
18856 can be used by adding `"_json"` to a string literal and returns a JSON object
18857 if no parse error occurred.
18858
18859 @param[in] s a string representation of a JSON object
18860 @param[in] n the length of string @a s
18861 @return a JSON object
18862
18863 @since version 1.0.0
18864 */
operator ""_json(const char * s,std::size_t n)18865 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
18866 {
18867 return nlohmann::json::parse(s, s + n);
18868 }
18869
18870 /*!
18871 @brief user-defined string literal for JSON pointer
18872
18873 This operator implements a user-defined string literal for JSON Pointers. It
18874 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
18875 object if no parse error occurred.
18876
18877 @param[in] s a string representation of a JSON Pointer
18878 @param[in] n the length of string @a s
18879 @return a JSON pointer object
18880
18881 @since version 2.0.0
18882 */
operator ""_json_pointer(const char * s,std::size_t n)18883 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
18884 {
18885 return nlohmann::json::json_pointer(std::string(s, n));
18886 }
18887
18888 // #include <nlohmann/detail/macro_unscope.hpp>
18889
18890
18891 // restore GCC/clang diagnostic settings
18892 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
18893 #pragma GCC diagnostic pop
18894 #endif
18895 #if defined(__clang__)
18896 #pragma GCC diagnostic pop
18897 #endif
18898
18899 // clean up
18900 #undef JSON_INTERNAL_CATCH
18901 #undef JSON_CATCH
18902 #undef JSON_THROW
18903 #undef JSON_TRY
18904 #undef JSON_LIKELY
18905 #undef JSON_UNLIKELY
18906 #undef JSON_DEPRECATED
18907 #undef JSON_HAS_CPP_14
18908 #undef JSON_HAS_CPP_17
18909 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
18910 #undef NLOHMANN_BASIC_JSON_TPL
18911 #undef NLOHMANN_JSON_HAS_HELPER
18912
18913
18914 #endif
18915