1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.3.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 3
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__) < 40800
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 #undef JSON_INTERNAL_CATCH
181 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
182 #endif
183 #if defined(JSON_INTERNAL_CATCH_USER)
184 #undef JSON_INTERNAL_CATCH
185 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
186 #endif
187
188 // manual branch prediction
189 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
190 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
191 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
192 #else
193 #define JSON_LIKELY(x) x
194 #define JSON_UNLIKELY(x) x
195 #endif
196
197 // C++ language standard detection
198 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
199 #define JSON_HAS_CPP_17
200 #define JSON_HAS_CPP_14
201 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
202 #define JSON_HAS_CPP_14
203 #endif
204
205 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
206 // may be removed in the future once the class is split.
207
208 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
209 template<template<typename, typename, typename...> class ObjectType, \
210 template<typename, typename...> class ArrayType, \
211 class StringType, class BooleanType, class NumberIntegerType, \
212 class NumberUnsignedType, class NumberFloatType, \
213 template<typename> class AllocatorType, \
214 template<typename, typename = void> class JSONSerializer>
215
216 #define NLOHMANN_BASIC_JSON_TPL \
217 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
218 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
219 AllocatorType, JSONSerializer>
220
221 // #include <nlohmann/detail/meta/cpp_future.hpp>
222
223
224 #include <ciso646> // not
225 #include <cstddef> // size_t
226 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
227
228 namespace nlohmann
229 {
230 namespace detail
231 {
232 // alias templates to reduce boilerplate
233 template<bool B, typename T = void>
234 using enable_if_t = typename std::enable_if<B, T>::type;
235
236 template<typename T>
237 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
238
239 // implementation of C++14 index_sequence and affiliates
240 // source: https://stackoverflow.com/a/32223343
241 template<std::size_t... Ints>
242 struct index_sequence
243 {
244 using type = index_sequence;
245 using value_type = std::size_t;
sizenlohmann::detail::index_sequence246 static constexpr std::size_t size() noexcept
247 {
248 return sizeof...(Ints);
249 }
250 };
251
252 template<class Sequence1, class Sequence2>
253 struct merge_and_renumber;
254
255 template<std::size_t... I1, std::size_t... I2>
256 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
257 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
258
259 template<std::size_t N>
260 struct make_index_sequence
261 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
262 typename make_index_sequence < N - N / 2 >::type > {};
263
264 template<> struct make_index_sequence<0> : index_sequence<> {};
265 template<> struct make_index_sequence<1> : index_sequence<0> {};
266
267 template<typename... Ts>
268 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
269
270 // dispatch utility (taken from ranges-v3)
271 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
272 template<> struct priority_tag<0> {};
273
274 // taken from ranges-v3
275 template<typename T>
276 struct static_const
277 {
278 static constexpr T value{};
279 };
280
281 template<typename T>
282 constexpr T static_const<T>::value;
283 }
284 }
285
286 // #include <nlohmann/detail/meta/type_traits.hpp>
287
288
289 #include <ciso646> // not
290 #include <limits> // numeric_limits
291 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
292 #include <utility> // declval
293
294 // #include <nlohmann/json_fwd.hpp>
295
296 // #include <nlohmann/detail/meta/cpp_future.hpp>
297
298 // #include <nlohmann/detail/meta/detected.hpp>
299
300
301 #include <type_traits>
302
303 // #include <nlohmann/detail/meta/void_t.hpp>
304
305
306 namespace nlohmann
307 {
308 namespace detail
309 {
310 template <typename ...Ts> struct make_void
311 {
312 using type = void;
313 };
314 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
315 }
316 }
317
318
319 // http://en.cppreference.com/w/cpp/experimental/is_detected
320 namespace nlohmann
321 {
322 namespace detail
323 {
324 struct nonesuch
325 {
326 nonesuch() = delete;
327 ~nonesuch() = delete;
328 nonesuch(nonesuch const&) = delete;
329 void operator=(nonesuch const&) = delete;
330 };
331
332 template <class Default,
333 class AlwaysVoid,
334 template <class...> class Op,
335 class... Args>
336 struct detector
337 {
338 using value_t = std::false_type;
339 using type = Default;
340 };
341
342 template <class Default, template <class...> class Op, class... Args>
343 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
344 {
345 using value_t = std::true_type;
346 using type = Op<Args...>;
347 };
348
349 template <template <class...> class Op, class... Args>
350 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
351
352 template <template <class...> class Op, class... Args>
353 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
354
355 template <class Default, template <class...> class Op, class... Args>
356 using detected_or = detector<Default, void, Op, Args...>;
357
358 template <class Default, template <class...> class Op, class... Args>
359 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
360
361 template <class Expected, template <class...> class Op, class... Args>
362 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
363
364 template <class To, template <class...> class Op, class... Args>
365 using is_detected_convertible =
366 std::is_convertible<detected_t<Op, Args...>, To>;
367 }
368 }
369
370 // #include <nlohmann/detail/macro_scope.hpp>
371
372
373 namespace nlohmann
374 {
375 /*!
376 @brief detail namespace with internal helper functions
377
378 This namespace collects functions that should not be exposed,
379 implementations of some @ref basic_json methods, and meta-programming helpers.
380
381 @since version 2.1.0
382 */
383 namespace detail
384 {
385 /////////////
386 // helpers //
387 /////////////
388
389 template<typename> struct is_basic_json : std::false_type {};
390
391 NLOHMANN_BASIC_JSON_TPL_DECLARATION
392 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
393
394 //////////////////////////
395 // aliases for detected //
396 //////////////////////////
397
398 template <typename T>
399 using mapped_type_t = typename T::mapped_type;
400
401 template <typename T>
402 using key_type_t = typename T::key_type;
403
404 template <typename T>
405 using value_type_t = typename T::value_type;
406
407 template <typename T>
408 using difference_type_t = typename T::difference_type;
409
410 template <typename T>
411 using pointer_t = typename T::pointer;
412
413 template <typename T>
414 using reference_t = typename T::reference;
415
416 template <typename T>
417 using iterator_category_t = typename T::iterator_category;
418
419 template <typename T>
420 using iterator_t = typename T::iterator;
421
422 template <typename T, typename... Args>
423 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
424
425 template <typename T, typename... Args>
426 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
427
428 template <typename T, typename U>
429 using get_template_function = decltype(std::declval<T>().template get<U>());
430
431 ///////////////////
432 // is_ functions //
433 ///////////////////
434
435 template <typename T, typename = void>
436 struct is_iterator_traits : std::false_type {};
437
438 template <typename T>
439 struct is_iterator_traits<std::iterator_traits<T>>
440 {
441 private:
442 using traits = std::iterator_traits<T>;
443
444 public:
445 static constexpr auto value =
446 is_detected<value_type_t, traits>::value &&
447 is_detected<difference_type_t, traits>::value &&
448 is_detected<pointer_t, traits>::value &&
449 is_detected<iterator_category_t, traits>::value &&
450 is_detected<reference_t, traits>::value;
451 };
452
453 // source: https://stackoverflow.com/a/37193089/4116453
454
455 template <typename T, typename = void>
456 struct is_complete_type : std::false_type {};
457
458 template <typename T>
459 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
460
461 template <typename BasicJsonType, typename CompatibleObjectType,
462 typename = void>
463 struct is_compatible_object_type_impl : std::false_type {};
464
465 template <typename BasicJsonType, typename CompatibleObjectType>
466 struct is_compatible_object_type_impl <
467 BasicJsonType, CompatibleObjectType,
468 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
469 is_detected<key_type_t, CompatibleObjectType>::value >>
470 {
471
472 using object_t = typename BasicJsonType::object_t;
473
474 // macOS's is_constructible does not play well with nonesuch...
475 static constexpr bool value =
476 std::is_constructible<typename object_t::key_type,
477 typename CompatibleObjectType::key_type>::value and
478 std::is_constructible<typename object_t::mapped_type,
479 typename CompatibleObjectType::mapped_type>::value;
480 };
481
482 template <typename BasicJsonType, typename CompatibleObjectType>
483 struct is_compatible_object_type
484 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
485
486 template <typename BasicJsonType, typename CompatibleStringType,
487 typename = void>
488 struct is_compatible_string_type_impl : std::false_type {};
489
490 template <typename BasicJsonType, typename CompatibleStringType>
491 struct is_compatible_string_type_impl <
492 BasicJsonType, CompatibleStringType,
493 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
494 value_type_t, CompatibleStringType>::value >>
495 {
496 static constexpr auto value =
497 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
498 };
499
500 template <typename BasicJsonType, typename CompatibleStringType>
501 struct is_compatible_string_type
502 : is_compatible_string_type_impl<BasicJsonType, CompatibleStringType> {};
503
504 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
505 struct is_compatible_array_type_impl : std::false_type {};
506
507 template <typename BasicJsonType, typename CompatibleArrayType>
508 struct is_compatible_array_type_impl <
509 BasicJsonType, CompatibleArrayType,
510 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
511 is_detected<iterator_t, CompatibleArrayType>::value >>
512 {
513 // This is needed because json_reverse_iterator has a ::iterator type...
514 // Therefore it is detected as a CompatibleArrayType.
515 // The real fix would be to have an Iterable concept.
516 static constexpr bool value = not is_iterator_traits<std::iterator_traits<CompatibleArrayType>>::value;
517 };
518
519 template <typename BasicJsonType, typename CompatibleArrayType>
520 struct is_compatible_array_type
521 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
522
523 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
524 typename = void>
525 struct is_compatible_integer_type_impl : std::false_type {};
526
527 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
528 struct is_compatible_integer_type_impl <
529 RealIntegerType, CompatibleNumberIntegerType,
530 enable_if_t<std::is_integral<RealIntegerType>::value and
531 std::is_integral<CompatibleNumberIntegerType>::value and
532 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
533 {
534 // is there an assert somewhere on overflows?
535 using RealLimits = std::numeric_limits<RealIntegerType>;
536 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
537
538 static constexpr auto value =
539 std::is_constructible<RealIntegerType,
540 CompatibleNumberIntegerType>::value and
541 CompatibleLimits::is_integer and
542 RealLimits::is_signed == CompatibleLimits::is_signed;
543 };
544
545 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
546 struct is_compatible_integer_type
547 : is_compatible_integer_type_impl<RealIntegerType,
548 CompatibleNumberIntegerType> {};
549
550 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
551 template <typename BasicJsonType, typename T, typename = void>
552 struct has_from_json : std::false_type {};
553
554 template <typename BasicJsonType, typename T>
555 struct has_from_json<BasicJsonType, T,
556 enable_if_t<not is_basic_json<T>::value>>
557 {
558 using serializer = typename BasicJsonType::template json_serializer<T, void>;
559
560 static constexpr bool value =
561 is_detected_exact<void, from_json_function, serializer,
562 const BasicJsonType&, T&>::value;
563 };
564
565 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
566 // this overload is used for non-default-constructible user-defined-types
567 template <typename BasicJsonType, typename T, typename = void>
568 struct has_non_default_from_json : std::false_type {};
569
570 template<typename BasicJsonType, typename T>
571 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
572 {
573 using serializer = typename BasicJsonType::template json_serializer<T, void>;
574
575 static constexpr bool value =
576 is_detected_exact<T, from_json_function, serializer,
577 const BasicJsonType&>::value;
578 };
579
580 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
581 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
582 template <typename BasicJsonType, typename T, typename = void>
583 struct has_to_json : std::false_type {};
584
585 template <typename BasicJsonType, typename T>
586 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
587 {
588 using serializer = typename BasicJsonType::template json_serializer<T, void>;
589
590 static constexpr bool value =
591 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
592 T>::value;
593 };
594
595 template <typename BasicJsonType, typename CompatibleType, typename = void>
596 struct is_compatible_type_impl: std::false_type {};
597
598 template <typename BasicJsonType, typename CompatibleType>
599 struct is_compatible_type_impl <
600 BasicJsonType, CompatibleType,
601 enable_if_t<is_complete_type<CompatibleType>::value >>
602 {
603 static constexpr bool value =
604 has_to_json<BasicJsonType, CompatibleType>::value;
605 };
606
607 template <typename BasicJsonType, typename CompatibleType>
608 struct is_compatible_type
609 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
610 }
611 }
612
613 // #include <nlohmann/detail/exceptions.hpp>
614
615
616 #include <exception> // exception
617 #include <stdexcept> // runtime_error
618 #include <string> // to_string
619
620 namespace nlohmann
621 {
622 namespace detail
623 {
624 ////////////////
625 // exceptions //
626 ////////////////
627
628 /*!
629 @brief general exception of the @ref basic_json class
630
631 This class is an extension of `std::exception` objects with a member @a id for
632 exception ids. It is used as the base class for all exceptions thrown by the
633 @ref basic_json class. This class can hence be used as "wildcard" to catch
634 exceptions.
635
636 Subclasses:
637 - @ref parse_error for exceptions indicating a parse error
638 - @ref invalid_iterator for exceptions indicating errors with iterators
639 - @ref type_error for exceptions indicating executing a member function with
640 a wrong type
641 - @ref out_of_range for exceptions indicating access out of the defined range
642 - @ref other_error for exceptions indicating other library errors
643
644 @internal
645 @note To have nothrow-copy-constructible exceptions, we internally use
646 `std::runtime_error` which can cope with arbitrary-length error messages.
647 Intermediate strings are built with static functions and then passed to
648 the actual constructor.
649 @endinternal
650
651 @liveexample{The following code shows how arbitrary library exceptions can be
652 caught.,exception}
653
654 @since version 3.0.0
655 */
656 class exception : public std::exception
657 {
658 public:
659 /// returns the explanatory string
what() const660 const char* what() const noexcept override
661 {
662 return m.what();
663 }
664
665 /// the id of the exception
666 const int id;
667
668 protected:
exception(int id_,const char * what_arg)669 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
670
name(const std::string & ename,int id_)671 static std::string name(const std::string& ename, int id_)
672 {
673 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
674 }
675
676 private:
677 /// an exception object as storage for error messages
678 std::runtime_error m;
679 };
680
681 /*!
682 @brief exception indicating a parse error
683
684 This exception is thrown by the library when a parse error occurs. Parse errors
685 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
686 as when using JSON Patch.
687
688 Member @a byte holds the byte index of the last read character in the input
689 file.
690
691 Exceptions have ids 1xx.
692
693 name / id | example message | description
694 ------------------------------ | --------------- | -------------------------
695 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.
696 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.
697 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.
698 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.
699 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.
700 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`.
701 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.
702 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.
703 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
704 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.
705 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.
706 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.
707
708 @note For an input with n bytes, 1 is the index of the first character and n+1
709 is the index of the terminating null byte or the end of file. This also
710 holds true when reading a byte vector (CBOR or MessagePack).
711
712 @liveexample{The following code shows how a `parse_error` exception can be
713 caught.,parse_error}
714
715 @sa @ref exception for the base class of the library exceptions
716 @sa @ref invalid_iterator for exceptions indicating errors with iterators
717 @sa @ref type_error for exceptions indicating executing a member function with
718 a wrong type
719 @sa @ref out_of_range for exceptions indicating access out of the defined range
720 @sa @ref other_error for exceptions indicating other library errors
721
722 @since version 3.0.0
723 */
724 class parse_error : public exception
725 {
726 public:
727 /*!
728 @brief create a parse error exception
729 @param[in] id_ the id of the exception
730 @param[in] byte_ the byte index where the error occurred (or 0 if the
731 position cannot be determined)
732 @param[in] what_arg the explanatory string
733 @return parse_error object
734 */
create(int id_,std::size_t byte_,const std::string & what_arg)735 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
736 {
737 std::string w = exception::name("parse_error", id_) + "parse error" +
738 (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
739 ": " + what_arg;
740 return parse_error(id_, byte_, w.c_str());
741 }
742
743 /*!
744 @brief byte index of the parse error
745
746 The byte index of the last read character in the input file.
747
748 @note For an input with n bytes, 1 is the index of the first character and
749 n+1 is the index of the terminating null byte or the end of file.
750 This also holds true when reading a byte vector (CBOR or MessagePack).
751 */
752 const std::size_t byte;
753
754 private:
parse_error(int id_,std::size_t byte_,const char * what_arg)755 parse_error(int id_, std::size_t byte_, const char* what_arg)
756 : exception(id_, what_arg), byte(byte_) {}
757 };
758
759 /*!
760 @brief exception indicating errors with iterators
761
762 This exception is thrown if iterators passed to a library function do not match
763 the expected semantics.
764
765 Exceptions have ids 2xx.
766
767 name / id | example message | description
768 ----------------------------------- | --------------- | -------------------------
769 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.
770 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.
771 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.
772 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.
773 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.
774 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.
775 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.
776 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.
777 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.
778 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.
779 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.
780 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
781 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
782 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().
783
784 @liveexample{The following code shows how an `invalid_iterator` exception can be
785 caught.,invalid_iterator}
786
787 @sa @ref exception for the base class of the library exceptions
788 @sa @ref parse_error for exceptions indicating a parse error
789 @sa @ref type_error for exceptions indicating executing a member function with
790 a wrong type
791 @sa @ref out_of_range for exceptions indicating access out of the defined range
792 @sa @ref other_error for exceptions indicating other library errors
793
794 @since version 3.0.0
795 */
796 class invalid_iterator : public exception
797 {
798 public:
create(int id_,const std::string & what_arg)799 static invalid_iterator create(int id_, const std::string& what_arg)
800 {
801 std::string w = exception::name("invalid_iterator", id_) + what_arg;
802 return invalid_iterator(id_, w.c_str());
803 }
804
805 private:
invalid_iterator(int id_,const char * what_arg)806 invalid_iterator(int id_, const char* what_arg)
807 : exception(id_, what_arg) {}
808 };
809
810 /*!
811 @brief exception indicating executing a member function with a wrong type
812
813 This exception is thrown in case of a type error; that is, a library function is
814 executed on a JSON value whose type does not match the expected semantics.
815
816 Exceptions have ids 3xx.
817
818 name / id | example message | description
819 ----------------------------- | --------------- | -------------------------
820 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.
821 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.
822 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&.
823 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
824 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
825 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
826 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
827 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.
828 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
829 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
830 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.
831 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
832 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.
833 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
834 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.
835 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. |
836
837 @liveexample{The following code shows how a `type_error` exception can be
838 caught.,type_error}
839
840 @sa @ref exception for the base class of the library exceptions
841 @sa @ref parse_error for exceptions indicating a parse error
842 @sa @ref invalid_iterator for exceptions indicating errors with iterators
843 @sa @ref out_of_range for exceptions indicating access out of the defined range
844 @sa @ref other_error for exceptions indicating other library errors
845
846 @since version 3.0.0
847 */
848 class type_error : public exception
849 {
850 public:
create(int id_,const std::string & what_arg)851 static type_error create(int id_, const std::string& what_arg)
852 {
853 std::string w = exception::name("type_error", id_) + what_arg;
854 return type_error(id_, w.c_str());
855 }
856
857 private:
type_error(int id_,const char * what_arg)858 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
859 };
860
861 /*!
862 @brief exception indicating access out of the defined range
863
864 This exception is thrown in case a library function is called on an input
865 parameter that exceeds the expected range, for instance in case of array
866 indices or nonexisting object keys.
867
868 Exceptions have ids 4xx.
869
870 name / id | example message | description
871 ------------------------------- | --------------- | -------------------------
872 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.
873 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.
874 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
875 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
876 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.
877 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.
878 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON only supports integers numbers up to 9223372036854775807. |
879 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
880
881 @liveexample{The following code shows how an `out_of_range` exception can be
882 caught.,out_of_range}
883
884 @sa @ref exception for the base class of the library exceptions
885 @sa @ref parse_error for exceptions indicating a parse error
886 @sa @ref invalid_iterator for exceptions indicating errors with iterators
887 @sa @ref type_error for exceptions indicating executing a member function with
888 a wrong type
889 @sa @ref other_error for exceptions indicating other library errors
890
891 @since version 3.0.0
892 */
893 class out_of_range : public exception
894 {
895 public:
create(int id_,const std::string & what_arg)896 static out_of_range create(int id_, const std::string& what_arg)
897 {
898 std::string w = exception::name("out_of_range", id_) + what_arg;
899 return out_of_range(id_, w.c_str());
900 }
901
902 private:
out_of_range(int id_,const char * what_arg)903 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
904 };
905
906 /*!
907 @brief exception indicating other library errors
908
909 This exception is thrown in case of errors that cannot be classified with the
910 other exception types.
911
912 Exceptions have ids 5xx.
913
914 name / id | example message | description
915 ------------------------------ | --------------- | -------------------------
916 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
917
918 @sa @ref exception for the base class of the library exceptions
919 @sa @ref parse_error for exceptions indicating a parse error
920 @sa @ref invalid_iterator for exceptions indicating errors with iterators
921 @sa @ref type_error for exceptions indicating executing a member function with
922 a wrong type
923 @sa @ref out_of_range for exceptions indicating access out of the defined range
924
925 @liveexample{The following code shows how an `other_error` exception can be
926 caught.,other_error}
927
928 @since version 3.0.0
929 */
930 class other_error : public exception
931 {
932 public:
create(int id_,const std::string & what_arg)933 static other_error create(int id_, const std::string& what_arg)
934 {
935 std::string w = exception::name("other_error", id_) + what_arg;
936 return other_error(id_, w.c_str());
937 }
938
939 private:
other_error(int id_,const char * what_arg)940 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
941 };
942 }
943 }
944
945 // #include <nlohmann/detail/value_t.hpp>
946
947
948 #include <array> // array
949 #include <ciso646> // and
950 #include <cstddef> // size_t
951 #include <cstdint> // uint8_t
952
953 namespace nlohmann
954 {
955 namespace detail
956 {
957 ///////////////////////////
958 // JSON type enumeration //
959 ///////////////////////////
960
961 /*!
962 @brief the JSON type enumeration
963
964 This enumeration collects the different JSON types. It is internally used to
965 distinguish the stored values, and the functions @ref basic_json::is_null(),
966 @ref basic_json::is_object(), @ref basic_json::is_array(),
967 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
968 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
969 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
970 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
971 @ref basic_json::is_structured() rely on it.
972
973 @note There are three enumeration entries (number_integer, number_unsigned, and
974 number_float), because the library distinguishes these three types for numbers:
975 @ref basic_json::number_unsigned_t is used for unsigned integers,
976 @ref basic_json::number_integer_t is used for signed integers, and
977 @ref basic_json::number_float_t is used for floating-point numbers or to
978 approximate integers which do not fit in the limits of their respective type.
979
980 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
981 value with the default value for a given type
982
983 @since version 1.0.0
984 */
985 enum class value_t : std::uint8_t
986 {
987 null, ///< null value
988 object, ///< object (unordered set of name/value pairs)
989 array, ///< array (ordered collection of values)
990 string, ///< string value
991 boolean, ///< boolean value
992 number_integer, ///< number value (signed integer)
993 number_unsigned, ///< number value (unsigned integer)
994 number_float, ///< number value (floating-point)
995 discarded ///< discarded by the the parser callback function
996 };
997
998 /*!
999 @brief comparison operator for JSON types
1000
1001 Returns an ordering that is similar to Python:
1002 - order: null < boolean < number < object < array < string
1003 - furthermore, each type is not smaller than itself
1004 - discarded values are not comparable
1005
1006 @since version 1.0.0
1007 */
operator <(const value_t lhs,const value_t rhs)1008 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1009 {
1010 static constexpr std::array<std::uint8_t, 8> order = {{
1011 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1012 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1013 }
1014 };
1015
1016 const auto l_index = static_cast<std::size_t>(lhs);
1017 const auto r_index = static_cast<std::size_t>(rhs);
1018 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1019 }
1020 }
1021 }
1022
1023 // #include <nlohmann/detail/conversions/from_json.hpp>
1024
1025
1026 #include <algorithm> // transform
1027 #include <array> // array
1028 #include <ciso646> // and, not
1029 #include <forward_list> // forward_list
1030 #include <iterator> // inserter, front_inserter, end
1031 #include <map> // map
1032 #include <string> // string
1033 #include <tuple> // tuple, make_tuple
1034 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
1035 #include <unordered_map> // unordered_map
1036 #include <utility> // pair, declval
1037 #include <valarray> // valarray
1038
1039 // #include <nlohmann/detail/exceptions.hpp>
1040
1041 // #include <nlohmann/detail/macro_scope.hpp>
1042
1043 // #include <nlohmann/detail/meta/cpp_future.hpp>
1044
1045 // #include <nlohmann/detail/meta/type_traits.hpp>
1046
1047 // #include <nlohmann/detail/value_t.hpp>
1048
1049
1050 namespace nlohmann
1051 {
1052 namespace detail
1053 {
1054 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)1055 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1056 {
1057 if (JSON_UNLIKELY(not j.is_null()))
1058 {
1059 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1060 }
1061 n = nullptr;
1062 }
1063
1064 // overloads for basic_json template parameters
1065 template<typename BasicJsonType, typename ArithmeticType,
1066 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1067 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1068 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1069 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1070 {
1071 switch (static_cast<value_t>(j))
1072 {
1073 case value_t::number_unsigned:
1074 {
1075 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1076 break;
1077 }
1078 case value_t::number_integer:
1079 {
1080 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1081 break;
1082 }
1083 case value_t::number_float:
1084 {
1085 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1086 break;
1087 }
1088
1089 default:
1090 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1091 }
1092 }
1093
1094 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1095 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1096 {
1097 if (JSON_UNLIKELY(not j.is_boolean()))
1098 {
1099 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1100 }
1101 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1102 }
1103
1104 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1105 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1106 {
1107 if (JSON_UNLIKELY(not j.is_string()))
1108 {
1109 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1110 }
1111 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1112 }
1113
1114 template <
1115 typename BasicJsonType, typename CompatibleStringType,
1116 enable_if_t <
1117 is_compatible_string_type<BasicJsonType, CompatibleStringType>::value and
1118 not std::is_same<typename BasicJsonType::string_t,
1119 CompatibleStringType>::value,
1120 int > = 0 >
from_json(const BasicJsonType & j,CompatibleStringType & s)1121 void from_json(const BasicJsonType& j, CompatibleStringType& s)
1122 {
1123 if (JSON_UNLIKELY(not j.is_string()))
1124 {
1125 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1126 }
1127
1128 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1129 }
1130
1131 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1132 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1133 {
1134 get_arithmetic_value(j, val);
1135 }
1136
1137 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1138 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1139 {
1140 get_arithmetic_value(j, val);
1141 }
1142
1143 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1144 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1145 {
1146 get_arithmetic_value(j, val);
1147 }
1148
1149 template<typename BasicJsonType, typename EnumType,
1150 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1151 void from_json(const BasicJsonType& j, EnumType& e)
1152 {
1153 typename std::underlying_type<EnumType>::type val;
1154 get_arithmetic_value(j, val);
1155 e = static_cast<EnumType>(val);
1156 }
1157
1158 // forward_list doesn't have an insert method
1159 template<typename BasicJsonType, typename T, typename Allocator,
1160 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1161 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1162 {
1163 if (JSON_UNLIKELY(not j.is_array()))
1164 {
1165 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1166 }
1167 std::transform(j.rbegin(), j.rend(),
1168 std::front_inserter(l), [](const BasicJsonType & i)
1169 {
1170 return i.template get<T>();
1171 });
1172 }
1173
1174 // valarray doesn't have an insert method
1175 template<typename BasicJsonType, typename T,
1176 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1177 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1178 {
1179 if (JSON_UNLIKELY(not j.is_array()))
1180 {
1181 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1182 }
1183 l.resize(j.size());
1184 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1185 }
1186
1187 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)1188 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1189 {
1190 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1191 }
1192
1193 template <typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1194 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1195 priority_tag<2> /*unused*/)
1196 -> decltype(j.template get<T>(), void())
1197 {
1198 for (std::size_t i = 0; i < N; ++i)
1199 {
1200 arr[i] = j.at(i).template get<T>();
1201 }
1202 }
1203
1204 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<1>)1205 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1206 -> decltype(
1207 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1208 j.template get<typename CompatibleArrayType::value_type>(),
1209 void())
1210 {
1211 using std::end;
1212
1213 arr.reserve(j.size());
1214 std::transform(j.begin(), j.end(),
1215 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1216 {
1217 // get<BasicJsonType>() returns *this, this won't call a from_json
1218 // method when value_type is BasicJsonType
1219 return i.template get<typename CompatibleArrayType::value_type>();
1220 });
1221 }
1222
1223 template <typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<0>)1224 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr,
1225 priority_tag<0> /*unused*/)
1226 {
1227 using std::end;
1228
1229 std::transform(
1230 j.begin(), j.end(), std::inserter(arr, end(arr)),
1231 [](const BasicJsonType & i)
1232 {
1233 // get<BasicJsonType>() returns *this, this won't call a from_json
1234 // method when value_type is BasicJsonType
1235 return i.template get<typename CompatibleArrayType::value_type>();
1236 });
1237 }
1238
1239 template <typename BasicJsonType, typename CompatibleArrayType,
1240 enable_if_t <
1241 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1242 not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
1243 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
1244 not is_basic_json<CompatibleArrayType>::value,
1245 int > = 0 >
1246
from_json(const BasicJsonType & j,CompatibleArrayType & arr)1247 auto from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1248 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1249 j.template get<typename CompatibleArrayType::value_type>(),
1250 void())
1251 {
1252 if (JSON_UNLIKELY(not j.is_array()))
1253 {
1254 JSON_THROW(type_error::create(302, "type must be array, but is " +
1255 std::string(j.type_name())));
1256 }
1257
1258 from_json_array_impl(j, arr, priority_tag<3> {});
1259 }
1260
1261 template<typename BasicJsonType, typename CompatibleObjectType,
1262 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleObjectType & obj)1263 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1264 {
1265 if (JSON_UNLIKELY(not j.is_object()))
1266 {
1267 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1268 }
1269
1270 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1271 using value_type = typename CompatibleObjectType::value_type;
1272 std::transform(
1273 inner_object->begin(), inner_object->end(),
1274 std::inserter(obj, obj.begin()),
1275 [](typename BasicJsonType::object_t::value_type const & p)
1276 {
1277 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1278 });
1279 }
1280
1281 // overload for arithmetic types, not chosen for basic_json template arguments
1282 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1283 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1284 // an arithmetic type?
1285 template<typename BasicJsonType, typename ArithmeticType,
1286 enable_if_t <
1287 std::is_arithmetic<ArithmeticType>::value and
1288 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1289 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1290 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1291 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1292 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1293 void from_json(const BasicJsonType& j, ArithmeticType& val)
1294 {
1295 switch (static_cast<value_t>(j))
1296 {
1297 case value_t::number_unsigned:
1298 {
1299 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1300 break;
1301 }
1302 case value_t::number_integer:
1303 {
1304 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1305 break;
1306 }
1307 case value_t::number_float:
1308 {
1309 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1310 break;
1311 }
1312 case value_t::boolean:
1313 {
1314 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1315 break;
1316 }
1317
1318 default:
1319 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1320 }
1321 }
1322
1323 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1324 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1325 {
1326 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1327 }
1328
1329 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1330 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1331 {
1332 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1333 }
1334
1335 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1336 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1337 {
1338 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1339 }
1340
1341 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1342 typename = enable_if_t<not std::is_constructible<
1343 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)1344 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1345 {
1346 if (JSON_UNLIKELY(not j.is_array()))
1347 {
1348 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1349 }
1350 for (const auto& p : j)
1351 {
1352 if (JSON_UNLIKELY(not p.is_array()))
1353 {
1354 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1355 }
1356 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1357 }
1358 }
1359
1360 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1361 typename = enable_if_t<not std::is_constructible<
1362 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)1363 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1364 {
1365 if (JSON_UNLIKELY(not j.is_array()))
1366 {
1367 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1368 }
1369 for (const auto& p : j)
1370 {
1371 if (JSON_UNLIKELY(not p.is_array()))
1372 {
1373 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1374 }
1375 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1376 }
1377 }
1378
1379 struct from_json_fn
1380 {
1381 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1382 auto operator()(const BasicJsonType& j, T& val) const
1383 noexcept(noexcept(from_json(j, val)))
1384 -> decltype(from_json(j, val), void())
1385 {
1386 return from_json(j, val);
1387 }
1388 };
1389 }
1390
1391 /// namespace to hold default `from_json` function
1392 /// to see why this is required:
1393 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1394 namespace
1395 {
1396 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1397 }
1398 }
1399
1400 // #include <nlohmann/detail/conversions/to_json.hpp>
1401
1402
1403 #include <ciso646> // or, and, not
1404 #include <iterator> // begin, end
1405 #include <tuple> // tuple, get
1406 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1407 #include <utility> // move, forward, declval, pair
1408 #include <valarray> // valarray
1409 #include <vector> // vector
1410
1411 // #include <nlohmann/detail/meta/cpp_future.hpp>
1412
1413 // #include <nlohmann/detail/meta/type_traits.hpp>
1414
1415 // #include <nlohmann/detail/value_t.hpp>
1416
1417 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1418
1419
1420 #include <cstddef> // size_t
1421 #include <string> // string, to_string
1422 #include <iterator> // input_iterator_tag
1423
1424 // #include <nlohmann/detail/value_t.hpp>
1425
1426
1427 namespace nlohmann
1428 {
1429 namespace detail
1430 {
1431 /// proxy class for the items() function
1432 template<typename IteratorType> class iteration_proxy
1433 {
1434 private:
1435 /// helper class for iteration
1436 class iteration_proxy_internal
1437 {
1438 public:
1439 using difference_type = std::ptrdiff_t;
1440 using value_type = iteration_proxy_internal;
1441 using pointer = iteration_proxy_internal*;
1442 using reference = iteration_proxy_internal&;
1443 using iterator_category = std::input_iterator_tag;
1444
1445 private:
1446 /// the iterator
1447 IteratorType anchor;
1448 /// an index for arrays (used to create key names)
1449 std::size_t array_index = 0;
1450 /// last stringified array index
1451 mutable std::size_t array_index_last = 0;
1452 /// a string representation of the array index
1453 mutable std::string array_index_str = "0";
1454 /// an empty string (to return a reference for primitive values)
1455 const std::string empty_str = "";
1456
1457 public:
iteration_proxy_internal(IteratorType it)1458 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
1459
1460 iteration_proxy_internal(const iteration_proxy_internal&) = default;
1461 iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default;
1462
1463 /// dereference operator (needed for range-based for)
operator *()1464 iteration_proxy_internal& operator*()
1465 {
1466 return *this;
1467 }
1468
1469 /// increment operator (needed for range-based for)
operator ++()1470 iteration_proxy_internal& operator++()
1471 {
1472 ++anchor;
1473 ++array_index;
1474
1475 return *this;
1476 }
1477
1478 /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_internal & o) const1479 bool operator==(const iteration_proxy_internal& o) const noexcept
1480 {
1481 return anchor == o.anchor;
1482 }
1483
1484 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const1485 bool operator!=(const iteration_proxy_internal& o) const noexcept
1486 {
1487 return anchor != o.anchor;
1488 }
1489
1490 /// return key of the iterator
key() const1491 const std::string& key() const
1492 {
1493 assert(anchor.m_object != nullptr);
1494
1495 switch (anchor.m_object->type())
1496 {
1497 // use integer array index as key
1498 case value_t::array:
1499 {
1500 if (array_index != array_index_last)
1501 {
1502 array_index_str = std::to_string(array_index);
1503 array_index_last = array_index;
1504 }
1505 return array_index_str;
1506 }
1507
1508 // use key from the object
1509 case value_t::object:
1510 return anchor.key();
1511
1512 // use an empty key for all primitive types
1513 default:
1514 return empty_str;
1515 }
1516 }
1517
1518 /// return value of the iterator
value() const1519 typename IteratorType::reference value() const
1520 {
1521 return anchor.value();
1522 }
1523 };
1524
1525 /// the container to iterate
1526 typename IteratorType::reference container;
1527
1528 public:
1529 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)1530 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1531 : container(cont) {}
1532
1533 /// return iterator begin (needed for range-based for)
begin()1534 iteration_proxy_internal begin() noexcept
1535 {
1536 return iteration_proxy_internal(container.begin());
1537 }
1538
1539 /// return iterator end (needed for range-based for)
end()1540 iteration_proxy_internal end() noexcept
1541 {
1542 return iteration_proxy_internal(container.end());
1543 }
1544 };
1545 }
1546 }
1547
1548
1549 namespace nlohmann
1550 {
1551 namespace detail
1552 {
1553 //////////////////
1554 // constructors //
1555 //////////////////
1556
1557 template<value_t> struct external_constructor;
1558
1559 template<>
1560 struct external_constructor<value_t::boolean>
1561 {
1562 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1563 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1564 {
1565 j.m_type = value_t::boolean;
1566 j.m_value = b;
1567 j.assert_invariant();
1568 }
1569 };
1570
1571 template<>
1572 struct external_constructor<value_t::string>
1573 {
1574 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1575 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1576 {
1577 j.m_type = value_t::string;
1578 j.m_value = s;
1579 j.assert_invariant();
1580 }
1581
1582 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1583 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1584 {
1585 j.m_type = value_t::string;
1586 j.m_value = std::move(s);
1587 j.assert_invariant();
1588 }
1589
1590 template<typename BasicJsonType, typename CompatibleStringType,
1591 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1592 int> = 0>
constructnlohmann::detail::external_constructor1593 static void construct(BasicJsonType& j, const CompatibleStringType& str)
1594 {
1595 j.m_type = value_t::string;
1596 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1597 j.assert_invariant();
1598 }
1599 };
1600
1601 template<>
1602 struct external_constructor<value_t::number_float>
1603 {
1604 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1605 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1606 {
1607 j.m_type = value_t::number_float;
1608 j.m_value = val;
1609 j.assert_invariant();
1610 }
1611 };
1612
1613 template<>
1614 struct external_constructor<value_t::number_unsigned>
1615 {
1616 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1617 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1618 {
1619 j.m_type = value_t::number_unsigned;
1620 j.m_value = val;
1621 j.assert_invariant();
1622 }
1623 };
1624
1625 template<>
1626 struct external_constructor<value_t::number_integer>
1627 {
1628 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1629 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1630 {
1631 j.m_type = value_t::number_integer;
1632 j.m_value = val;
1633 j.assert_invariant();
1634 }
1635 };
1636
1637 template<>
1638 struct external_constructor<value_t::array>
1639 {
1640 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1641 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1642 {
1643 j.m_type = value_t::array;
1644 j.m_value = arr;
1645 j.assert_invariant();
1646 }
1647
1648 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1649 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1650 {
1651 j.m_type = value_t::array;
1652 j.m_value = std::move(arr);
1653 j.assert_invariant();
1654 }
1655
1656 template<typename BasicJsonType, typename CompatibleArrayType,
1657 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1658 int> = 0>
constructnlohmann::detail::external_constructor1659 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1660 {
1661 using std::begin;
1662 using std::end;
1663 j.m_type = value_t::array;
1664 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1665 j.assert_invariant();
1666 }
1667
1668 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1669 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1670 {
1671 j.m_type = value_t::array;
1672 j.m_value = value_t::array;
1673 j.m_value.array->reserve(arr.size());
1674 for (const bool x : arr)
1675 {
1676 j.m_value.array->push_back(x);
1677 }
1678 j.assert_invariant();
1679 }
1680
1681 template<typename BasicJsonType, typename T,
1682 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor1683 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1684 {
1685 j.m_type = value_t::array;
1686 j.m_value = value_t::array;
1687 j.m_value.array->resize(arr.size());
1688 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1689 j.assert_invariant();
1690 }
1691 };
1692
1693 template<>
1694 struct external_constructor<value_t::object>
1695 {
1696 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1697 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1698 {
1699 j.m_type = value_t::object;
1700 j.m_value = obj;
1701 j.assert_invariant();
1702 }
1703
1704 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1705 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1706 {
1707 j.m_type = value_t::object;
1708 j.m_value = std::move(obj);
1709 j.assert_invariant();
1710 }
1711
1712 template<typename BasicJsonType, typename CompatibleObjectType,
1713 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor1714 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1715 {
1716 using std::begin;
1717 using std::end;
1718
1719 j.m_type = value_t::object;
1720 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1721 j.assert_invariant();
1722 }
1723 };
1724
1725 /////////////
1726 // to_json //
1727 /////////////
1728
1729 template<typename BasicJsonType, typename T,
1730 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)1731 void to_json(BasicJsonType& j, T b) noexcept
1732 {
1733 external_constructor<value_t::boolean>::construct(j, b);
1734 }
1735
1736 template<typename BasicJsonType, typename CompatibleString,
1737 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)1738 void to_json(BasicJsonType& j, const CompatibleString& s)
1739 {
1740 external_constructor<value_t::string>::construct(j, s);
1741 }
1742
1743 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)1744 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1745 {
1746 external_constructor<value_t::string>::construct(j, std::move(s));
1747 }
1748
1749 template<typename BasicJsonType, typename FloatType,
1750 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)1751 void to_json(BasicJsonType& j, FloatType val) noexcept
1752 {
1753 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1754 }
1755
1756 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1757 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)1758 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1759 {
1760 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1761 }
1762
1763 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1764 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)1765 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1766 {
1767 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1768 }
1769
1770 template<typename BasicJsonType, typename EnumType,
1771 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)1772 void to_json(BasicJsonType& j, EnumType e) noexcept
1773 {
1774 using underlying_type = typename std::underlying_type<EnumType>::type;
1775 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1776 }
1777
1778 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)1779 void to_json(BasicJsonType& j, const std::vector<bool>& e)
1780 {
1781 external_constructor<value_t::array>::construct(j, e);
1782 }
1783
1784 template <typename BasicJsonType, typename CompatibleArrayType,
1785 enable_if_t<is_compatible_array_type<BasicJsonType,
1786 CompatibleArrayType>::value and
1787 not is_compatible_object_type<
1788 BasicJsonType, CompatibleArrayType>::value and
1789 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
1790 not is_basic_json<CompatibleArrayType>::value,
1791 int> = 0>
to_json(BasicJsonType & j,const CompatibleArrayType & arr)1792 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1793 {
1794 external_constructor<value_t::array>::construct(j, arr);
1795 }
1796
1797 template<typename BasicJsonType, typename T,
1798 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)1799 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
1800 {
1801 external_constructor<value_t::array>::construct(j, std::move(arr));
1802 }
1803
1804 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)1805 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1806 {
1807 external_constructor<value_t::array>::construct(j, std::move(arr));
1808 }
1809
1810 template<typename BasicJsonType, typename CompatibleObjectType,
1811 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleObjectType & obj)1812 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1813 {
1814 external_constructor<value_t::object>::construct(j, obj);
1815 }
1816
1817 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)1818 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1819 {
1820 external_constructor<value_t::object>::construct(j, std::move(obj));
1821 }
1822
1823 template <
1824 typename BasicJsonType, typename T, std::size_t N,
1825 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
1826 const T (&)[N]>::value,
1827 int> = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])1828 void to_json(BasicJsonType& j, const T (&arr)[N])
1829 {
1830 external_constructor<value_t::array>::construct(j, arr);
1831 }
1832
1833 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)1834 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1835 {
1836 j = {p.first, p.second};
1837 }
1838
1839 // for https://github.com/nlohmann/json/pull/1134
1840 template<typename BasicJsonType, typename T,
1841 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)1842 void to_json(BasicJsonType& j, T b) noexcept
1843 {
1844 j = {{b.key(), b.value()}};
1845 }
1846
1847 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)1848 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1849 {
1850 j = {std::get<Idx>(t)...};
1851 }
1852
1853 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)1854 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1855 {
1856 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1857 }
1858
1859 struct to_json_fn
1860 {
1861 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn1862 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1863 -> decltype(to_json(j, std::forward<T>(val)), void())
1864 {
1865 return to_json(j, std::forward<T>(val));
1866 }
1867 };
1868 }
1869
1870 /// namespace to hold default `to_json` function
1871 namespace
1872 {
1873 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1874 }
1875 }
1876
1877 // #include <nlohmann/detail/input/input_adapters.hpp>
1878
1879
1880 #include <cassert> // assert
1881 #include <cstddef> // size_t
1882 #include <cstring> // strlen
1883 #include <istream> // istream
1884 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1885 #include <memory> // shared_ptr, make_shared, addressof
1886 #include <numeric> // accumulate
1887 #include <string> // string, char_traits
1888 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1889 #include <utility> // pair, declval
1890
1891 // #include <nlohmann/detail/macro_scope.hpp>
1892
1893
1894 namespace nlohmann
1895 {
1896 namespace detail
1897 {
1898 /// the supported input formats
1899 enum class input_format_t { json, cbor, msgpack, ubjson };
1900
1901 ////////////////////
1902 // input adapters //
1903 ////////////////////
1904
1905 /*!
1906 @brief abstract input adapter interface
1907
1908 Produces a stream of std::char_traits<char>::int_type characters from a
1909 std::istream, a buffer, or some other input type. Accepts the return of
1910 exactly one non-EOF character for future input. The int_type characters
1911 returned consist of all valid char values as positive values (typically
1912 unsigned char), plus an EOF value outside that range, specified by the value
1913 of the function std::char_traits<char>::eof(). This value is typically -1, but
1914 could be any arbitrary value which is not a valid char value.
1915 */
1916 struct input_adapter_protocol
1917 {
1918 /// get a character [0,255] or std::char_traits<char>::eof().
1919 virtual std::char_traits<char>::int_type get_character() = 0;
1920 virtual ~input_adapter_protocol() = default;
1921 };
1922
1923 /// a type to simplify interfaces
1924 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1925
1926 /*!
1927 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1928 beginning of input. Does not support changing the underlying std::streambuf
1929 in mid-input. Maintains underlying std::istream and std::streambuf to support
1930 subsequent use of standard std::istream operations to process any input
1931 characters following those used in parsing the JSON input. Clears the
1932 std::istream flags; any input errors (e.g., EOF) will be detected by the first
1933 subsequent call for input from the std::istream.
1934 */
1935 class input_stream_adapter : public input_adapter_protocol
1936 {
1937 public:
~input_stream_adapter()1938 ~input_stream_adapter() override
1939 {
1940 // clear stream flags; we use underlying streambuf I/O, do not
1941 // maintain ifstream flags
1942 is.clear();
1943 }
1944
input_stream_adapter(std::istream & i)1945 explicit input_stream_adapter(std::istream& i)
1946 : is(i), sb(*i.rdbuf())
1947 {}
1948
1949 // delete because of pointer members
1950 input_stream_adapter(const input_stream_adapter&) = delete;
1951 input_stream_adapter& operator=(input_stream_adapter&) = delete;
1952
1953 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1954 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
1955 // end up as the same value, eg. 0xFFFFFFFF.
get_character()1956 std::char_traits<char>::int_type get_character() override
1957 {
1958 return sb.sbumpc();
1959 }
1960
1961 private:
1962 /// the associated input stream
1963 std::istream& is;
1964 std::streambuf& sb;
1965 };
1966
1967 /// input adapter for buffer input
1968 class input_buffer_adapter : public input_adapter_protocol
1969 {
1970 public:
input_buffer_adapter(const char * b,const std::size_t l)1971 input_buffer_adapter(const char* b, const std::size_t l)
1972 : cursor(b), limit(b + l)
1973 {}
1974
1975 // delete because of pointer members
1976 input_buffer_adapter(const input_buffer_adapter&) = delete;
1977 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1978
get_character()1979 std::char_traits<char>::int_type get_character() noexcept override
1980 {
1981 if (JSON_LIKELY(cursor < limit))
1982 {
1983 return std::char_traits<char>::to_int_type(*(cursor++));
1984 }
1985
1986 return std::char_traits<char>::eof();
1987 }
1988
1989 private:
1990 /// pointer to the current character
1991 const char* cursor;
1992 /// pointer past the last character
1993 const char* const limit;
1994 };
1995
1996 template<typename WideStringType, size_t T>
1997 struct wide_string_input_helper
1998 {
1999 // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper2000 static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
2001 {
2002 utf8_bytes_index = 0;
2003
2004 if (current_wchar == str.size())
2005 {
2006 utf8_bytes[0] = std::char_traits<char>::eof();
2007 utf8_bytes_filled = 1;
2008 }
2009 else
2010 {
2011 // get the current character
2012 const int wc = static_cast<int>(str[current_wchar++]);
2013
2014 // UTF-32 to UTF-8 encoding
2015 if (wc < 0x80)
2016 {
2017 utf8_bytes[0] = wc;
2018 utf8_bytes_filled = 1;
2019 }
2020 else if (wc <= 0x7FF)
2021 {
2022 utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2023 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2024 utf8_bytes_filled = 2;
2025 }
2026 else if (wc <= 0xFFFF)
2027 {
2028 utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2029 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2030 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2031 utf8_bytes_filled = 3;
2032 }
2033 else if (wc <= 0x10FFFF)
2034 {
2035 utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
2036 utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2037 utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2038 utf8_bytes[3] = 0x80 | (wc & 0x3F);
2039 utf8_bytes_filled = 4;
2040 }
2041 else
2042 {
2043 // unknown character
2044 utf8_bytes[0] = wc;
2045 utf8_bytes_filled = 1;
2046 }
2047 }
2048 }
2049 };
2050
2051 template<typename WideStringType>
2052 struct wide_string_input_helper<WideStringType, 2>
2053 {
2054 // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper2055 static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
2056 {
2057 utf8_bytes_index = 0;
2058
2059 if (current_wchar == str.size())
2060 {
2061 utf8_bytes[0] = std::char_traits<char>::eof();
2062 utf8_bytes_filled = 1;
2063 }
2064 else
2065 {
2066 // get the current character
2067 const int wc = static_cast<int>(str[current_wchar++]);
2068
2069 // UTF-16 to UTF-8 encoding
2070 if (wc < 0x80)
2071 {
2072 utf8_bytes[0] = wc;
2073 utf8_bytes_filled = 1;
2074 }
2075 else if (wc <= 0x7FF)
2076 {
2077 utf8_bytes[0] = 0xC0 | ((wc >> 6));
2078 utf8_bytes[1] = 0x80 | (wc & 0x3F);
2079 utf8_bytes_filled = 2;
2080 }
2081 else if (0xD800 > wc or wc >= 0xE000)
2082 {
2083 utf8_bytes[0] = 0xE0 | ((wc >> 12));
2084 utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2085 utf8_bytes[2] = 0x80 | (wc & 0x3F);
2086 utf8_bytes_filled = 3;
2087 }
2088 else
2089 {
2090 if (current_wchar < str.size())
2091 {
2092 const int wc2 = static_cast<int>(str[current_wchar++]);
2093 const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2094 utf8_bytes[0] = 0xf0 | (charcode >> 18);
2095 utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2096 utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2097 utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2098 utf8_bytes_filled = 4;
2099 }
2100 else
2101 {
2102 // unknown character
2103 ++current_wchar;
2104 utf8_bytes[0] = wc;
2105 utf8_bytes_filled = 1;
2106 }
2107 }
2108 }
2109 }
2110 };
2111
2112 template<typename WideStringType>
2113 class wide_string_input_adapter : public input_adapter_protocol
2114 {
2115 public:
wide_string_input_adapter(const WideStringType & w)2116 explicit wide_string_input_adapter(const WideStringType& w) : str(w) {}
2117
get_character()2118 std::char_traits<char>::int_type get_character() noexcept override
2119 {
2120 // check if buffer needs to be filled
2121 if (utf8_bytes_index == utf8_bytes_filled)
2122 {
2123 fill_buffer<sizeof(typename WideStringType::value_type)>();
2124
2125 assert(utf8_bytes_filled > 0);
2126 assert(utf8_bytes_index == 0);
2127 }
2128
2129 // use buffer
2130 assert(utf8_bytes_filled > 0);
2131 assert(utf8_bytes_index < utf8_bytes_filled);
2132 return utf8_bytes[utf8_bytes_index++];
2133 }
2134
2135 private:
2136 template<size_t T>
fill_buffer()2137 void fill_buffer()
2138 {
2139 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2140 }
2141
2142 /// the wstring to process
2143 const WideStringType& str;
2144
2145 /// index of the current wchar in str
2146 std::size_t current_wchar = 0;
2147
2148 /// a buffer for UTF-8 bytes
2149 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2150
2151 /// index to the utf8_codes array for the next valid byte
2152 std::size_t utf8_bytes_index = 0;
2153 /// number of valid bytes in the utf8_codes array
2154 std::size_t utf8_bytes_filled = 0;
2155 };
2156
2157 class input_adapter
2158 {
2159 public:
2160 // native support
2161
2162 /// input adapter for input stream
input_adapter(std::istream & i)2163 input_adapter(std::istream& i)
2164 : ia(std::make_shared<input_stream_adapter>(i)) {}
2165
2166 /// input adapter for input stream
input_adapter(std::istream && i)2167 input_adapter(std::istream&& i)
2168 : ia(std::make_shared<input_stream_adapter>(i)) {}
2169
input_adapter(const std::wstring & ws)2170 input_adapter(const std::wstring& ws)
2171 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2172
input_adapter(const std::u16string & ws)2173 input_adapter(const std::u16string& ws)
2174 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2175
input_adapter(const std::u32string & ws)2176 input_adapter(const std::u32string& ws)
2177 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2178
2179 /// input adapter for buffer
2180 template<typename CharT,
2181 typename std::enable_if<
2182 std::is_pointer<CharT>::value and
2183 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2184 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2185 int>::type = 0>
input_adapter(CharT b,std::size_t l)2186 input_adapter(CharT b, std::size_t l)
2187 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2188
2189 // derived support
2190
2191 /// input adapter for string literal
2192 template<typename CharT,
2193 typename std::enable_if<
2194 std::is_pointer<CharT>::value and
2195 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2196 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2197 int>::type = 0>
input_adapter(CharT b)2198 input_adapter(CharT b)
2199 : input_adapter(reinterpret_cast<const char*>(b),
2200 std::strlen(reinterpret_cast<const char*>(b))) {}
2201
2202 /// input adapter for iterator range with contiguous storage
2203 template<class IteratorType,
2204 typename std::enable_if<
2205 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2206 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)2207 input_adapter(IteratorType first, IteratorType last)
2208 {
2209 #ifndef NDEBUG
2210 // assertion to check that the iterator range is indeed contiguous,
2211 // see http://stackoverflow.com/a/35008842/266378 for more discussion
2212 const auto is_contiguous = std::accumulate(
2213 first, last, std::pair<bool, int>(true, 0),
2214 [&first](std::pair<bool, int> res, decltype(*first) val)
2215 {
2216 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2217 return res;
2218 }).first;
2219 assert(is_contiguous);
2220 #endif
2221
2222 // assertion to check that each element is 1 byte long
2223 static_assert(
2224 sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
2225 "each element in the iterator range must have the size of 1 byte");
2226
2227 const auto len = static_cast<size_t>(std::distance(first, last));
2228 if (JSON_LIKELY(len > 0))
2229 {
2230 // there is at least one element: use the address of first
2231 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2232 }
2233 else
2234 {
2235 // the address of first cannot be used: use nullptr
2236 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2237 }
2238 }
2239
2240 /// input adapter for array
2241 template<class T, std::size_t N>
input_adapter(T (& array)[N])2242 input_adapter(T (&array)[N])
2243 : input_adapter(std::begin(array), std::end(array)) {}
2244
2245 /// input adapter for contiguous container
2246 template<class ContiguousContainer, typename
2247 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2248 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2249 int>::type = 0>
input_adapter(const ContiguousContainer & c)2250 input_adapter(const ContiguousContainer& c)
2251 : input_adapter(std::begin(c), std::end(c)) {}
2252
operator input_adapter_t()2253 operator input_adapter_t()
2254 {
2255 return ia;
2256 }
2257
2258 private:
2259 /// the actual adapter
2260 input_adapter_t ia = nullptr;
2261 };
2262 }
2263 }
2264
2265 // #include <nlohmann/detail/input/lexer.hpp>
2266
2267
2268 #include <clocale> // localeconv
2269 #include <cstddef> // size_t
2270 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
2271 #include <cstdio> // snprintf
2272 #include <initializer_list> // initializer_list
2273 #include <string> // char_traits, string
2274 #include <vector> // vector
2275
2276 // #include <nlohmann/detail/macro_scope.hpp>
2277
2278 // #include <nlohmann/detail/input/input_adapters.hpp>
2279
2280
2281 namespace nlohmann
2282 {
2283 namespace detail
2284 {
2285 ///////////
2286 // lexer //
2287 ///////////
2288
2289 /*!
2290 @brief lexical analysis
2291
2292 This class organizes the lexical analysis during JSON deserialization.
2293 */
2294 template<typename BasicJsonType>
2295 class lexer
2296 {
2297 using number_integer_t = typename BasicJsonType::number_integer_t;
2298 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2299 using number_float_t = typename BasicJsonType::number_float_t;
2300 using string_t = typename BasicJsonType::string_t;
2301
2302 public:
2303 /// token types for the parser
2304 enum class token_type
2305 {
2306 uninitialized, ///< indicating the scanner is uninitialized
2307 literal_true, ///< the `true` literal
2308 literal_false, ///< the `false` literal
2309 literal_null, ///< the `null` literal
2310 value_string, ///< a string -- use get_string() for actual value
2311 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
2312 value_integer, ///< a signed integer -- use get_number_integer() for actual value
2313 value_float, ///< an floating point number -- use get_number_float() for actual value
2314 begin_array, ///< the character for array begin `[`
2315 begin_object, ///< the character for object begin `{`
2316 end_array, ///< the character for array end `]`
2317 end_object, ///< the character for object end `}`
2318 name_separator, ///< the name separator `:`
2319 value_separator, ///< the value separator `,`
2320 parse_error, ///< indicating a parse error
2321 end_of_input, ///< indicating the end of the input buffer
2322 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
2323 };
2324
2325 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)2326 static const char* token_type_name(const token_type t) noexcept
2327 {
2328 switch (t)
2329 {
2330 case token_type::uninitialized:
2331 return "<uninitialized>";
2332 case token_type::literal_true:
2333 return "true literal";
2334 case token_type::literal_false:
2335 return "false literal";
2336 case token_type::literal_null:
2337 return "null literal";
2338 case token_type::value_string:
2339 return "string literal";
2340 case lexer::token_type::value_unsigned:
2341 case lexer::token_type::value_integer:
2342 case lexer::token_type::value_float:
2343 return "number literal";
2344 case token_type::begin_array:
2345 return "'['";
2346 case token_type::begin_object:
2347 return "'{'";
2348 case token_type::end_array:
2349 return "']'";
2350 case token_type::end_object:
2351 return "'}'";
2352 case token_type::name_separator:
2353 return "':'";
2354 case token_type::value_separator:
2355 return "','";
2356 case token_type::parse_error:
2357 return "<parse error>";
2358 case token_type::end_of_input:
2359 return "end of input";
2360 case token_type::literal_or_value:
2361 return "'[', '{', or a literal";
2362 // LCOV_EXCL_START
2363 default: // catch non-enum values
2364 return "unknown token";
2365 // LCOV_EXCL_STOP
2366 }
2367 }
2368
lexer(detail::input_adapter_t && adapter)2369 explicit lexer(detail::input_adapter_t&& adapter)
2370 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2371
2372 // delete because of pointer members
2373 lexer(const lexer&) = delete;
2374 lexer& operator=(lexer&) = delete;
2375
2376 private:
2377 /////////////////////
2378 // locales
2379 /////////////////////
2380
2381 /// return the locale-dependent decimal point
get_decimal_point()2382 static char get_decimal_point() noexcept
2383 {
2384 const auto loc = localeconv();
2385 assert(loc != nullptr);
2386 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2387 }
2388
2389 /////////////////////
2390 // scan functions
2391 /////////////////////
2392
2393 /*!
2394 @brief get codepoint from 4 hex characters following `\u`
2395
2396 For input "\u c1 c2 c3 c4" the codepoint is:
2397 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
2398 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
2399
2400 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
2401 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
2402 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
2403 between the ASCII value of the character and the desired integer value.
2404
2405 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
2406 non-hex character)
2407 */
get_codepoint()2408 int get_codepoint()
2409 {
2410 // this function only makes sense after reading `\u`
2411 assert(current == 'u');
2412 int codepoint = 0;
2413
2414 const auto factors = { 12, 8, 4, 0 };
2415 for (const auto factor : factors)
2416 {
2417 get();
2418
2419 if (current >= '0' and current <= '9')
2420 {
2421 codepoint += ((current - 0x30) << factor);
2422 }
2423 else if (current >= 'A' and current <= 'F')
2424 {
2425 codepoint += ((current - 0x37) << factor);
2426 }
2427 else if (current >= 'a' and current <= 'f')
2428 {
2429 codepoint += ((current - 0x57) << factor);
2430 }
2431 else
2432 {
2433 return -1;
2434 }
2435 }
2436
2437 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2438 return codepoint;
2439 }
2440
2441 /*!
2442 @brief check if the next byte(s) are inside a given range
2443
2444 Adds the current byte and, for each passed range, reads a new byte and
2445 checks if it is inside the range. If a violation was detected, set up an
2446 error message and return false. Otherwise, return true.
2447
2448 @param[in] ranges list of integers; interpreted as list of pairs of
2449 inclusive lower and upper bound, respectively
2450
2451 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
2452 1, 2, or 3 pairs. This precondition is enforced by an assertion.
2453
2454 @return true if and only if no range violation was detected
2455 */
next_byte_in_range(std::initializer_list<int> ranges)2456 bool next_byte_in_range(std::initializer_list<int> ranges)
2457 {
2458 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2459 add(current);
2460
2461 for (auto range = ranges.begin(); range != ranges.end(); ++range)
2462 {
2463 get();
2464 if (JSON_LIKELY(*range <= current and current <= *(++range)))
2465 {
2466 add(current);
2467 }
2468 else
2469 {
2470 error_message = "invalid string: ill-formed UTF-8 byte";
2471 return false;
2472 }
2473 }
2474
2475 return true;
2476 }
2477
2478 /*!
2479 @brief scan a string literal
2480
2481 This function scans a string according to Sect. 7 of RFC 7159. While
2482 scanning, bytes are escaped and copied into buffer token_buffer. Then the
2483 function returns successfully, token_buffer is *not* null-terminated (as it
2484 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
2485 string.
2486
2487 @return token_type::value_string if string could be successfully scanned,
2488 token_type::parse_error otherwise
2489
2490 @note In case of errors, variable error_message contains a textual
2491 description.
2492 */
scan_string()2493 token_type scan_string()
2494 {
2495 // reset token_buffer (ignore opening quote)
2496 reset();
2497
2498 // we entered the function by reading an open quote
2499 assert(current == '\"');
2500
2501 while (true)
2502 {
2503 // get next character
2504 switch (get())
2505 {
2506 // end of file while parsing string
2507 case std::char_traits<char>::eof():
2508 {
2509 error_message = "invalid string: missing closing quote";
2510 return token_type::parse_error;
2511 }
2512
2513 // closing quote
2514 case '\"':
2515 {
2516 return token_type::value_string;
2517 }
2518
2519 // escapes
2520 case '\\':
2521 {
2522 switch (get())
2523 {
2524 // quotation mark
2525 case '\"':
2526 add('\"');
2527 break;
2528 // reverse solidus
2529 case '\\':
2530 add('\\');
2531 break;
2532 // solidus
2533 case '/':
2534 add('/');
2535 break;
2536 // backspace
2537 case 'b':
2538 add('\b');
2539 break;
2540 // form feed
2541 case 'f':
2542 add('\f');
2543 break;
2544 // line feed
2545 case 'n':
2546 add('\n');
2547 break;
2548 // carriage return
2549 case 'r':
2550 add('\r');
2551 break;
2552 // tab
2553 case 't':
2554 add('\t');
2555 break;
2556
2557 // unicode escapes
2558 case 'u':
2559 {
2560 const int codepoint1 = get_codepoint();
2561 int codepoint = codepoint1; // start with codepoint1
2562
2563 if (JSON_UNLIKELY(codepoint1 == -1))
2564 {
2565 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2566 return token_type::parse_error;
2567 }
2568
2569 // check if code point is a high surrogate
2570 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2571 {
2572 // expect next \uxxxx entry
2573 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2574 {
2575 const int codepoint2 = get_codepoint();
2576
2577 if (JSON_UNLIKELY(codepoint2 == -1))
2578 {
2579 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2580 return token_type::parse_error;
2581 }
2582
2583 // check if codepoint2 is a low surrogate
2584 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2585 {
2586 // overwrite codepoint
2587 codepoint =
2588 // high surrogate occupies the most significant 22 bits
2589 (codepoint1 << 10)
2590 // low surrogate occupies the least significant 15 bits
2591 + codepoint2
2592 // there is still the 0xD800, 0xDC00 and 0x10000 noise
2593 // in the result so we have to subtract with:
2594 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2595 - 0x35FDC00;
2596 }
2597 else
2598 {
2599 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2600 return token_type::parse_error;
2601 }
2602 }
2603 else
2604 {
2605 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2606 return token_type::parse_error;
2607 }
2608 }
2609 else
2610 {
2611 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2612 {
2613 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2614 return token_type::parse_error;
2615 }
2616 }
2617
2618 // result of the above calculation yields a proper codepoint
2619 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2620
2621 // translate codepoint into bytes
2622 if (codepoint < 0x80)
2623 {
2624 // 1-byte characters: 0xxxxxxx (ASCII)
2625 add(codepoint);
2626 }
2627 else if (codepoint <= 0x7FF)
2628 {
2629 // 2-byte characters: 110xxxxx 10xxxxxx
2630 add(0xC0 | (codepoint >> 6));
2631 add(0x80 | (codepoint & 0x3F));
2632 }
2633 else if (codepoint <= 0xFFFF)
2634 {
2635 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2636 add(0xE0 | (codepoint >> 12));
2637 add(0x80 | ((codepoint >> 6) & 0x3F));
2638 add(0x80 | (codepoint & 0x3F));
2639 }
2640 else
2641 {
2642 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2643 add(0xF0 | (codepoint >> 18));
2644 add(0x80 | ((codepoint >> 12) & 0x3F));
2645 add(0x80 | ((codepoint >> 6) & 0x3F));
2646 add(0x80 | (codepoint & 0x3F));
2647 }
2648
2649 break;
2650 }
2651
2652 // other characters after escape
2653 default:
2654 error_message = "invalid string: forbidden character after backslash";
2655 return token_type::parse_error;
2656 }
2657
2658 break;
2659 }
2660
2661 // invalid control characters
2662 case 0x00:
2663 case 0x01:
2664 case 0x02:
2665 case 0x03:
2666 case 0x04:
2667 case 0x05:
2668 case 0x06:
2669 case 0x07:
2670 case 0x08:
2671 case 0x09:
2672 case 0x0A:
2673 case 0x0B:
2674 case 0x0C:
2675 case 0x0D:
2676 case 0x0E:
2677 case 0x0F:
2678 case 0x10:
2679 case 0x11:
2680 case 0x12:
2681 case 0x13:
2682 case 0x14:
2683 case 0x15:
2684 case 0x16:
2685 case 0x17:
2686 case 0x18:
2687 case 0x19:
2688 case 0x1A:
2689 case 0x1B:
2690 case 0x1C:
2691 case 0x1D:
2692 case 0x1E:
2693 case 0x1F:
2694 {
2695 error_message = "invalid string: control character must be escaped";
2696 return token_type::parse_error;
2697 }
2698
2699 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2700 case 0x20:
2701 case 0x21:
2702 case 0x23:
2703 case 0x24:
2704 case 0x25:
2705 case 0x26:
2706 case 0x27:
2707 case 0x28:
2708 case 0x29:
2709 case 0x2A:
2710 case 0x2B:
2711 case 0x2C:
2712 case 0x2D:
2713 case 0x2E:
2714 case 0x2F:
2715 case 0x30:
2716 case 0x31:
2717 case 0x32:
2718 case 0x33:
2719 case 0x34:
2720 case 0x35:
2721 case 0x36:
2722 case 0x37:
2723 case 0x38:
2724 case 0x39:
2725 case 0x3A:
2726 case 0x3B:
2727 case 0x3C:
2728 case 0x3D:
2729 case 0x3E:
2730 case 0x3F:
2731 case 0x40:
2732 case 0x41:
2733 case 0x42:
2734 case 0x43:
2735 case 0x44:
2736 case 0x45:
2737 case 0x46:
2738 case 0x47:
2739 case 0x48:
2740 case 0x49:
2741 case 0x4A:
2742 case 0x4B:
2743 case 0x4C:
2744 case 0x4D:
2745 case 0x4E:
2746 case 0x4F:
2747 case 0x50:
2748 case 0x51:
2749 case 0x52:
2750 case 0x53:
2751 case 0x54:
2752 case 0x55:
2753 case 0x56:
2754 case 0x57:
2755 case 0x58:
2756 case 0x59:
2757 case 0x5A:
2758 case 0x5B:
2759 case 0x5D:
2760 case 0x5E:
2761 case 0x5F:
2762 case 0x60:
2763 case 0x61:
2764 case 0x62:
2765 case 0x63:
2766 case 0x64:
2767 case 0x65:
2768 case 0x66:
2769 case 0x67:
2770 case 0x68:
2771 case 0x69:
2772 case 0x6A:
2773 case 0x6B:
2774 case 0x6C:
2775 case 0x6D:
2776 case 0x6E:
2777 case 0x6F:
2778 case 0x70:
2779 case 0x71:
2780 case 0x72:
2781 case 0x73:
2782 case 0x74:
2783 case 0x75:
2784 case 0x76:
2785 case 0x77:
2786 case 0x78:
2787 case 0x79:
2788 case 0x7A:
2789 case 0x7B:
2790 case 0x7C:
2791 case 0x7D:
2792 case 0x7E:
2793 case 0x7F:
2794 {
2795 add(current);
2796 break;
2797 }
2798
2799 // U+0080..U+07FF: bytes C2..DF 80..BF
2800 case 0xC2:
2801 case 0xC3:
2802 case 0xC4:
2803 case 0xC5:
2804 case 0xC6:
2805 case 0xC7:
2806 case 0xC8:
2807 case 0xC9:
2808 case 0xCA:
2809 case 0xCB:
2810 case 0xCC:
2811 case 0xCD:
2812 case 0xCE:
2813 case 0xCF:
2814 case 0xD0:
2815 case 0xD1:
2816 case 0xD2:
2817 case 0xD3:
2818 case 0xD4:
2819 case 0xD5:
2820 case 0xD6:
2821 case 0xD7:
2822 case 0xD8:
2823 case 0xD9:
2824 case 0xDA:
2825 case 0xDB:
2826 case 0xDC:
2827 case 0xDD:
2828 case 0xDE:
2829 case 0xDF:
2830 {
2831 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2832 {
2833 return token_type::parse_error;
2834 }
2835 break;
2836 }
2837
2838 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2839 case 0xE0:
2840 {
2841 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2842 {
2843 return token_type::parse_error;
2844 }
2845 break;
2846 }
2847
2848 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2849 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2850 case 0xE1:
2851 case 0xE2:
2852 case 0xE3:
2853 case 0xE4:
2854 case 0xE5:
2855 case 0xE6:
2856 case 0xE7:
2857 case 0xE8:
2858 case 0xE9:
2859 case 0xEA:
2860 case 0xEB:
2861 case 0xEC:
2862 case 0xEE:
2863 case 0xEF:
2864 {
2865 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2866 {
2867 return token_type::parse_error;
2868 }
2869 break;
2870 }
2871
2872 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2873 case 0xED:
2874 {
2875 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2876 {
2877 return token_type::parse_error;
2878 }
2879 break;
2880 }
2881
2882 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2883 case 0xF0:
2884 {
2885 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2886 {
2887 return token_type::parse_error;
2888 }
2889 break;
2890 }
2891
2892 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2893 case 0xF1:
2894 case 0xF2:
2895 case 0xF3:
2896 {
2897 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2898 {
2899 return token_type::parse_error;
2900 }
2901 break;
2902 }
2903
2904 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2905 case 0xF4:
2906 {
2907 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2908 {
2909 return token_type::parse_error;
2910 }
2911 break;
2912 }
2913
2914 // remaining bytes (80..C1 and F5..FF) are ill-formed
2915 default:
2916 {
2917 error_message = "invalid string: ill-formed UTF-8 byte";
2918 return token_type::parse_error;
2919 }
2920 }
2921 }
2922 }
2923
strtof(float & f,const char * str,char ** endptr)2924 static void strtof(float& f, const char* str, char** endptr) noexcept
2925 {
2926 f = std::strtof(str, endptr);
2927 }
2928
strtof(double & f,const char * str,char ** endptr)2929 static void strtof(double& f, const char* str, char** endptr) noexcept
2930 {
2931 f = std::strtod(str, endptr);
2932 }
2933
strtof(long double & f,const char * str,char ** endptr)2934 static void strtof(long double& f, const char* str, char** endptr) noexcept
2935 {
2936 f = std::strtold(str, endptr);
2937 }
2938
2939 /*!
2940 @brief scan a number literal
2941
2942 This function scans a string according to Sect. 6 of RFC 7159.
2943
2944 The function is realized with a deterministic finite state machine derived
2945 from the grammar described in RFC 7159. Starting in state "init", the
2946 input is read and used to determined the next state. Only state "done"
2947 accepts the number. State "error" is a trap state to model errors. In the
2948 table below, "anything" means any character but the ones listed before.
2949
2950 state | 0 | 1-9 | e E | + | - | . | anything
2951 ---------|----------|----------|----------|---------|---------|----------|-----------
2952 init | zero | any1 | [error] | [error] | minus | [error] | [error]
2953 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
2954 zero | done | done | exponent | done | done | decimal1 | done
2955 any1 | any1 | any1 | exponent | done | done | decimal1 | done
2956 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
2957 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
2958 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
2959 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
2960 any2 | any2 | any2 | done | done | done | done | done
2961
2962 The state machine is realized with one label per state (prefixed with
2963 "scan_number_") and `goto` statements between them. The state machine
2964 contains cycles, but any cycle can be left when EOF is read. Therefore,
2965 the function is guaranteed to terminate.
2966
2967 During scanning, the read bytes are stored in token_buffer. This string is
2968 then converted to a signed integer, an unsigned integer, or a
2969 floating-point number.
2970
2971 @return token_type::value_unsigned, token_type::value_integer, or
2972 token_type::value_float if number could be successfully scanned,
2973 token_type::parse_error otherwise
2974
2975 @note The scanner is independent of the current locale. Internally, the
2976 locale's decimal point is used instead of `.` to work with the
2977 locale-dependent converters.
2978 */
scan_number()2979 token_type scan_number()
2980 {
2981 // reset token_buffer to store the number's bytes
2982 reset();
2983
2984 // the type of the parsed number; initially set to unsigned; will be
2985 // changed if minus sign, decimal point or exponent is read
2986 token_type number_type = token_type::value_unsigned;
2987
2988 // state (init): we just found out we need to scan a number
2989 switch (current)
2990 {
2991 case '-':
2992 {
2993 add(current);
2994 goto scan_number_minus;
2995 }
2996
2997 case '0':
2998 {
2999 add(current);
3000 goto scan_number_zero;
3001 }
3002
3003 case '1':
3004 case '2':
3005 case '3':
3006 case '4':
3007 case '5':
3008 case '6':
3009 case '7':
3010 case '8':
3011 case '9':
3012 {
3013 add(current);
3014 goto scan_number_any1;
3015 }
3016
3017 // LCOV_EXCL_START
3018 default:
3019 {
3020 // all other characters are rejected outside scan_number()
3021 assert(false);
3022 }
3023 // LCOV_EXCL_STOP
3024 }
3025
3026 scan_number_minus:
3027 // state: we just parsed a leading minus sign
3028 number_type = token_type::value_integer;
3029 switch (get())
3030 {
3031 case '0':
3032 {
3033 add(current);
3034 goto scan_number_zero;
3035 }
3036
3037 case '1':
3038 case '2':
3039 case '3':
3040 case '4':
3041 case '5':
3042 case '6':
3043 case '7':
3044 case '8':
3045 case '9':
3046 {
3047 add(current);
3048 goto scan_number_any1;
3049 }
3050
3051 default:
3052 {
3053 error_message = "invalid number; expected digit after '-'";
3054 return token_type::parse_error;
3055 }
3056 }
3057
3058 scan_number_zero:
3059 // state: we just parse a zero (maybe with a leading minus sign)
3060 switch (get())
3061 {
3062 case '.':
3063 {
3064 add(decimal_point_char);
3065 goto scan_number_decimal1;
3066 }
3067
3068 case 'e':
3069 case 'E':
3070 {
3071 add(current);
3072 goto scan_number_exponent;
3073 }
3074
3075 default:
3076 goto scan_number_done;
3077 }
3078
3079 scan_number_any1:
3080 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
3081 switch (get())
3082 {
3083 case '0':
3084 case '1':
3085 case '2':
3086 case '3':
3087 case '4':
3088 case '5':
3089 case '6':
3090 case '7':
3091 case '8':
3092 case '9':
3093 {
3094 add(current);
3095 goto scan_number_any1;
3096 }
3097
3098 case '.':
3099 {
3100 add(decimal_point_char);
3101 goto scan_number_decimal1;
3102 }
3103
3104 case 'e':
3105 case 'E':
3106 {
3107 add(current);
3108 goto scan_number_exponent;
3109 }
3110
3111 default:
3112 goto scan_number_done;
3113 }
3114
3115 scan_number_decimal1:
3116 // state: we just parsed a decimal point
3117 number_type = token_type::value_float;
3118 switch (get())
3119 {
3120 case '0':
3121 case '1':
3122 case '2':
3123 case '3':
3124 case '4':
3125 case '5':
3126 case '6':
3127 case '7':
3128 case '8':
3129 case '9':
3130 {
3131 add(current);
3132 goto scan_number_decimal2;
3133 }
3134
3135 default:
3136 {
3137 error_message = "invalid number; expected digit after '.'";
3138 return token_type::parse_error;
3139 }
3140 }
3141
3142 scan_number_decimal2:
3143 // we just parsed at least one number after a decimal point
3144 switch (get())
3145 {
3146 case '0':
3147 case '1':
3148 case '2':
3149 case '3':
3150 case '4':
3151 case '5':
3152 case '6':
3153 case '7':
3154 case '8':
3155 case '9':
3156 {
3157 add(current);
3158 goto scan_number_decimal2;
3159 }
3160
3161 case 'e':
3162 case 'E':
3163 {
3164 add(current);
3165 goto scan_number_exponent;
3166 }
3167
3168 default:
3169 goto scan_number_done;
3170 }
3171
3172 scan_number_exponent:
3173 // we just parsed an exponent
3174 number_type = token_type::value_float;
3175 switch (get())
3176 {
3177 case '+':
3178 case '-':
3179 {
3180 add(current);
3181 goto scan_number_sign;
3182 }
3183
3184 case '0':
3185 case '1':
3186 case '2':
3187 case '3':
3188 case '4':
3189 case '5':
3190 case '6':
3191 case '7':
3192 case '8':
3193 case '9':
3194 {
3195 add(current);
3196 goto scan_number_any2;
3197 }
3198
3199 default:
3200 {
3201 error_message =
3202 "invalid number; expected '+', '-', or digit after exponent";
3203 return token_type::parse_error;
3204 }
3205 }
3206
3207 scan_number_sign:
3208 // we just parsed an exponent sign
3209 switch (get())
3210 {
3211 case '0':
3212 case '1':
3213 case '2':
3214 case '3':
3215 case '4':
3216 case '5':
3217 case '6':
3218 case '7':
3219 case '8':
3220 case '9':
3221 {
3222 add(current);
3223 goto scan_number_any2;
3224 }
3225
3226 default:
3227 {
3228 error_message = "invalid number; expected digit after exponent sign";
3229 return token_type::parse_error;
3230 }
3231 }
3232
3233 scan_number_any2:
3234 // we just parsed a number after the exponent or exponent sign
3235 switch (get())
3236 {
3237 case '0':
3238 case '1':
3239 case '2':
3240 case '3':
3241 case '4':
3242 case '5':
3243 case '6':
3244 case '7':
3245 case '8':
3246 case '9':
3247 {
3248 add(current);
3249 goto scan_number_any2;
3250 }
3251
3252 default:
3253 goto scan_number_done;
3254 }
3255
3256 scan_number_done:
3257 // unget the character after the number (we only read it to know that
3258 // we are done scanning a number)
3259 unget();
3260
3261 char* endptr = nullptr;
3262 errno = 0;
3263
3264 // try to parse integers first and fall back to floats
3265 if (number_type == token_type::value_unsigned)
3266 {
3267 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3268
3269 // we checked the number format before
3270 assert(endptr == token_buffer.data() + token_buffer.size());
3271
3272 if (errno == 0)
3273 {
3274 value_unsigned = static_cast<number_unsigned_t>(x);
3275 if (value_unsigned == x)
3276 {
3277 return token_type::value_unsigned;
3278 }
3279 }
3280 }
3281 else if (number_type == token_type::value_integer)
3282 {
3283 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3284
3285 // we checked the number format before
3286 assert(endptr == token_buffer.data() + token_buffer.size());
3287
3288 if (errno == 0)
3289 {
3290 value_integer = static_cast<number_integer_t>(x);
3291 if (value_integer == x)
3292 {
3293 return token_type::value_integer;
3294 }
3295 }
3296 }
3297
3298 // this code is reached if we parse a floating-point number or if an
3299 // integer conversion above failed
3300 strtof(value_float, token_buffer.data(), &endptr);
3301
3302 // we checked the number format before
3303 assert(endptr == token_buffer.data() + token_buffer.size());
3304
3305 return token_type::value_float;
3306 }
3307
3308 /*!
3309 @param[in] literal_text the literal text to expect
3310 @param[in] length the length of the passed literal text
3311 @param[in] return_type the token type to return on success
3312 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)3313 token_type scan_literal(const char* literal_text, const std::size_t length,
3314 token_type return_type)
3315 {
3316 assert(current == literal_text[0]);
3317 for (std::size_t i = 1; i < length; ++i)
3318 {
3319 if (JSON_UNLIKELY(get() != literal_text[i]))
3320 {
3321 error_message = "invalid literal";
3322 return token_type::parse_error;
3323 }
3324 }
3325 return return_type;
3326 }
3327
3328 /////////////////////
3329 // input management
3330 /////////////////////
3331
3332 /// reset token_buffer; current character is beginning of token
reset()3333 void reset() noexcept
3334 {
3335 token_buffer.clear();
3336 token_string.clear();
3337 token_string.push_back(std::char_traits<char>::to_char_type(current));
3338 }
3339
3340 /*
3341 @brief get next character from the input
3342
3343 This function provides the interface to the used input adapter. It does
3344 not throw in case the input reached EOF, but returns a
3345 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
3346 for use in error messages.
3347
3348 @return character read from the input
3349 */
get()3350 std::char_traits<char>::int_type get()
3351 {
3352 ++chars_read;
3353 if (next_unget)
3354 {
3355 // just reset the next_unget variable and work with current
3356 next_unget = false;
3357 }
3358 else
3359 {
3360 current = ia->get_character();
3361 }
3362
3363 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3364 {
3365 token_string.push_back(std::char_traits<char>::to_char_type(current));
3366 }
3367 return current;
3368 }
3369
3370 /*!
3371 @brief unget current character (read it again on next get)
3372
3373 We implement unget by setting variable next_unget to true. The input is not
3374 changed - we just simulate ungetting by modifying chars_read and
3375 token_string. The next call to get() will behave as if the unget character
3376 is read again.
3377 */
unget()3378 void unget()
3379 {
3380 next_unget = true;
3381 --chars_read;
3382 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3383 {
3384 assert(token_string.size() != 0);
3385 token_string.pop_back();
3386 }
3387 }
3388
3389 /// add a character to token_buffer
add(int c)3390 void add(int c)
3391 {
3392 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3393 }
3394
3395 public:
3396 /////////////////////
3397 // value getters
3398 /////////////////////
3399
3400 /// return integer value
get_number_integer() const3401 constexpr number_integer_t get_number_integer() const noexcept
3402 {
3403 return value_integer;
3404 }
3405
3406 /// return unsigned integer value
get_number_unsigned() const3407 constexpr number_unsigned_t get_number_unsigned() const noexcept
3408 {
3409 return value_unsigned;
3410 }
3411
3412 /// return floating-point value
get_number_float() const3413 constexpr number_float_t get_number_float() const noexcept
3414 {
3415 return value_float;
3416 }
3417
3418 /// return current string value (implicitly resets the token; useful only once)
get_string()3419 string_t& get_string()
3420 {
3421 return token_buffer;
3422 }
3423
3424 /////////////////////
3425 // diagnostics
3426 /////////////////////
3427
3428 /// return position of last read token
get_position() const3429 constexpr std::size_t get_position() const noexcept
3430 {
3431 return chars_read;
3432 }
3433
3434 /// return the last read token (for errors only). Will never contain EOF
3435 /// (an arbitrary value that is not a valid char value, often -1), because
3436 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const3437 std::string get_token_string() const
3438 {
3439 // escape control characters
3440 std::string result;
3441 for (const auto c : token_string)
3442 {
3443 if ('\x00' <= c and c <= '\x1F')
3444 {
3445 // escape control characters
3446 char cs[9];
3447 snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
3448 result += cs;
3449 }
3450 else
3451 {
3452 // add character as is
3453 result.push_back(c);
3454 }
3455 }
3456
3457 return result;
3458 }
3459
3460 /// return syntax error message
get_error_message() const3461 constexpr const char* get_error_message() const noexcept
3462 {
3463 return error_message;
3464 }
3465
3466 /////////////////////
3467 // actual scanner
3468 /////////////////////
3469
3470 /*!
3471 @brief skip the UTF-8 byte order mark
3472 @return true iff there is no BOM or the correct BOM has been skipped
3473 */
skip_bom()3474 bool skip_bom()
3475 {
3476 if (get() == 0xEF)
3477 {
3478 if (get() == 0xBB and get() == 0xBF)
3479 {
3480 // we completely parsed the BOM
3481 return true;
3482 }
3483 else
3484 {
3485 // after reading 0xEF, an unexpected character followed
3486 return false;
3487 }
3488 }
3489 else
3490 {
3491 // the first character is not the beginning of the BOM; unget it to
3492 // process is later
3493 unget();
3494 return true;
3495 }
3496 }
3497
scan()3498 token_type scan()
3499 {
3500 // initially, skip the BOM
3501 if (chars_read == 0 and not skip_bom())
3502 {
3503 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
3504 return token_type::parse_error;
3505 }
3506
3507 // read next character and ignore whitespace
3508 do
3509 {
3510 get();
3511 }
3512 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3513
3514 switch (current)
3515 {
3516 // structural characters
3517 case '[':
3518 return token_type::begin_array;
3519 case ']':
3520 return token_type::end_array;
3521 case '{':
3522 return token_type::begin_object;
3523 case '}':
3524 return token_type::end_object;
3525 case ':':
3526 return token_type::name_separator;
3527 case ',':
3528 return token_type::value_separator;
3529
3530 // literals
3531 case 't':
3532 return scan_literal("true", 4, token_type::literal_true);
3533 case 'f':
3534 return scan_literal("false", 5, token_type::literal_false);
3535 case 'n':
3536 return scan_literal("null", 4, token_type::literal_null);
3537
3538 // string
3539 case '\"':
3540 return scan_string();
3541
3542 // number
3543 case '-':
3544 case '0':
3545 case '1':
3546 case '2':
3547 case '3':
3548 case '4':
3549 case '5':
3550 case '6':
3551 case '7':
3552 case '8':
3553 case '9':
3554 return scan_number();
3555
3556 // end of input (the null byte is needed when parsing from
3557 // string literals)
3558 case '\0':
3559 case std::char_traits<char>::eof():
3560 return token_type::end_of_input;
3561
3562 // error
3563 default:
3564 error_message = "invalid literal";
3565 return token_type::parse_error;
3566 }
3567 }
3568
3569 private:
3570 /// input adapter
3571 detail::input_adapter_t ia = nullptr;
3572
3573 /// the current character
3574 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3575
3576 /// whether the next get() call should just return current
3577 bool next_unget = false;
3578
3579 /// the number of characters read
3580 std::size_t chars_read = 0;
3581
3582 /// raw input token string (for error messages)
3583 std::vector<char> token_string {};
3584
3585 /// buffer for variable-length tokens (numbers, strings)
3586 string_t token_buffer {};
3587
3588 /// a description of occurred lexer errors
3589 const char* error_message = "";
3590
3591 // number values
3592 number_integer_t value_integer = 0;
3593 number_unsigned_t value_unsigned = 0;
3594 number_float_t value_float = 0;
3595
3596 /// the decimal point
3597 const char decimal_point_char = '.';
3598 };
3599 }
3600 }
3601
3602 // #include <nlohmann/detail/input/parser.hpp>
3603
3604
3605 #include <cassert> // assert
3606 #include <cmath> // isfinite
3607 #include <cstdint> // uint8_t
3608 #include <functional> // function
3609 #include <string> // string
3610 #include <utility> // move
3611
3612 // #include <nlohmann/detail/exceptions.hpp>
3613
3614 // #include <nlohmann/detail/macro_scope.hpp>
3615
3616 // #include <nlohmann/detail/meta/is_sax.hpp>
3617
3618
3619 #include <cstdint> // size_t
3620 #include <utility> // declval
3621
3622 // #include <nlohmann/detail/meta/detected.hpp>
3623
3624 // #include <nlohmann/detail/meta/type_traits.hpp>
3625
3626
3627 namespace nlohmann
3628 {
3629 namespace detail
3630 {
3631 template <typename T>
3632 using null_function_t = decltype(std::declval<T&>().null());
3633
3634 template <typename T>
3635 using boolean_function_t =
3636 decltype(std::declval<T&>().boolean(std::declval<bool>()));
3637
3638 template <typename T, typename Integer>
3639 using number_integer_function_t =
3640 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3641
3642 template <typename T, typename Unsigned>
3643 using number_unsigned_function_t =
3644 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3645
3646 template <typename T, typename Float, typename String>
3647 using number_float_function_t = decltype(std::declval<T&>().number_float(
3648 std::declval<Float>(), std::declval<const String&>()));
3649
3650 template <typename T, typename String>
3651 using string_function_t =
3652 decltype(std::declval<T&>().string(std::declval<String&>()));
3653
3654 template <typename T>
3655 using start_object_function_t =
3656 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3657
3658 template <typename T, typename String>
3659 using key_function_t =
3660 decltype(std::declval<T&>().key(std::declval<String&>()));
3661
3662 template <typename T>
3663 using end_object_function_t = decltype(std::declval<T&>().end_object());
3664
3665 template <typename T>
3666 using start_array_function_t =
3667 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3668
3669 template <typename T>
3670 using end_array_function_t = decltype(std::declval<T&>().end_array());
3671
3672 template <typename T, typename Exception>
3673 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3674 std::declval<std::size_t>(), std::declval<const std::string&>(),
3675 std::declval<const Exception&>()));
3676
3677 template <typename SAX, typename BasicJsonType>
3678 struct is_sax
3679 {
3680 private:
3681 static_assert(is_basic_json<BasicJsonType>::value,
3682 "BasicJsonType must be of type basic_json<...>");
3683
3684 using number_integer_t = typename BasicJsonType::number_integer_t;
3685 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3686 using number_float_t = typename BasicJsonType::number_float_t;
3687 using string_t = typename BasicJsonType::string_t;
3688 using exception_t = typename BasicJsonType::exception;
3689
3690 public:
3691 static constexpr bool value =
3692 is_detected_exact<bool, null_function_t, SAX>::value &&
3693 is_detected_exact<bool, boolean_function_t, SAX>::value &&
3694 is_detected_exact<bool, number_integer_function_t, SAX,
3695 number_integer_t>::value &&
3696 is_detected_exact<bool, number_unsigned_function_t, SAX,
3697 number_unsigned_t>::value &&
3698 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3699 string_t>::value &&
3700 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3701 is_detected_exact<bool, start_object_function_t, SAX>::value &&
3702 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3703 is_detected_exact<bool, end_object_function_t, SAX>::value &&
3704 is_detected_exact<bool, start_array_function_t, SAX>::value &&
3705 is_detected_exact<bool, end_array_function_t, SAX>::value &&
3706 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3707 };
3708
3709 template <typename SAX, typename BasicJsonType>
3710 struct is_sax_static_asserts
3711 {
3712 private:
3713 static_assert(is_basic_json<BasicJsonType>::value,
3714 "BasicJsonType must be of type basic_json<...>");
3715
3716 using number_integer_t = typename BasicJsonType::number_integer_t;
3717 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3718 using number_float_t = typename BasicJsonType::number_float_t;
3719 using string_t = typename BasicJsonType::string_t;
3720 using exception_t = typename BasicJsonType::exception;
3721
3722 public:
3723 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3724 "Missing/invalid function: bool null()");
3725 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3726 "Missing/invalid function: bool boolean(bool)");
3727 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3728 "Missing/invalid function: bool boolean(bool)");
3729 static_assert(
3730 is_detected_exact<bool, number_integer_function_t, SAX,
3731 number_integer_t>::value,
3732 "Missing/invalid function: bool number_integer(number_integer_t)");
3733 static_assert(
3734 is_detected_exact<bool, number_unsigned_function_t, SAX,
3735 number_unsigned_t>::value,
3736 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3737 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3738 number_float_t, string_t>::value,
3739 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3740 static_assert(
3741 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3742 "Missing/invalid function: bool string(string_t&)");
3743 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3744 "Missing/invalid function: bool start_object(std::size_t)");
3745 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3746 "Missing/invalid function: bool key(string_t&)");
3747 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3748 "Missing/invalid function: bool end_object()");
3749 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3750 "Missing/invalid function: bool start_array(std::size_t)");
3751 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3752 "Missing/invalid function: bool end_array()");
3753 static_assert(
3754 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3755 "Missing/invalid function: bool parse_error(std::size_t, const "
3756 "std::string&, const exception&)");
3757 };
3758 }
3759 }
3760
3761 // #include <nlohmann/detail/input/input_adapters.hpp>
3762
3763 // #include <nlohmann/detail/input/json_sax.hpp>
3764
3765
3766 #include <cstddef>
3767 #include <string>
3768 #include <vector>
3769
3770 // #include <nlohmann/detail/input/parser.hpp>
3771
3772 // #include <nlohmann/detail/exceptions.hpp>
3773
3774
3775 namespace nlohmann
3776 {
3777
3778 /*!
3779 @brief SAX interface
3780
3781 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
3782 Each function is called in different situations while the input is parsed. The
3783 boolean return value informs the parser whether to continue processing the
3784 input.
3785 */
3786 template<typename BasicJsonType>
3787 struct json_sax
3788 {
3789 /// type for (signed) integers
3790 using number_integer_t = typename BasicJsonType::number_integer_t;
3791 /// type for unsigned integers
3792 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3793 /// type for floating-point numbers
3794 using number_float_t = typename BasicJsonType::number_float_t;
3795 /// type for strings
3796 using string_t = typename BasicJsonType::string_t;
3797
3798 /*!
3799 @brief a null value was read
3800 @return whether parsing should proceed
3801 */
3802 virtual bool null() = 0;
3803
3804 /*!
3805 @brief a boolean value was read
3806 @param[in] val boolean value
3807 @return whether parsing should proceed
3808 */
3809 virtual bool boolean(bool val) = 0;
3810
3811 /*!
3812 @brief an integer number was read
3813 @param[in] val integer value
3814 @return whether parsing should proceed
3815 */
3816 virtual bool number_integer(number_integer_t val) = 0;
3817
3818 /*!
3819 @brief an unsigned integer number was read
3820 @param[in] val unsigned integer value
3821 @return whether parsing should proceed
3822 */
3823 virtual bool number_unsigned(number_unsigned_t val) = 0;
3824
3825 /*!
3826 @brief an floating-point number was read
3827 @param[in] val floating-point value
3828 @param[in] s raw token value
3829 @return whether parsing should proceed
3830 */
3831 virtual bool number_float(number_float_t val, const string_t& s) = 0;
3832
3833 /*!
3834 @brief a string was read
3835 @param[in] val string value
3836 @return whether parsing should proceed
3837 @note It is safe to move the passed string.
3838 */
3839 virtual bool string(string_t& val) = 0;
3840
3841 /*!
3842 @brief the beginning of an object was read
3843 @param[in] elements number of object elements or -1 if unknown
3844 @return whether parsing should proceed
3845 @note binary formats may report the number of elements
3846 */
3847 virtual bool start_object(std::size_t elements) = 0;
3848
3849 /*!
3850 @brief an object key was read
3851 @param[in] val object key
3852 @return whether parsing should proceed
3853 @note It is safe to move the passed string.
3854 */
3855 virtual bool key(string_t& val) = 0;
3856
3857 /*!
3858 @brief the end of an object was read
3859 @return whether parsing should proceed
3860 */
3861 virtual bool end_object() = 0;
3862
3863 /*!
3864 @brief the beginning of an array was read
3865 @param[in] elements number of array elements or -1 if unknown
3866 @return whether parsing should proceed
3867 @note binary formats may report the number of elements
3868 */
3869 virtual bool start_array(std::size_t elements) = 0;
3870
3871 /*!
3872 @brief the end of an array was read
3873 @return whether parsing should proceed
3874 */
3875 virtual bool end_array() = 0;
3876
3877 /*!
3878 @brief a parse error occurred
3879 @param[in] position the position in the input where the error occurs
3880 @param[in] last_token the last read token
3881 @param[in] error_msg a detailed error message
3882 @return whether parsing should proceed (must return false)
3883 */
3884 virtual bool parse_error(std::size_t position,
3885 const std::string& last_token,
3886 const detail::exception& ex) = 0;
3887
3888 virtual ~json_sax() = default;
3889 };
3890
3891
3892 namespace detail
3893 {
3894 /*!
3895 @brief SAX implementation to create a JSON value from SAX events
3896
3897 This class implements the @ref json_sax interface and processes the SAX events
3898 to create a JSON value which makes it basically a DOM parser. The structure or
3899 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
3900 a pointer to the respective array or object for each recursion depth.
3901
3902 After successful parsing, the value that is passed by reference to the
3903 constructor contains the parsed value.
3904
3905 @tparam BasicJsonType the JSON type
3906 */
3907 template<typename BasicJsonType>
3908 class json_sax_dom_parser
3909 {
3910 public:
3911 using number_integer_t = typename BasicJsonType::number_integer_t;
3912 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3913 using number_float_t = typename BasicJsonType::number_float_t;
3914 using string_t = typename BasicJsonType::string_t;
3915
3916 /*!
3917 @param[in, out] r reference to a JSON value that is manipulated while
3918 parsing
3919 @param[in] allow_exceptions_ whether parse errors yield exceptions
3920 */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)3921 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
3922 : root(r), allow_exceptions(allow_exceptions_)
3923 {}
3924
null()3925 bool null()
3926 {
3927 handle_value(nullptr);
3928 return true;
3929 }
3930
boolean(bool val)3931 bool boolean(bool val)
3932 {
3933 handle_value(val);
3934 return true;
3935 }
3936
number_integer(number_integer_t val)3937 bool number_integer(number_integer_t val)
3938 {
3939 handle_value(val);
3940 return true;
3941 }
3942
number_unsigned(number_unsigned_t val)3943 bool number_unsigned(number_unsigned_t val)
3944 {
3945 handle_value(val);
3946 return true;
3947 }
3948
number_float(number_float_t val,const string_t &)3949 bool number_float(number_float_t val, const string_t&)
3950 {
3951 handle_value(val);
3952 return true;
3953 }
3954
string(string_t & val)3955 bool string(string_t& val)
3956 {
3957 handle_value(val);
3958 return true;
3959 }
3960
start_object(std::size_t len)3961 bool start_object(std::size_t len)
3962 {
3963 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
3964
3965 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3966 {
3967 JSON_THROW(out_of_range::create(408,
3968 "excessive object size: " + std::to_string(len)));
3969 }
3970
3971 return true;
3972 }
3973
key(string_t & val)3974 bool key(string_t& val)
3975 {
3976 // add null at given key and store the reference for later
3977 object_element = &(ref_stack.back()->m_value.object->operator[](val));
3978 return true;
3979 }
3980
end_object()3981 bool end_object()
3982 {
3983 ref_stack.pop_back();
3984 return true;
3985 }
3986
start_array(std::size_t len)3987 bool start_array(std::size_t len)
3988 {
3989 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
3990
3991 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3992 {
3993 JSON_THROW(out_of_range::create(408,
3994 "excessive array size: " + std::to_string(len)));
3995 }
3996
3997 return true;
3998 }
3999
end_array()4000 bool end_array()
4001 {
4002 ref_stack.pop_back();
4003 return true;
4004 }
4005
parse_error(std::size_t,const std::string &,const detail::exception & ex)4006 bool parse_error(std::size_t, const std::string&,
4007 const detail::exception& ex)
4008 {
4009 errored = true;
4010 if (allow_exceptions)
4011 {
4012 // determine the proper exception type from the id
4013 switch ((ex.id / 100) % 100)
4014 {
4015 case 1:
4016 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4017 case 4:
4018 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4019 // LCOV_EXCL_START
4020 case 2:
4021 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4022 case 3:
4023 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4024 case 5:
4025 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4026 default:
4027 assert(false);
4028 // LCOV_EXCL_STOP
4029 }
4030 }
4031 return false;
4032 }
4033
is_errored() const4034 constexpr bool is_errored() const
4035 {
4036 return errored;
4037 }
4038
4039 private:
4040 /*!
4041 @invariant If the ref stack is empty, then the passed value will be the new
4042 root.
4043 @invariant If the ref stack contains a value, then it is an array or an
4044 object to which we can add elements
4045 */
4046 template<typename Value>
handle_value(Value && v)4047 BasicJsonType* handle_value(Value&& v)
4048 {
4049 if (ref_stack.empty())
4050 {
4051 root = BasicJsonType(std::forward<Value>(v));
4052 return &root;
4053 }
4054 else
4055 {
4056 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4057 if (ref_stack.back()->is_array())
4058 {
4059 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4060 return &(ref_stack.back()->m_value.array->back());
4061 }
4062 else
4063 {
4064 assert(object_element);
4065 *object_element = BasicJsonType(std::forward<Value>(v));
4066 return object_element;
4067 }
4068 }
4069 }
4070
4071 /// the parsed JSON value
4072 BasicJsonType& root;
4073 /// stack to model hierarchy of values
4074 std::vector<BasicJsonType*> ref_stack;
4075 /// helper to hold the reference for the next object element
4076 BasicJsonType* object_element = nullptr;
4077 /// whether a syntax error occurred
4078 bool errored = false;
4079 /// whether to throw exceptions in case of errors
4080 const bool allow_exceptions = true;
4081 };
4082
4083 template<typename BasicJsonType>
4084 class json_sax_dom_callback_parser
4085 {
4086 public:
4087 using number_integer_t = typename BasicJsonType::number_integer_t;
4088 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4089 using number_float_t = typename BasicJsonType::number_float_t;
4090 using string_t = typename BasicJsonType::string_t;
4091 using parser_callback_t = typename BasicJsonType::parser_callback_t;
4092 using parse_event_t = typename BasicJsonType::parse_event_t;
4093
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)4094 json_sax_dom_callback_parser(BasicJsonType& r,
4095 const parser_callback_t cb,
4096 const bool allow_exceptions_ = true)
4097 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4098 {
4099 keep_stack.push_back(true);
4100 }
4101
null()4102 bool null()
4103 {
4104 handle_value(nullptr);
4105 return true;
4106 }
4107
boolean(bool val)4108 bool boolean(bool val)
4109 {
4110 handle_value(val);
4111 return true;
4112 }
4113
number_integer(number_integer_t val)4114 bool number_integer(number_integer_t val)
4115 {
4116 handle_value(val);
4117 return true;
4118 }
4119
number_unsigned(number_unsigned_t val)4120 bool number_unsigned(number_unsigned_t val)
4121 {
4122 handle_value(val);
4123 return true;
4124 }
4125
number_float(number_float_t val,const string_t &)4126 bool number_float(number_float_t val, const string_t&)
4127 {
4128 handle_value(val);
4129 return true;
4130 }
4131
string(string_t & val)4132 bool string(string_t& val)
4133 {
4134 handle_value(val);
4135 return true;
4136 }
4137
start_object(std::size_t len)4138 bool start_object(std::size_t len)
4139 {
4140 // check callback for object start
4141 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4142 keep_stack.push_back(keep);
4143
4144 auto val = handle_value(BasicJsonType::value_t::object, true);
4145 ref_stack.push_back(val.second);
4146
4147 // check object limit
4148 if (ref_stack.back())
4149 {
4150 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4151 {
4152 JSON_THROW(out_of_range::create(408,
4153 "excessive object size: " + std::to_string(len)));
4154 }
4155 }
4156
4157 return true;
4158 }
4159
key(string_t & val)4160 bool key(string_t& val)
4161 {
4162 BasicJsonType k = BasicJsonType(val);
4163
4164 // check callback for key
4165 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4166 key_keep_stack.push_back(keep);
4167
4168 // add discarded value at given key and store the reference for later
4169 if (keep and ref_stack.back())
4170 {
4171 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4172 }
4173
4174 return true;
4175 }
4176
end_object()4177 bool end_object()
4178 {
4179 if (ref_stack.back())
4180 {
4181 if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4182 {
4183 // discard object
4184 *ref_stack.back() = discarded;
4185 }
4186 }
4187
4188 assert(not ref_stack.empty());
4189 assert(not keep_stack.empty());
4190 ref_stack.pop_back();
4191 keep_stack.pop_back();
4192
4193 if (not ref_stack.empty() and ref_stack.back())
4194 {
4195 // remove discarded value
4196 if (ref_stack.back()->is_object())
4197 {
4198 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4199 {
4200 if (it->is_discarded())
4201 {
4202 ref_stack.back()->erase(it);
4203 break;
4204 }
4205 }
4206 }
4207 }
4208
4209 return true;
4210 }
4211
start_array(std::size_t len)4212 bool start_array(std::size_t len)
4213 {
4214 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4215 keep_stack.push_back(keep);
4216
4217 auto val = handle_value(BasicJsonType::value_t::array, true);
4218 ref_stack.push_back(val.second);
4219
4220 // check array limit
4221 if (ref_stack.back())
4222 {
4223 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4224 {
4225 JSON_THROW(out_of_range::create(408,
4226 "excessive array size: " + std::to_string(len)));
4227 }
4228 }
4229
4230 return true;
4231 }
4232
end_array()4233 bool end_array()
4234 {
4235 bool keep = true;
4236
4237 if (ref_stack.back())
4238 {
4239 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4240 if (not keep)
4241 {
4242 // discard array
4243 *ref_stack.back() = discarded;
4244 }
4245 }
4246
4247 assert(not ref_stack.empty());
4248 assert(not keep_stack.empty());
4249 ref_stack.pop_back();
4250 keep_stack.pop_back();
4251
4252 // remove discarded value
4253 if (not keep and not ref_stack.empty())
4254 {
4255 if (ref_stack.back()->is_array())
4256 {
4257 ref_stack.back()->m_value.array->pop_back();
4258 }
4259 }
4260
4261 return true;
4262 }
4263
parse_error(std::size_t,const std::string &,const detail::exception & ex)4264 bool parse_error(std::size_t, const std::string&,
4265 const detail::exception& ex)
4266 {
4267 errored = true;
4268 if (allow_exceptions)
4269 {
4270 // determine the proper exception type from the id
4271 switch ((ex.id / 100) % 100)
4272 {
4273 case 1:
4274 JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4275 case 4:
4276 JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4277 // LCOV_EXCL_START
4278 case 2:
4279 JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4280 case 3:
4281 JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4282 case 5:
4283 JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4284 default:
4285 assert(false);
4286 // LCOV_EXCL_STOP
4287 }
4288 }
4289 return false;
4290 }
4291
is_errored() const4292 constexpr bool is_errored() const
4293 {
4294 return errored;
4295 }
4296
4297 private:
4298 /*!
4299 @param[in] v value to add to the JSON value we build during parsing
4300 @param[in] skip_callback whether we should skip calling the callback
4301 function; this is required after start_array() and
4302 start_object() SAX events, because otherwise we would call the
4303 callback function with an empty array or object, respectively.
4304
4305 @invariant If the ref stack is empty, then the passed value will be the new
4306 root.
4307 @invariant If the ref stack contains a value, then it is an array or an
4308 object to which we can add elements
4309
4310 @return pair of boolean (whether value should be kept) and pointer (to the
4311 passed value in the ref_stack hierarchy; nullptr if not kept)
4312 */
4313 template<typename Value>
handle_value(Value && v,const bool skip_callback=false)4314 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4315 {
4316 assert(not keep_stack.empty());
4317
4318 // do not handle this value if we know it would be added to a discarded
4319 // container
4320 if (not keep_stack.back())
4321 {
4322 return {false, nullptr};
4323 }
4324
4325 // create value
4326 auto value = BasicJsonType(std::forward<Value>(v));
4327
4328 // check callback
4329 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4330
4331 // do not handle this value if we just learnt it shall be discarded
4332 if (not keep)
4333 {
4334 return {false, nullptr};
4335 }
4336
4337 if (ref_stack.empty())
4338 {
4339 root = std::move(value);
4340 return {true, &root};
4341 }
4342 else
4343 {
4344 // skip this value if we already decided to skip the parent
4345 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4346 if (not ref_stack.back())
4347 {
4348 return {false, nullptr};
4349 }
4350
4351 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4352 if (ref_stack.back()->is_array())
4353 {
4354 ref_stack.back()->m_value.array->push_back(std::move(value));
4355 return {true, &(ref_stack.back()->m_value.array->back())};
4356 }
4357 else
4358 {
4359 // check if we should store an element for the current key
4360 assert(not key_keep_stack.empty());
4361 const bool store_element = key_keep_stack.back();
4362 key_keep_stack.pop_back();
4363
4364 if (not store_element)
4365 {
4366 return {false, nullptr};
4367 }
4368
4369 assert(object_element);
4370 *object_element = std::move(value);
4371 return {true, object_element};
4372 }
4373 }
4374 }
4375
4376 /// the parsed JSON value
4377 BasicJsonType& root;
4378 /// stack to model hierarchy of values
4379 std::vector<BasicJsonType*> ref_stack;
4380 /// stack to manage which values to keep
4381 std::vector<bool> keep_stack;
4382 /// stack to manage which object keys to keep
4383 std::vector<bool> key_keep_stack;
4384 /// helper to hold the reference for the next object element
4385 BasicJsonType* object_element = nullptr;
4386 /// whether a syntax error occurred
4387 bool errored = false;
4388 /// callback function
4389 const parser_callback_t callback = nullptr;
4390 /// whether to throw exceptions in case of errors
4391 const bool allow_exceptions = true;
4392 /// a discarded value for the callback
4393 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4394 };
4395
4396 template<typename BasicJsonType>
4397 class json_sax_acceptor
4398 {
4399 public:
4400 using number_integer_t = typename BasicJsonType::number_integer_t;
4401 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4402 using number_float_t = typename BasicJsonType::number_float_t;
4403 using string_t = typename BasicJsonType::string_t;
4404
null()4405 bool null()
4406 {
4407 return true;
4408 }
4409
boolean(bool)4410 bool boolean(bool)
4411 {
4412 return true;
4413 }
4414
number_integer(number_integer_t)4415 bool number_integer(number_integer_t)
4416 {
4417 return true;
4418 }
4419
number_unsigned(number_unsigned_t)4420 bool number_unsigned(number_unsigned_t)
4421 {
4422 return true;
4423 }
4424
number_float(number_float_t,const string_t &)4425 bool number_float(number_float_t, const string_t&)
4426 {
4427 return true;
4428 }
4429
string(string_t &)4430 bool string(string_t&)
4431 {
4432 return true;
4433 }
4434
start_object(std::size_t=std::size_t (-1))4435 bool start_object(std::size_t = std::size_t(-1))
4436 {
4437 return true;
4438 }
4439
key(string_t &)4440 bool key(string_t&)
4441 {
4442 return true;
4443 }
4444
end_object()4445 bool end_object()
4446 {
4447 return true;
4448 }
4449
start_array(std::size_t=std::size_t (-1))4450 bool start_array(std::size_t = std::size_t(-1))
4451 {
4452 return true;
4453 }
4454
end_array()4455 bool end_array()
4456 {
4457 return true;
4458 }
4459
parse_error(std::size_t,const std::string &,const detail::exception &)4460 bool parse_error(std::size_t, const std::string&, const detail::exception&)
4461 {
4462 return false;
4463 }
4464 };
4465 }
4466
4467 }
4468
4469 // #include <nlohmann/detail/input/lexer.hpp>
4470
4471 // #include <nlohmann/detail/value_t.hpp>
4472
4473
4474 namespace nlohmann
4475 {
4476 namespace detail
4477 {
4478 ////////////
4479 // parser //
4480 ////////////
4481
4482 /*!
4483 @brief syntax analysis
4484
4485 This class implements a recursive decent parser.
4486 */
4487 template<typename BasicJsonType>
4488 class parser
4489 {
4490 using number_integer_t = typename BasicJsonType::number_integer_t;
4491 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4492 using number_float_t = typename BasicJsonType::number_float_t;
4493 using string_t = typename BasicJsonType::string_t;
4494 using lexer_t = lexer<BasicJsonType>;
4495 using token_type = typename lexer_t::token_type;
4496
4497 public:
4498 enum class parse_event_t : uint8_t
4499 {
4500 /// the parser read `{` and started to process a JSON object
4501 object_start,
4502 /// the parser read `}` and finished processing a JSON object
4503 object_end,
4504 /// the parser read `[` and started to process a JSON array
4505 array_start,
4506 /// the parser read `]` and finished processing a JSON array
4507 array_end,
4508 /// the parser read a key of a value in an object
4509 key,
4510 /// the parser finished reading a JSON value
4511 value
4512 };
4513
4514 using parser_callback_t =
4515 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4516
4517 /// a parser reading from an input adapter
parser(detail::input_adapter_t && adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)4518 explicit parser(detail::input_adapter_t&& adapter,
4519 const parser_callback_t cb = nullptr,
4520 const bool allow_exceptions_ = true)
4521 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
4522 {
4523 // read first token
4524 get_token();
4525 }
4526
4527 /*!
4528 @brief public parser interface
4529
4530 @param[in] strict whether to expect the last token to be EOF
4531 @param[in,out] result parsed JSON value
4532
4533 @throw parse_error.101 in case of an unexpected token
4534 @throw parse_error.102 if to_unicode fails or surrogate error
4535 @throw parse_error.103 if to_unicode fails
4536 */
parse(const bool strict,BasicJsonType & result)4537 void parse(const bool strict, BasicJsonType& result)
4538 {
4539 if (callback)
4540 {
4541 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
4542 sax_parse_internal(&sdp);
4543 result.assert_invariant();
4544
4545 // in strict mode, input must be completely read
4546 if (strict and (get_token() != token_type::end_of_input))
4547 {
4548 sdp.parse_error(m_lexer.get_position(),
4549 m_lexer.get_token_string(),
4550 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4551 }
4552
4553 // in case of an error, return discarded value
4554 if (sdp.is_errored())
4555 {
4556 result = value_t::discarded;
4557 return;
4558 }
4559
4560 // set top-level value to null if it was discarded by the callback
4561 // function
4562 if (result.is_discarded())
4563 {
4564 result = nullptr;
4565 }
4566 }
4567 else
4568 {
4569 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
4570 sax_parse_internal(&sdp);
4571 result.assert_invariant();
4572
4573 // in strict mode, input must be completely read
4574 if (strict and (get_token() != token_type::end_of_input))
4575 {
4576 sdp.parse_error(m_lexer.get_position(),
4577 m_lexer.get_token_string(),
4578 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4579 }
4580
4581 // in case of an error, return discarded value
4582 if (sdp.is_errored())
4583 {
4584 result = value_t::discarded;
4585 return;
4586 }
4587 }
4588 }
4589
4590 /*!
4591 @brief public accept interface
4592
4593 @param[in] strict whether to expect the last token to be EOF
4594 @return whether the input is a proper JSON text
4595 */
accept(const bool strict=true)4596 bool accept(const bool strict = true)
4597 {
4598 json_sax_acceptor<BasicJsonType> sax_acceptor;
4599 return sax_parse(&sax_acceptor, strict);
4600 }
4601
4602 template <typename SAX>
sax_parse(SAX * sax,const bool strict=true)4603 bool sax_parse(SAX* sax, const bool strict = true)
4604 {
4605 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
4606 const bool result = sax_parse_internal(sax);
4607
4608 // strict mode: next byte must be EOF
4609 if (result and strict and (get_token() != token_type::end_of_input))
4610 {
4611 return sax->parse_error(m_lexer.get_position(),
4612 m_lexer.get_token_string(),
4613 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4614 }
4615
4616 return result;
4617 }
4618
4619 private:
4620 template <typename SAX>
sax_parse_internal(SAX * sax)4621 bool sax_parse_internal(SAX* sax)
4622 {
4623 // stack to remember the hieararchy of structured values we are parsing
4624 // true = array; false = object
4625 std::vector<bool> states;
4626 // value to avoid a goto (see comment where set to true)
4627 bool skip_to_state_evaluation = false;
4628
4629 while (true)
4630 {
4631 if (not skip_to_state_evaluation)
4632 {
4633 // invariant: get_token() was called before each iteration
4634 switch (last_token)
4635 {
4636 case token_type::begin_object:
4637 {
4638 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
4639 {
4640 return false;
4641 }
4642
4643 // closing } -> we are done
4644 if (get_token() == token_type::end_object)
4645 {
4646 if (JSON_UNLIKELY(not sax->end_object()))
4647 {
4648 return false;
4649 }
4650 break;
4651 }
4652
4653 // parse key
4654 if (JSON_UNLIKELY(last_token != token_type::value_string))
4655 {
4656 return sax->parse_error(m_lexer.get_position(),
4657 m_lexer.get_token_string(),
4658 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4659 }
4660 else
4661 {
4662 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4663 {
4664 return false;
4665 }
4666 }
4667
4668 // parse separator (:)
4669 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
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::name_separator)));
4674 }
4675
4676 // remember we are now inside an object
4677 states.push_back(false);
4678
4679 // parse values
4680 get_token();
4681 continue;
4682 }
4683
4684 case token_type::begin_array:
4685 {
4686 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
4687 {
4688 return false;
4689 }
4690
4691 // closing ] -> we are done
4692 if (get_token() == token_type::end_array)
4693 {
4694 if (JSON_UNLIKELY(not sax->end_array()))
4695 {
4696 return false;
4697 }
4698 break;
4699 }
4700
4701 // remember we are now inside an array
4702 states.push_back(true);
4703
4704 // parse values (no need to call get_token)
4705 continue;
4706 }
4707
4708 case token_type::value_float:
4709 {
4710 const auto res = m_lexer.get_number_float();
4711
4712 if (JSON_UNLIKELY(not std::isfinite(res)))
4713 {
4714 return sax->parse_error(m_lexer.get_position(),
4715 m_lexer.get_token_string(),
4716 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
4717 }
4718 else
4719 {
4720 if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
4721 {
4722 return false;
4723 }
4724 break;
4725 }
4726 }
4727
4728 case token_type::literal_false:
4729 {
4730 if (JSON_UNLIKELY(not sax->boolean(false)))
4731 {
4732 return false;
4733 }
4734 break;
4735 }
4736
4737 case token_type::literal_null:
4738 {
4739 if (JSON_UNLIKELY(not sax->null()))
4740 {
4741 return false;
4742 }
4743 break;
4744 }
4745
4746 case token_type::literal_true:
4747 {
4748 if (JSON_UNLIKELY(not sax->boolean(true)))
4749 {
4750 return false;
4751 }
4752 break;
4753 }
4754
4755 case token_type::value_integer:
4756 {
4757 if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
4758 {
4759 return false;
4760 }
4761 break;
4762 }
4763
4764 case token_type::value_string:
4765 {
4766 if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
4767 {
4768 return false;
4769 }
4770 break;
4771 }
4772
4773 case token_type::value_unsigned:
4774 {
4775 if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
4776 {
4777 return false;
4778 }
4779 break;
4780 }
4781
4782 case token_type::parse_error:
4783 {
4784 // using "uninitialized" to avoid "expected" message
4785 return sax->parse_error(m_lexer.get_position(),
4786 m_lexer.get_token_string(),
4787 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized)));
4788 }
4789
4790 default: // the last token was unexpected
4791 {
4792 return sax->parse_error(m_lexer.get_position(),
4793 m_lexer.get_token_string(),
4794 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value)));
4795 }
4796 }
4797 }
4798 else
4799 {
4800 skip_to_state_evaluation = false;
4801 }
4802
4803 // we reached this line after we successfully parsed a value
4804 if (states.empty())
4805 {
4806 // empty stack: we reached the end of the hieararchy: done
4807 return true;
4808 }
4809 else
4810 {
4811 if (states.back()) // array
4812 {
4813 // comma -> next value
4814 if (get_token() == token_type::value_separator)
4815 {
4816 // parse a new value
4817 get_token();
4818 continue;
4819 }
4820
4821 // closing ]
4822 if (JSON_LIKELY(last_token == token_type::end_array))
4823 {
4824 if (JSON_UNLIKELY(not sax->end_array()))
4825 {
4826 return false;
4827 }
4828
4829 // We are done with this array. Before we can parse a
4830 // new value, we need to evaluate the new state first.
4831 // By setting skip_to_state_evaluation to false, we
4832 // are effectively jumping to the beginning of this if.
4833 assert(not states.empty());
4834 states.pop_back();
4835 skip_to_state_evaluation = true;
4836 continue;
4837 }
4838 else
4839 {
4840 return sax->parse_error(m_lexer.get_position(),
4841 m_lexer.get_token_string(),
4842 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array)));
4843 }
4844 }
4845 else // object
4846 {
4847 // comma -> next value
4848 if (get_token() == token_type::value_separator)
4849 {
4850 // parse key
4851 if (JSON_UNLIKELY(get_token() != token_type::value_string))
4852 {
4853 return sax->parse_error(m_lexer.get_position(),
4854 m_lexer.get_token_string(),
4855 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4856 }
4857 else
4858 {
4859 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4860 {
4861 return false;
4862 }
4863 }
4864
4865 // parse separator (:)
4866 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
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::name_separator)));
4871 }
4872
4873 // parse values
4874 get_token();
4875 continue;
4876 }
4877
4878 // closing }
4879 if (JSON_LIKELY(last_token == token_type::end_object))
4880 {
4881 if (JSON_UNLIKELY(not sax->end_object()))
4882 {
4883 return false;
4884 }
4885
4886 // We are done with this object. Before we can parse a
4887 // new value, we need to evaluate the new state first.
4888 // By setting skip_to_state_evaluation to false, we
4889 // are effectively jumping to the beginning of this if.
4890 assert(not states.empty());
4891 states.pop_back();
4892 skip_to_state_evaluation = true;
4893 continue;
4894 }
4895 else
4896 {
4897 return sax->parse_error(m_lexer.get_position(),
4898 m_lexer.get_token_string(),
4899 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object)));
4900 }
4901 }
4902 }
4903 }
4904 }
4905
4906 /// get next token from lexer
get_token()4907 token_type get_token()
4908 {
4909 return (last_token = m_lexer.scan());
4910 }
4911
exception_message(const token_type expected)4912 std::string exception_message(const token_type expected)
4913 {
4914 std::string error_msg = "syntax error - ";
4915 if (last_token == token_type::parse_error)
4916 {
4917 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
4918 m_lexer.get_token_string() + "'";
4919 }
4920 else
4921 {
4922 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
4923 }
4924
4925 if (expected != token_type::uninitialized)
4926 {
4927 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
4928 }
4929
4930 return error_msg;
4931 }
4932
4933 private:
4934 /// callback function
4935 const parser_callback_t callback = nullptr;
4936 /// the type of the last read token
4937 token_type last_token = token_type::uninitialized;
4938 /// the lexer
4939 lexer_t m_lexer;
4940 /// whether to throw exceptions in case of errors
4941 const bool allow_exceptions = true;
4942 };
4943 }
4944 }
4945
4946 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
4947
4948
4949 #include <cstddef> // ptrdiff_t
4950 #include <limits> // numeric_limits
4951
4952 namespace nlohmann
4953 {
4954 namespace detail
4955 {
4956 /*
4957 @brief an iterator for primitive JSON types
4958
4959 This class models an iterator for primitive JSON types (boolean, number,
4960 string). It's only purpose is to allow the iterator/const_iterator classes
4961 to "iterate" over primitive values. Internally, the iterator is modeled by
4962 a `difference_type` variable. Value begin_value (`0`) models the begin,
4963 end_value (`1`) models past the end.
4964 */
4965 class primitive_iterator_t
4966 {
4967 private:
4968 using difference_type = std::ptrdiff_t;
4969 static constexpr difference_type begin_value = 0;
4970 static constexpr difference_type end_value = begin_value + 1;
4971
4972 /// iterator as signed integer type
4973 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
4974
4975 public:
get_value() const4976 constexpr difference_type get_value() const noexcept
4977 {
4978 return m_it;
4979 }
4980
4981 /// set iterator to a defined beginning
set_begin()4982 void set_begin() noexcept
4983 {
4984 m_it = begin_value;
4985 }
4986
4987 /// set iterator to a defined past the end
set_end()4988 void set_end() noexcept
4989 {
4990 m_it = end_value;
4991 }
4992
4993 /// return whether the iterator can be dereferenced
is_begin() const4994 constexpr bool is_begin() const noexcept
4995 {
4996 return m_it == begin_value;
4997 }
4998
4999 /// return whether the iterator is at end
is_end() const5000 constexpr bool is_end() const noexcept
5001 {
5002 return m_it == end_value;
5003 }
5004
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)5005 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5006 {
5007 return lhs.m_it == rhs.m_it;
5008 }
5009
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)5010 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5011 {
5012 return lhs.m_it < rhs.m_it;
5013 }
5014
operator +(difference_type n)5015 primitive_iterator_t operator+(difference_type n) noexcept
5016 {
5017 auto result = *this;
5018 result += n;
5019 return result;
5020 }
5021
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)5022 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5023 {
5024 return lhs.m_it - rhs.m_it;
5025 }
5026
operator ++()5027 primitive_iterator_t& operator++() noexcept
5028 {
5029 ++m_it;
5030 return *this;
5031 }
5032
operator ++(int)5033 primitive_iterator_t const operator++(int) noexcept
5034 {
5035 auto result = *this;
5036 ++m_it;
5037 return result;
5038 }
5039
operator --()5040 primitive_iterator_t& operator--() noexcept
5041 {
5042 --m_it;
5043 return *this;
5044 }
5045
operator --(int)5046 primitive_iterator_t const operator--(int) noexcept
5047 {
5048 auto result = *this;
5049 --m_it;
5050 return result;
5051 }
5052
operator +=(difference_type n)5053 primitive_iterator_t& operator+=(difference_type n) noexcept
5054 {
5055 m_it += n;
5056 return *this;
5057 }
5058
operator -=(difference_type n)5059 primitive_iterator_t& operator-=(difference_type n) noexcept
5060 {
5061 m_it -= n;
5062 return *this;
5063 }
5064 };
5065 }
5066 }
5067
5068 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5069
5070
5071 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5072
5073
5074 namespace nlohmann
5075 {
5076 namespace detail
5077 {
5078 /*!
5079 @brief an iterator value
5080
5081 @note This structure could easily be a union, but MSVC currently does not allow
5082 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
5083 */
5084 template<typename BasicJsonType> struct internal_iterator
5085 {
5086 /// iterator for JSON objects
5087 typename BasicJsonType::object_t::iterator object_iterator {};
5088 /// iterator for JSON arrays
5089 typename BasicJsonType::array_t::iterator array_iterator {};
5090 /// generic iterator for all other types
5091 primitive_iterator_t primitive_iterator {};
5092 };
5093 }
5094 }
5095
5096 // #include <nlohmann/detail/iterators/iter_impl.hpp>
5097
5098
5099 #include <ciso646> // not
5100 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
5101 #include <type_traits> // conditional, is_const, remove_const
5102
5103 // #include <nlohmann/detail/exceptions.hpp>
5104
5105 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5106
5107 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5108
5109 // #include <nlohmann/detail/macro_scope.hpp>
5110
5111 // #include <nlohmann/detail/meta/cpp_future.hpp>
5112
5113 // #include <nlohmann/detail/value_t.hpp>
5114
5115
5116 namespace nlohmann
5117 {
5118 namespace detail
5119 {
5120 // forward declare, to be able to friend it later on
5121 template<typename IteratorType> class iteration_proxy;
5122
5123 /*!
5124 @brief a template for a bidirectional iterator for the @ref basic_json class
5125
5126 This class implements a both iterators (iterator and const_iterator) for the
5127 @ref basic_json class.
5128
5129 @note An iterator is called *initialized* when a pointer to a JSON value has
5130 been set (e.g., by a constructor or a copy assignment). If the iterator is
5131 default-constructed, it is *uninitialized* and most methods are undefined.
5132 **The library uses assertions to detect calls on uninitialized iterators.**
5133
5134 @requirement The class satisfies the following concept requirements:
5135 -
5136 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5137 The iterator that can be moved can be moved in both directions (i.e.
5138 incremented and decremented).
5139
5140 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
5141 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
5142 */
5143 template<typename BasicJsonType>
5144 class iter_impl
5145 {
5146 /// allow basic_json to access private members
5147 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
5148 friend BasicJsonType;
5149 friend iteration_proxy<iter_impl>;
5150
5151 using object_t = typename BasicJsonType::object_t;
5152 using array_t = typename BasicJsonType::array_t;
5153 // make sure BasicJsonType is basic_json or const basic_json
5154 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
5155 "iter_impl only accepts (const) basic_json");
5156
5157 public:
5158
5159 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
5160 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
5161 /// A user-defined iterator should provide publicly accessible typedefs named
5162 /// iterator_category, value_type, difference_type, pointer, and reference.
5163 /// Note that value_type is required to be non-const, even for constant iterators.
5164 using iterator_category = std::bidirectional_iterator_tag;
5165
5166 /// the type of the values when the iterator is dereferenced
5167 using value_type = typename BasicJsonType::value_type;
5168 /// a type to represent differences between iterators
5169 using difference_type = typename BasicJsonType::difference_type;
5170 /// defines a pointer to the type iterated over (value_type)
5171 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
5172 typename BasicJsonType::const_pointer,
5173 typename BasicJsonType::pointer>::type;
5174 /// defines a reference to the type iterated over (value_type)
5175 using reference =
5176 typename std::conditional<std::is_const<BasicJsonType>::value,
5177 typename BasicJsonType::const_reference,
5178 typename BasicJsonType::reference>::type;
5179
5180 /// default constructor
5181 iter_impl() = default;
5182
5183 /*!
5184 @brief constructor for a given JSON instance
5185 @param[in] object pointer to a JSON object for this iterator
5186 @pre object != nullptr
5187 @post The iterator is initialized; i.e. `m_object != nullptr`.
5188 */
iter_impl(pointer object)5189 explicit iter_impl(pointer object) noexcept : m_object(object)
5190 {
5191 assert(m_object != nullptr);
5192
5193 switch (m_object->m_type)
5194 {
5195 case value_t::object:
5196 {
5197 m_it.object_iterator = typename object_t::iterator();
5198 break;
5199 }
5200
5201 case value_t::array:
5202 {
5203 m_it.array_iterator = typename array_t::iterator();
5204 break;
5205 }
5206
5207 default:
5208 {
5209 m_it.primitive_iterator = primitive_iterator_t();
5210 break;
5211 }
5212 }
5213 }
5214
5215 /*!
5216 @note The conventional copy constructor and copy assignment are implicitly
5217 defined. Combined with the following converting constructor and
5218 assignment, they support: (1) copy from iterator to iterator, (2)
5219 copy from const iterator to const iterator, and (3) conversion from
5220 iterator to const iterator. However conversion from const iterator
5221 to iterator is not defined.
5222 */
5223
5224 /*!
5225 @brief converting constructor
5226 @param[in] other non-const iterator to copy from
5227 @note It is not checked whether @a other is initialized.
5228 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)5229 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5230 : m_object(other.m_object), m_it(other.m_it) {}
5231
5232 /*!
5233 @brief converting assignment
5234 @param[in,out] other non-const iterator to copy from
5235 @return const/non-const iterator
5236 @note It is not checked whether @a other is initialized.
5237 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)5238 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5239 {
5240 m_object = other.m_object;
5241 m_it = other.m_it;
5242 return *this;
5243 }
5244
5245 private:
5246 /*!
5247 @brief set the iterator to the first value
5248 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5249 */
set_begin()5250 void set_begin() noexcept
5251 {
5252 assert(m_object != nullptr);
5253
5254 switch (m_object->m_type)
5255 {
5256 case value_t::object:
5257 {
5258 m_it.object_iterator = m_object->m_value.object->begin();
5259 break;
5260 }
5261
5262 case value_t::array:
5263 {
5264 m_it.array_iterator = m_object->m_value.array->begin();
5265 break;
5266 }
5267
5268 case value_t::null:
5269 {
5270 // set to end so begin()==end() is true: null is empty
5271 m_it.primitive_iterator.set_end();
5272 break;
5273 }
5274
5275 default:
5276 {
5277 m_it.primitive_iterator.set_begin();
5278 break;
5279 }
5280 }
5281 }
5282
5283 /*!
5284 @brief set the iterator past the last value
5285 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5286 */
set_end()5287 void set_end() noexcept
5288 {
5289 assert(m_object != nullptr);
5290
5291 switch (m_object->m_type)
5292 {
5293 case value_t::object:
5294 {
5295 m_it.object_iterator = m_object->m_value.object->end();
5296 break;
5297 }
5298
5299 case value_t::array:
5300 {
5301 m_it.array_iterator = m_object->m_value.array->end();
5302 break;
5303 }
5304
5305 default:
5306 {
5307 m_it.primitive_iterator.set_end();
5308 break;
5309 }
5310 }
5311 }
5312
5313 public:
5314 /*!
5315 @brief return a reference to the value pointed to by the iterator
5316 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5317 */
operator *() const5318 reference operator*() const
5319 {
5320 assert(m_object != nullptr);
5321
5322 switch (m_object->m_type)
5323 {
5324 case value_t::object:
5325 {
5326 assert(m_it.object_iterator != m_object->m_value.object->end());
5327 return m_it.object_iterator->second;
5328 }
5329
5330 case value_t::array:
5331 {
5332 assert(m_it.array_iterator != m_object->m_value.array->end());
5333 return *m_it.array_iterator;
5334 }
5335
5336 case value_t::null:
5337 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5338
5339 default:
5340 {
5341 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5342 {
5343 return *m_object;
5344 }
5345
5346 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5347 }
5348 }
5349 }
5350
5351 /*!
5352 @brief dereference the iterator
5353 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5354 */
operator ->() const5355 pointer operator->() const
5356 {
5357 assert(m_object != nullptr);
5358
5359 switch (m_object->m_type)
5360 {
5361 case value_t::object:
5362 {
5363 assert(m_it.object_iterator != m_object->m_value.object->end());
5364 return &(m_it.object_iterator->second);
5365 }
5366
5367 case value_t::array:
5368 {
5369 assert(m_it.array_iterator != m_object->m_value.array->end());
5370 return &*m_it.array_iterator;
5371 }
5372
5373 default:
5374 {
5375 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5376 {
5377 return m_object;
5378 }
5379
5380 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5381 }
5382 }
5383 }
5384
5385 /*!
5386 @brief post-increment (it++)
5387 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5388 */
operator ++(int)5389 iter_impl const operator++(int)
5390 {
5391 auto result = *this;
5392 ++(*this);
5393 return result;
5394 }
5395
5396 /*!
5397 @brief pre-increment (++it)
5398 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5399 */
operator ++()5400 iter_impl& operator++()
5401 {
5402 assert(m_object != nullptr);
5403
5404 switch (m_object->m_type)
5405 {
5406 case value_t::object:
5407 {
5408 std::advance(m_it.object_iterator, 1);
5409 break;
5410 }
5411
5412 case value_t::array:
5413 {
5414 std::advance(m_it.array_iterator, 1);
5415 break;
5416 }
5417
5418 default:
5419 {
5420 ++m_it.primitive_iterator;
5421 break;
5422 }
5423 }
5424
5425 return *this;
5426 }
5427
5428 /*!
5429 @brief post-decrement (it--)
5430 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5431 */
operator --(int)5432 iter_impl const operator--(int)
5433 {
5434 auto result = *this;
5435 --(*this);
5436 return result;
5437 }
5438
5439 /*!
5440 @brief pre-decrement (--it)
5441 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5442 */
operator --()5443 iter_impl& operator--()
5444 {
5445 assert(m_object != nullptr);
5446
5447 switch (m_object->m_type)
5448 {
5449 case value_t::object:
5450 {
5451 std::advance(m_it.object_iterator, -1);
5452 break;
5453 }
5454
5455 case value_t::array:
5456 {
5457 std::advance(m_it.array_iterator, -1);
5458 break;
5459 }
5460
5461 default:
5462 {
5463 --m_it.primitive_iterator;
5464 break;
5465 }
5466 }
5467
5468 return *this;
5469 }
5470
5471 /*!
5472 @brief comparison: equal
5473 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5474 */
operator ==(const iter_impl & other) const5475 bool operator==(const iter_impl& other) const
5476 {
5477 // if objects are not the same, the comparison is undefined
5478 if (JSON_UNLIKELY(m_object != other.m_object))
5479 {
5480 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5481 }
5482
5483 assert(m_object != nullptr);
5484
5485 switch (m_object->m_type)
5486 {
5487 case value_t::object:
5488 return (m_it.object_iterator == other.m_it.object_iterator);
5489
5490 case value_t::array:
5491 return (m_it.array_iterator == other.m_it.array_iterator);
5492
5493 default:
5494 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5495 }
5496 }
5497
5498 /*!
5499 @brief comparison: not equal
5500 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5501 */
operator !=(const iter_impl & other) const5502 bool operator!=(const iter_impl& other) const
5503 {
5504 return not operator==(other);
5505 }
5506
5507 /*!
5508 @brief comparison: smaller
5509 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5510 */
operator <(const iter_impl & other) const5511 bool operator<(const iter_impl& other) const
5512 {
5513 // if objects are not the same, the comparison is undefined
5514 if (JSON_UNLIKELY(m_object != other.m_object))
5515 {
5516 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5517 }
5518
5519 assert(m_object != nullptr);
5520
5521 switch (m_object->m_type)
5522 {
5523 case value_t::object:
5524 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
5525
5526 case value_t::array:
5527 return (m_it.array_iterator < other.m_it.array_iterator);
5528
5529 default:
5530 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
5531 }
5532 }
5533
5534 /*!
5535 @brief comparison: less than or equal
5536 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5537 */
operator <=(const iter_impl & other) const5538 bool operator<=(const iter_impl& other) const
5539 {
5540 return not other.operator < (*this);
5541 }
5542
5543 /*!
5544 @brief comparison: greater than
5545 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5546 */
operator >(const iter_impl & other) const5547 bool operator>(const iter_impl& other) const
5548 {
5549 return not operator<=(other);
5550 }
5551
5552 /*!
5553 @brief comparison: greater than or equal
5554 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5555 */
operator >=(const iter_impl & other) const5556 bool operator>=(const iter_impl& other) const
5557 {
5558 return not operator<(other);
5559 }
5560
5561 /*!
5562 @brief add to iterator
5563 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5564 */
operator +=(difference_type i)5565 iter_impl& operator+=(difference_type i)
5566 {
5567 assert(m_object != nullptr);
5568
5569 switch (m_object->m_type)
5570 {
5571 case value_t::object:
5572 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5573
5574 case value_t::array:
5575 {
5576 std::advance(m_it.array_iterator, i);
5577 break;
5578 }
5579
5580 default:
5581 {
5582 m_it.primitive_iterator += i;
5583 break;
5584 }
5585 }
5586
5587 return *this;
5588 }
5589
5590 /*!
5591 @brief subtract from iterator
5592 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5593 */
operator -=(difference_type i)5594 iter_impl& operator-=(difference_type i)
5595 {
5596 return operator+=(-i);
5597 }
5598
5599 /*!
5600 @brief add to iterator
5601 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5602 */
operator +(difference_type i) const5603 iter_impl operator+(difference_type i) const
5604 {
5605 auto result = *this;
5606 result += i;
5607 return result;
5608 }
5609
5610 /*!
5611 @brief addition of distance and iterator
5612 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5613 */
operator +(difference_type i,const iter_impl & it)5614 friend iter_impl operator+(difference_type i, const iter_impl& it)
5615 {
5616 auto result = it;
5617 result += i;
5618 return result;
5619 }
5620
5621 /*!
5622 @brief subtract from iterator
5623 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5624 */
operator -(difference_type i) const5625 iter_impl operator-(difference_type i) const
5626 {
5627 auto result = *this;
5628 result -= i;
5629 return result;
5630 }
5631
5632 /*!
5633 @brief return difference
5634 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5635 */
operator -(const iter_impl & other) const5636 difference_type operator-(const iter_impl& other) const
5637 {
5638 assert(m_object != nullptr);
5639
5640 switch (m_object->m_type)
5641 {
5642 case value_t::object:
5643 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5644
5645 case value_t::array:
5646 return m_it.array_iterator - other.m_it.array_iterator;
5647
5648 default:
5649 return m_it.primitive_iterator - other.m_it.primitive_iterator;
5650 }
5651 }
5652
5653 /*!
5654 @brief access to successor
5655 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5656 */
operator [](difference_type n) const5657 reference operator[](difference_type n) const
5658 {
5659 assert(m_object != nullptr);
5660
5661 switch (m_object->m_type)
5662 {
5663 case value_t::object:
5664 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
5665
5666 case value_t::array:
5667 return *std::next(m_it.array_iterator, n);
5668
5669 case value_t::null:
5670 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5671
5672 default:
5673 {
5674 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
5675 {
5676 return *m_object;
5677 }
5678
5679 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5680 }
5681 }
5682 }
5683
5684 /*!
5685 @brief return the key of an object iterator
5686 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5687 */
key() const5688 const typename object_t::key_type& key() const
5689 {
5690 assert(m_object != nullptr);
5691
5692 if (JSON_LIKELY(m_object->is_object()))
5693 {
5694 return m_it.object_iterator->first;
5695 }
5696
5697 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
5698 }
5699
5700 /*!
5701 @brief return the value of an iterator
5702 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5703 */
value() const5704 reference value() const
5705 {
5706 return operator*();
5707 }
5708
5709 private:
5710 /// associated JSON instance
5711 pointer m_object = nullptr;
5712 /// the actual iterator of the associated instance
5713 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
5714 };
5715 }
5716 }
5717
5718 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5719
5720 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
5721
5722
5723 #include <cstddef> // ptrdiff_t
5724 #include <iterator> // reverse_iterator
5725 #include <utility> // declval
5726
5727 namespace nlohmann
5728 {
5729 namespace detail
5730 {
5731 //////////////////////
5732 // reverse_iterator //
5733 //////////////////////
5734
5735 /*!
5736 @brief a template for a reverse iterator class
5737
5738 @tparam Base the base iterator type to reverse. Valid types are @ref
5739 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
5740 create @ref const_reverse_iterator).
5741
5742 @requirement The class satisfies the following concept requirements:
5743 -
5744 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5745 The iterator that can be moved can be moved in both directions (i.e.
5746 incremented and decremented).
5747 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
5748 It is possible to write to the pointed-to element (only if @a Base is
5749 @ref iterator).
5750
5751 @since version 1.0.0
5752 */
5753 template<typename Base>
5754 class json_reverse_iterator : public std::reverse_iterator<Base>
5755 {
5756 public:
5757 using difference_type = std::ptrdiff_t;
5758 /// shortcut to the reverse iterator adapter
5759 using base_iterator = std::reverse_iterator<Base>;
5760 /// the reference type for the pointed-to element
5761 using reference = typename Base::reference;
5762
5763 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)5764 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
5765 : base_iterator(it) {}
5766
5767 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)5768 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
5769
5770 /// post-increment (it++)
operator ++(int)5771 json_reverse_iterator const operator++(int)
5772 {
5773 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
5774 }
5775
5776 /// pre-increment (++it)
operator ++()5777 json_reverse_iterator& operator++()
5778 {
5779 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
5780 }
5781
5782 /// post-decrement (it--)
operator --(int)5783 json_reverse_iterator const operator--(int)
5784 {
5785 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
5786 }
5787
5788 /// pre-decrement (--it)
operator --()5789 json_reverse_iterator& operator--()
5790 {
5791 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
5792 }
5793
5794 /// add to iterator
operator +=(difference_type i)5795 json_reverse_iterator& operator+=(difference_type i)
5796 {
5797 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
5798 }
5799
5800 /// add to iterator
operator +(difference_type i) const5801 json_reverse_iterator operator+(difference_type i) const
5802 {
5803 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
5804 }
5805
5806 /// subtract from iterator
operator -(difference_type i) const5807 json_reverse_iterator operator-(difference_type i) const
5808 {
5809 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
5810 }
5811
5812 /// return difference
operator -(const json_reverse_iterator & other) const5813 difference_type operator-(const json_reverse_iterator& other) const
5814 {
5815 return base_iterator(*this) - base_iterator(other);
5816 }
5817
5818 /// access to successor
operator [](difference_type n) const5819 reference operator[](difference_type n) const
5820 {
5821 return *(this->operator+(n));
5822 }
5823
5824 /// return the key of an object iterator
key() const5825 auto key() const -> decltype(std::declval<Base>().key())
5826 {
5827 auto it = --this->base();
5828 return it.key();
5829 }
5830
5831 /// return the value of an iterator
value() const5832 reference value() const
5833 {
5834 auto it = --this->base();
5835 return it.operator * ();
5836 }
5837 };
5838 }
5839 }
5840
5841 // #include <nlohmann/detail/output/output_adapters.hpp>
5842
5843
5844 #include <algorithm> // copy
5845 #include <cstddef> // size_t
5846 #include <ios> // streamsize
5847 #include <iterator> // back_inserter
5848 #include <memory> // shared_ptr, make_shared
5849 #include <ostream> // basic_ostream
5850 #include <string> // basic_string
5851 #include <vector> // vector
5852
5853 namespace nlohmann
5854 {
5855 namespace detail
5856 {
5857 /// abstract output adapter interface
5858 template<typename CharType> struct output_adapter_protocol
5859 {
5860 virtual void write_character(CharType c) = 0;
5861 virtual void write_characters(const CharType* s, std::size_t length) = 0;
5862 virtual ~output_adapter_protocol() = default;
5863 };
5864
5865 /// a type to simplify interfaces
5866 template<typename CharType>
5867 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
5868
5869 /// output adapter for byte vectors
5870 template<typename CharType>
5871 class output_vector_adapter : public output_adapter_protocol<CharType>
5872 {
5873 public:
output_vector_adapter(std::vector<CharType> & vec)5874 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
5875
write_character(CharType c)5876 void write_character(CharType c) override
5877 {
5878 v.push_back(c);
5879 }
5880
write_characters(const CharType * s,std::size_t length)5881 void write_characters(const CharType* s, std::size_t length) override
5882 {
5883 std::copy(s, s + length, std::back_inserter(v));
5884 }
5885
5886 private:
5887 std::vector<CharType>& v;
5888 };
5889
5890 /// output adapter for output streams
5891 template<typename CharType>
5892 class output_stream_adapter : public output_adapter_protocol<CharType>
5893 {
5894 public:
output_stream_adapter(std::basic_ostream<CharType> & s)5895 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
5896
write_character(CharType c)5897 void write_character(CharType c) override
5898 {
5899 stream.put(c);
5900 }
5901
write_characters(const CharType * s,std::size_t length)5902 void write_characters(const CharType* s, std::size_t length) override
5903 {
5904 stream.write(s, static_cast<std::streamsize>(length));
5905 }
5906
5907 private:
5908 std::basic_ostream<CharType>& stream;
5909 };
5910
5911 /// output adapter for basic_string
5912 template<typename CharType, typename StringType = std::basic_string<CharType>>
5913 class output_string_adapter : public output_adapter_protocol<CharType>
5914 {
5915 public:
output_string_adapter(StringType & s)5916 explicit output_string_adapter(StringType& s) : str(s) {}
5917
write_character(CharType c)5918 void write_character(CharType c) override
5919 {
5920 str.push_back(c);
5921 }
5922
write_characters(const CharType * s,std::size_t length)5923 void write_characters(const CharType* s, std::size_t length) override
5924 {
5925 str.append(s, length);
5926 }
5927
5928 private:
5929 StringType& str;
5930 };
5931
5932 template<typename CharType, typename StringType = std::basic_string<CharType>>
5933 class output_adapter
5934 {
5935 public:
output_adapter(std::vector<CharType> & vec)5936 output_adapter(std::vector<CharType>& vec)
5937 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
5938
output_adapter(std::basic_ostream<CharType> & s)5939 output_adapter(std::basic_ostream<CharType>& s)
5940 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
5941
output_adapter(StringType & s)5942 output_adapter(StringType& s)
5943 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
5944
operator output_adapter_t<CharType>()5945 operator output_adapter_t<CharType>()
5946 {
5947 return oa;
5948 }
5949
5950 private:
5951 output_adapter_t<CharType> oa = nullptr;
5952 };
5953 }
5954 }
5955
5956 // #include <nlohmann/detail/input/binary_reader.hpp>
5957
5958
5959 #include <algorithm> // generate_n
5960 #include <array> // array
5961 #include <cassert> // assert
5962 #include <cmath> // ldexp
5963 #include <cstddef> // size_t
5964 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5965 #include <cstdio> // snprintf
5966 #include <cstring> // memcpy
5967 #include <iterator> // back_inserter
5968 #include <limits> // numeric_limits
5969 #include <string> // char_traits, string
5970 #include <utility> // make_pair, move
5971
5972 // #include <nlohmann/detail/input/input_adapters.hpp>
5973
5974 // #include <nlohmann/detail/input/json_sax.hpp>
5975
5976 // #include <nlohmann/detail/exceptions.hpp>
5977
5978 // #include <nlohmann/detail/macro_scope.hpp>
5979
5980 // #include <nlohmann/detail/meta/is_sax.hpp>
5981
5982 // #include <nlohmann/detail/value_t.hpp>
5983
5984
5985 namespace nlohmann
5986 {
5987 namespace detail
5988 {
5989 ///////////////////
5990 // binary reader //
5991 ///////////////////
5992
5993 /*!
5994 @brief deserialization of CBOR, MessagePack, and UBJSON values
5995 */
5996 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5997 class binary_reader
5998 {
5999 using number_integer_t = typename BasicJsonType::number_integer_t;
6000 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6001 using number_float_t = typename BasicJsonType::number_float_t;
6002 using string_t = typename BasicJsonType::string_t;
6003 using json_sax_t = SAX;
6004
6005 public:
6006 /*!
6007 @brief create a binary reader
6008
6009 @param[in] adapter input adapter to read from
6010 */
binary_reader(input_adapter_t adapter)6011 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
6012 {
6013 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
6014 assert(ia);
6015 }
6016
6017 /*!
6018 @param[in] format the binary format to parse
6019 @param[in] sax_ a SAX event processor
6020 @param[in] strict whether to expect the input to be consumed completed
6021
6022 @return
6023 */
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true)6024 bool sax_parse(const input_format_t format,
6025 json_sax_t* sax_,
6026 const bool strict = true)
6027 {
6028 sax = sax_;
6029 bool result = false;
6030
6031 switch (format)
6032 {
6033 case input_format_t::cbor:
6034 result = parse_cbor_internal();
6035 break;
6036
6037 case input_format_t::msgpack:
6038 result = parse_msgpack_internal();
6039 break;
6040
6041 case input_format_t::ubjson:
6042 result = parse_ubjson_internal();
6043 break;
6044
6045 // LCOV_EXCL_START
6046 default:
6047 assert(false);
6048 // LCOV_EXCL_STOP
6049 }
6050
6051 // strict mode: next byte must be EOF
6052 if (result and strict)
6053 {
6054 if (format == input_format_t::ubjson)
6055 {
6056 get_ignore_noop();
6057 }
6058 else
6059 {
6060 get();
6061 }
6062
6063 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6064 {
6065 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input"));
6066 }
6067 }
6068
6069 return result;
6070 }
6071
6072 /*!
6073 @brief determine system byte order
6074
6075 @return true if and only if system's byte order is little endian
6076
6077 @note from http://stackoverflow.com/a/1001328/266378
6078 */
little_endianess(int num=1)6079 static constexpr bool little_endianess(int num = 1) noexcept
6080 {
6081 return (*reinterpret_cast<char*>(&num) == 1);
6082 }
6083
6084 private:
6085 /*!
6086 @param[in] get_char whether a new character should be retrieved from the
6087 input (true, default) or whether the last read
6088 character should be considered instead
6089
6090 @return whether a valid CBOR value was passed to the SAX parser
6091 */
parse_cbor_internal(const bool get_char=true)6092 bool parse_cbor_internal(const bool get_char = true)
6093 {
6094 switch (get_char ? get() : current)
6095 {
6096 // EOF
6097 case std::char_traits<char>::eof():
6098 return unexpect_eof();
6099
6100 // Integer 0x00..0x17 (0..23)
6101 case 0x00:
6102 case 0x01:
6103 case 0x02:
6104 case 0x03:
6105 case 0x04:
6106 case 0x05:
6107 case 0x06:
6108 case 0x07:
6109 case 0x08:
6110 case 0x09:
6111 case 0x0A:
6112 case 0x0B:
6113 case 0x0C:
6114 case 0x0D:
6115 case 0x0E:
6116 case 0x0F:
6117 case 0x10:
6118 case 0x11:
6119 case 0x12:
6120 case 0x13:
6121 case 0x14:
6122 case 0x15:
6123 case 0x16:
6124 case 0x17:
6125 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6126
6127 case 0x18: // Unsigned integer (one-byte uint8_t follows)
6128 {
6129 uint8_t number;
6130 return get_number(number) and sax->number_unsigned(number);
6131 }
6132
6133 case 0x19: // Unsigned integer (two-byte uint16_t follows)
6134 {
6135 uint16_t number;
6136 return get_number(number) and sax->number_unsigned(number);
6137 }
6138
6139 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6140 {
6141 uint32_t number;
6142 return get_number(number) and sax->number_unsigned(number);
6143 }
6144
6145 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6146 {
6147 uint64_t number;
6148 return get_number(number) and sax->number_unsigned(number);
6149 }
6150
6151 // Negative integer -1-0x00..-1-0x17 (-1..-24)
6152 case 0x20:
6153 case 0x21:
6154 case 0x22:
6155 case 0x23:
6156 case 0x24:
6157 case 0x25:
6158 case 0x26:
6159 case 0x27:
6160 case 0x28:
6161 case 0x29:
6162 case 0x2A:
6163 case 0x2B:
6164 case 0x2C:
6165 case 0x2D:
6166 case 0x2E:
6167 case 0x2F:
6168 case 0x30:
6169 case 0x31:
6170 case 0x32:
6171 case 0x33:
6172 case 0x34:
6173 case 0x35:
6174 case 0x36:
6175 case 0x37:
6176 return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6177
6178 case 0x38: // Negative integer (one-byte uint8_t follows)
6179 {
6180 uint8_t number;
6181 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6182 }
6183
6184 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6185 {
6186 uint16_t number;
6187 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6188 }
6189
6190 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6191 {
6192 uint32_t number;
6193 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6194 }
6195
6196 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6197 {
6198 uint64_t number;
6199 return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1)
6200 - static_cast<number_integer_t>(number));
6201 }
6202
6203 // UTF-8 string (0x00..0x17 bytes follow)
6204 case 0x60:
6205 case 0x61:
6206 case 0x62:
6207 case 0x63:
6208 case 0x64:
6209 case 0x65:
6210 case 0x66:
6211 case 0x67:
6212 case 0x68:
6213 case 0x69:
6214 case 0x6A:
6215 case 0x6B:
6216 case 0x6C:
6217 case 0x6D:
6218 case 0x6E:
6219 case 0x6F:
6220 case 0x70:
6221 case 0x71:
6222 case 0x72:
6223 case 0x73:
6224 case 0x74:
6225 case 0x75:
6226 case 0x76:
6227 case 0x77:
6228 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6229 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6230 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6231 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6232 case 0x7F: // UTF-8 string (indefinite length)
6233 {
6234 string_t s;
6235 return get_cbor_string(s) and sax->string(s);
6236 }
6237
6238 // array (0x00..0x17 data items follow)
6239 case 0x80:
6240 case 0x81:
6241 case 0x82:
6242 case 0x83:
6243 case 0x84:
6244 case 0x85:
6245 case 0x86:
6246 case 0x87:
6247 case 0x88:
6248 case 0x89:
6249 case 0x8A:
6250 case 0x8B:
6251 case 0x8C:
6252 case 0x8D:
6253 case 0x8E:
6254 case 0x8F:
6255 case 0x90:
6256 case 0x91:
6257 case 0x92:
6258 case 0x93:
6259 case 0x94:
6260 case 0x95:
6261 case 0x96:
6262 case 0x97:
6263 return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6264
6265 case 0x98: // array (one-byte uint8_t for n follows)
6266 {
6267 uint8_t len;
6268 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6269 }
6270
6271 case 0x99: // array (two-byte uint16_t for n follow)
6272 {
6273 uint16_t len;
6274 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6275 }
6276
6277 case 0x9A: // array (four-byte uint32_t for n follow)
6278 {
6279 uint32_t len;
6280 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6281 }
6282
6283 case 0x9B: // array (eight-byte uint64_t for n follow)
6284 {
6285 uint64_t len;
6286 return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6287 }
6288
6289 case 0x9F: // array (indefinite length)
6290 return get_cbor_array(std::size_t(-1));
6291
6292 // map (0x00..0x17 pairs of data items follow)
6293 case 0xA0:
6294 case 0xA1:
6295 case 0xA2:
6296 case 0xA3:
6297 case 0xA4:
6298 case 0xA5:
6299 case 0xA6:
6300 case 0xA7:
6301 case 0xA8:
6302 case 0xA9:
6303 case 0xAA:
6304 case 0xAB:
6305 case 0xAC:
6306 case 0xAD:
6307 case 0xAE:
6308 case 0xAF:
6309 case 0xB0:
6310 case 0xB1:
6311 case 0xB2:
6312 case 0xB3:
6313 case 0xB4:
6314 case 0xB5:
6315 case 0xB6:
6316 case 0xB7:
6317 return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
6318
6319 case 0xB8: // map (one-byte uint8_t for n follows)
6320 {
6321 uint8_t len;
6322 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6323 }
6324
6325 case 0xB9: // map (two-byte uint16_t for n follow)
6326 {
6327 uint16_t len;
6328 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6329 }
6330
6331 case 0xBA: // map (four-byte uint32_t for n follow)
6332 {
6333 uint32_t len;
6334 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6335 }
6336
6337 case 0xBB: // map (eight-byte uint64_t for n follow)
6338 {
6339 uint64_t len;
6340 return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6341 }
6342
6343 case 0xBF: // map (indefinite length)
6344 return get_cbor_object(std::size_t(-1));
6345
6346 case 0xF4: // false
6347 return sax->boolean(false);
6348
6349 case 0xF5: // true
6350 return sax->boolean(true);
6351
6352 case 0xF6: // null
6353 return sax->null();
6354
6355 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6356 {
6357 const int byte1 = get();
6358 if (JSON_UNLIKELY(not unexpect_eof()))
6359 {
6360 return false;
6361 }
6362 const int byte2 = get();
6363 if (JSON_UNLIKELY(not unexpect_eof()))
6364 {
6365 return false;
6366 }
6367
6368 // code from RFC 7049, Appendix D, Figure 3:
6369 // As half-precision floating-point numbers were only added
6370 // to IEEE 754 in 2008, today's programming platforms often
6371 // still only have limited support for them. It is very
6372 // easy to include at least decoding support for them even
6373 // without such support. An example of a small decoder for
6374 // half-precision floating-point numbers in the C language
6375 // is shown in Fig. 3.
6376 const int half = (byte1 << 8) + byte2;
6377 const double val = [&half]
6378 {
6379 const int exp = (half >> 10) & 0x1F;
6380 const int mant = half & 0x3FF;
6381 assert(0 <= exp and exp <= 32);
6382 assert(0 <= mant and mant <= 1024);
6383 switch (exp)
6384 {
6385 case 0:
6386 return std::ldexp(mant, -24);
6387 case 31:
6388 return (mant == 0)
6389 ? std::numeric_limits<double>::infinity()
6390 : std::numeric_limits<double>::quiet_NaN();
6391 default:
6392 return std::ldexp(mant + 1024, exp - 25);
6393 }
6394 }();
6395 return sax->number_float((half & 0x8000) != 0
6396 ? static_cast<number_float_t>(-val)
6397 : static_cast<number_float_t>(val), "");
6398 }
6399
6400 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6401 {
6402 float number;
6403 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6404 }
6405
6406 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6407 {
6408 double number;
6409 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6410 }
6411
6412 default: // anything else (0xFF is handled inside the other types)
6413 {
6414 auto last_token = get_token_string();
6415 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token));
6416 }
6417 }
6418 }
6419
6420 /*!
6421 @return whether a valid MessagePack value was passed to the SAX parser
6422 */
parse_msgpack_internal()6423 bool parse_msgpack_internal()
6424 {
6425 switch (get())
6426 {
6427 // EOF
6428 case std::char_traits<char>::eof():
6429 return unexpect_eof();
6430
6431 // positive fixint
6432 case 0x00:
6433 case 0x01:
6434 case 0x02:
6435 case 0x03:
6436 case 0x04:
6437 case 0x05:
6438 case 0x06:
6439 case 0x07:
6440 case 0x08:
6441 case 0x09:
6442 case 0x0A:
6443 case 0x0B:
6444 case 0x0C:
6445 case 0x0D:
6446 case 0x0E:
6447 case 0x0F:
6448 case 0x10:
6449 case 0x11:
6450 case 0x12:
6451 case 0x13:
6452 case 0x14:
6453 case 0x15:
6454 case 0x16:
6455 case 0x17:
6456 case 0x18:
6457 case 0x19:
6458 case 0x1A:
6459 case 0x1B:
6460 case 0x1C:
6461 case 0x1D:
6462 case 0x1E:
6463 case 0x1F:
6464 case 0x20:
6465 case 0x21:
6466 case 0x22:
6467 case 0x23:
6468 case 0x24:
6469 case 0x25:
6470 case 0x26:
6471 case 0x27:
6472 case 0x28:
6473 case 0x29:
6474 case 0x2A:
6475 case 0x2B:
6476 case 0x2C:
6477 case 0x2D:
6478 case 0x2E:
6479 case 0x2F:
6480 case 0x30:
6481 case 0x31:
6482 case 0x32:
6483 case 0x33:
6484 case 0x34:
6485 case 0x35:
6486 case 0x36:
6487 case 0x37:
6488 case 0x38:
6489 case 0x39:
6490 case 0x3A:
6491 case 0x3B:
6492 case 0x3C:
6493 case 0x3D:
6494 case 0x3E:
6495 case 0x3F:
6496 case 0x40:
6497 case 0x41:
6498 case 0x42:
6499 case 0x43:
6500 case 0x44:
6501 case 0x45:
6502 case 0x46:
6503 case 0x47:
6504 case 0x48:
6505 case 0x49:
6506 case 0x4A:
6507 case 0x4B:
6508 case 0x4C:
6509 case 0x4D:
6510 case 0x4E:
6511 case 0x4F:
6512 case 0x50:
6513 case 0x51:
6514 case 0x52:
6515 case 0x53:
6516 case 0x54:
6517 case 0x55:
6518 case 0x56:
6519 case 0x57:
6520 case 0x58:
6521 case 0x59:
6522 case 0x5A:
6523 case 0x5B:
6524 case 0x5C:
6525 case 0x5D:
6526 case 0x5E:
6527 case 0x5F:
6528 case 0x60:
6529 case 0x61:
6530 case 0x62:
6531 case 0x63:
6532 case 0x64:
6533 case 0x65:
6534 case 0x66:
6535 case 0x67:
6536 case 0x68:
6537 case 0x69:
6538 case 0x6A:
6539 case 0x6B:
6540 case 0x6C:
6541 case 0x6D:
6542 case 0x6E:
6543 case 0x6F:
6544 case 0x70:
6545 case 0x71:
6546 case 0x72:
6547 case 0x73:
6548 case 0x74:
6549 case 0x75:
6550 case 0x76:
6551 case 0x77:
6552 case 0x78:
6553 case 0x79:
6554 case 0x7A:
6555 case 0x7B:
6556 case 0x7C:
6557 case 0x7D:
6558 case 0x7E:
6559 case 0x7F:
6560 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6561
6562 // fixmap
6563 case 0x80:
6564 case 0x81:
6565 case 0x82:
6566 case 0x83:
6567 case 0x84:
6568 case 0x85:
6569 case 0x86:
6570 case 0x87:
6571 case 0x88:
6572 case 0x89:
6573 case 0x8A:
6574 case 0x8B:
6575 case 0x8C:
6576 case 0x8D:
6577 case 0x8E:
6578 case 0x8F:
6579 return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
6580
6581 // fixarray
6582 case 0x90:
6583 case 0x91:
6584 case 0x92:
6585 case 0x93:
6586 case 0x94:
6587 case 0x95:
6588 case 0x96:
6589 case 0x97:
6590 case 0x98:
6591 case 0x99:
6592 case 0x9A:
6593 case 0x9B:
6594 case 0x9C:
6595 case 0x9D:
6596 case 0x9E:
6597 case 0x9F:
6598 return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
6599
6600 // fixstr
6601 case 0xA0:
6602 case 0xA1:
6603 case 0xA2:
6604 case 0xA3:
6605 case 0xA4:
6606 case 0xA5:
6607 case 0xA6:
6608 case 0xA7:
6609 case 0xA8:
6610 case 0xA9:
6611 case 0xAA:
6612 case 0xAB:
6613 case 0xAC:
6614 case 0xAD:
6615 case 0xAE:
6616 case 0xAF:
6617 case 0xB0:
6618 case 0xB1:
6619 case 0xB2:
6620 case 0xB3:
6621 case 0xB4:
6622 case 0xB5:
6623 case 0xB6:
6624 case 0xB7:
6625 case 0xB8:
6626 case 0xB9:
6627 case 0xBA:
6628 case 0xBB:
6629 case 0xBC:
6630 case 0xBD:
6631 case 0xBE:
6632 case 0xBF:
6633 {
6634 string_t s;
6635 return get_msgpack_string(s) and sax->string(s);
6636 }
6637
6638 case 0xC0: // nil
6639 return sax->null();
6640
6641 case 0xC2: // false
6642 return sax->boolean(false);
6643
6644 case 0xC3: // true
6645 return sax->boolean(true);
6646
6647 case 0xCA: // float 32
6648 {
6649 float number;
6650 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6651 }
6652
6653 case 0xCB: // float 64
6654 {
6655 double number;
6656 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6657 }
6658
6659 case 0xCC: // uint 8
6660 {
6661 uint8_t number;
6662 return get_number(number) and sax->number_unsigned(number);
6663 }
6664
6665 case 0xCD: // uint 16
6666 {
6667 uint16_t number;
6668 return get_number(number) and sax->number_unsigned(number);
6669 }
6670
6671 case 0xCE: // uint 32
6672 {
6673 uint32_t number;
6674 return get_number(number) and sax->number_unsigned(number);
6675 }
6676
6677 case 0xCF: // uint 64
6678 {
6679 uint64_t number;
6680 return get_number(number) and sax->number_unsigned(number);
6681 }
6682
6683 case 0xD0: // int 8
6684 {
6685 int8_t number;
6686 return get_number(number) and sax->number_integer(number);
6687 }
6688
6689 case 0xD1: // int 16
6690 {
6691 int16_t number;
6692 return get_number(number) and sax->number_integer(number);
6693 }
6694
6695 case 0xD2: // int 32
6696 {
6697 int32_t number;
6698 return get_number(number) and sax->number_integer(number);
6699 }
6700
6701 case 0xD3: // int 64
6702 {
6703 int64_t number;
6704 return get_number(number) and sax->number_integer(number);
6705 }
6706
6707 case 0xD9: // str 8
6708 case 0xDA: // str 16
6709 case 0xDB: // str 32
6710 {
6711 string_t s;
6712 return get_msgpack_string(s) and sax->string(s);
6713 }
6714
6715 case 0xDC: // array 16
6716 {
6717 uint16_t len;
6718 return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6719 }
6720
6721 case 0xDD: // array 32
6722 {
6723 uint32_t len;
6724 return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6725 }
6726
6727 case 0xDE: // map 16
6728 {
6729 uint16_t len;
6730 return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6731 }
6732
6733 case 0xDF: // map 32
6734 {
6735 uint32_t len;
6736 return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6737 }
6738
6739 // negative fixint
6740 case 0xE0:
6741 case 0xE1:
6742 case 0xE2:
6743 case 0xE3:
6744 case 0xE4:
6745 case 0xE5:
6746 case 0xE6:
6747 case 0xE7:
6748 case 0xE8:
6749 case 0xE9:
6750 case 0xEA:
6751 case 0xEB:
6752 case 0xEC:
6753 case 0xED:
6754 case 0xEE:
6755 case 0xEF:
6756 case 0xF0:
6757 case 0xF1:
6758 case 0xF2:
6759 case 0xF3:
6760 case 0xF4:
6761 case 0xF5:
6762 case 0xF6:
6763 case 0xF7:
6764 case 0xF8:
6765 case 0xF9:
6766 case 0xFA:
6767 case 0xFB:
6768 case 0xFC:
6769 case 0xFD:
6770 case 0xFE:
6771 case 0xFF:
6772 return sax->number_integer(static_cast<int8_t>(current));
6773
6774 default: // anything else
6775 {
6776 auto last_token = get_token_string();
6777 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token));
6778 }
6779 }
6780 }
6781
6782 /*!
6783 @param[in] get_char whether a new character should be retrieved from the
6784 input (true, default) or whether the last read
6785 character should be considered instead
6786
6787 @return whether a valid UBJSON value was passed to the SAX parser
6788 */
parse_ubjson_internal(const bool get_char=true)6789 bool parse_ubjson_internal(const bool get_char = true)
6790 {
6791 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6792 }
6793
6794 /*!
6795 @brief get next character from the input
6796
6797 This function provides the interface to the used input adapter. It does
6798 not throw in case the input reached EOF, but returns a -'ve valued
6799 `std::char_traits<char>::eof()` in that case.
6800
6801 @return character read from the input
6802 */
get()6803 int get()
6804 {
6805 ++chars_read;
6806 return (current = ia->get_character());
6807 }
6808
6809 /*!
6810 @return character read from the input after ignoring all 'N' entries
6811 */
get_ignore_noop()6812 int get_ignore_noop()
6813 {
6814 do
6815 {
6816 get();
6817 }
6818 while (current == 'N');
6819
6820 return current;
6821 }
6822
6823 /*
6824 @brief read a number from the input
6825
6826 @tparam NumberType the type of the number
6827 @param[out] result number of type @a NumberType
6828
6829 @return whether conversion completed
6830
6831 @note This function needs to respect the system's endianess, because
6832 bytes in CBOR, MessagePack, and UBJSON are stored in network order
6833 (big endian) and therefore need reordering on little endian systems.
6834 */
6835 template<typename NumberType>
get_number(NumberType & result)6836 bool get_number(NumberType& result)
6837 {
6838 // step 1: read input into array with system's byte order
6839 std::array<uint8_t, sizeof(NumberType)> vec;
6840 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
6841 {
6842 get();
6843 if (JSON_UNLIKELY(not unexpect_eof()))
6844 {
6845 return false;
6846 }
6847
6848 // reverse byte order prior to conversion if necessary
6849 if (is_little_endian)
6850 {
6851 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
6852 }
6853 else
6854 {
6855 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
6856 }
6857 }
6858
6859 // step 2: convert array into number of type T and return
6860 std::memcpy(&result, vec.data(), sizeof(NumberType));
6861 return true;
6862 }
6863
6864 /*!
6865 @brief create a string by reading characters from the input
6866
6867 @tparam NumberType the type of the number
6868 @param[in] len number of characters to read
6869 @param[out] string created by reading @a len bytes
6870
6871 @return whether string creation completed
6872
6873 @note We can not reserve @a len bytes for the result, because @a len
6874 may be too large. Usually, @ref unexpect_eof() detects the end of
6875 the input before we run out of string memory.
6876 */
6877 template<typename NumberType>
get_string(const NumberType len,string_t & result)6878 bool get_string(const NumberType len, string_t& result)
6879 {
6880 bool success = true;
6881 std::generate_n(std::back_inserter(result), len, [this, &success]()
6882 {
6883 get();
6884 if (JSON_UNLIKELY(not unexpect_eof()))
6885 {
6886 success = false;
6887 }
6888 return static_cast<char>(current);
6889 });
6890 return success;
6891 }
6892
6893 /*!
6894 @brief reads a CBOR string
6895
6896 This function first reads starting bytes to determine the expected
6897 string length and then copies this number of bytes into a string.
6898 Additionally, CBOR's strings with indefinite lengths are supported.
6899
6900 @param[out] result created string
6901
6902 @return whether string creation completed
6903 */
get_cbor_string(string_t & result)6904 bool get_cbor_string(string_t& result)
6905 {
6906 if (JSON_UNLIKELY(not unexpect_eof()))
6907 {
6908 return false;
6909 }
6910
6911 switch (current)
6912 {
6913 // UTF-8 string (0x00..0x17 bytes follow)
6914 case 0x60:
6915 case 0x61:
6916 case 0x62:
6917 case 0x63:
6918 case 0x64:
6919 case 0x65:
6920 case 0x66:
6921 case 0x67:
6922 case 0x68:
6923 case 0x69:
6924 case 0x6A:
6925 case 0x6B:
6926 case 0x6C:
6927 case 0x6D:
6928 case 0x6E:
6929 case 0x6F:
6930 case 0x70:
6931 case 0x71:
6932 case 0x72:
6933 case 0x73:
6934 case 0x74:
6935 case 0x75:
6936 case 0x76:
6937 case 0x77:
6938 {
6939 return get_string(current & 0x1F, result);
6940 }
6941
6942 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6943 {
6944 uint8_t len;
6945 return get_number(len) and get_string(len, result);
6946 }
6947
6948 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6949 {
6950 uint16_t len;
6951 return get_number(len) and get_string(len, result);
6952 }
6953
6954 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6955 {
6956 uint32_t len;
6957 return get_number(len) and get_string(len, result);
6958 }
6959
6960 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6961 {
6962 uint64_t len;
6963 return get_number(len) and get_string(len, result);
6964 }
6965
6966 case 0x7F: // UTF-8 string (indefinite length)
6967 {
6968 while (get() != 0xFF)
6969 {
6970 string_t chunk;
6971 if (not get_cbor_string(chunk))
6972 {
6973 return false;
6974 }
6975 result.append(chunk);
6976 }
6977 return true;
6978 }
6979
6980 default:
6981 {
6982 auto last_token = get_token_string();
6983 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token));
6984 }
6985 }
6986 }
6987
6988 /*!
6989 @param[in] len the length of the array or std::size_t(-1) for an
6990 array of indefinite size
6991 @return whether array creation completed
6992 */
get_cbor_array(const std::size_t len)6993 bool get_cbor_array(const std::size_t len)
6994 {
6995 if (JSON_UNLIKELY(not sax->start_array(len)))
6996 {
6997 return false;
6998 }
6999
7000 if (len != std::size_t(-1))
7001 for (std::size_t i = 0; i < len; ++i)
7002 {
7003 if (JSON_UNLIKELY(not parse_cbor_internal()))
7004 {
7005 return false;
7006 }
7007 }
7008 else
7009 {
7010 while (get() != 0xFF)
7011 {
7012 if (JSON_UNLIKELY(not parse_cbor_internal(false)))
7013 {
7014 return false;
7015 }
7016 }
7017 }
7018
7019 return sax->end_array();
7020 }
7021
7022 /*!
7023 @param[in] len the length of the object or std::size_t(-1) for an
7024 object of indefinite size
7025 @return whether object creation completed
7026 */
get_cbor_object(const std::size_t len)7027 bool get_cbor_object(const std::size_t len)
7028 {
7029 if (not JSON_UNLIKELY(sax->start_object(len)))
7030 {
7031 return false;
7032 }
7033
7034 string_t key;
7035 if (len != std::size_t(-1))
7036 {
7037 for (std::size_t i = 0; i < len; ++i)
7038 {
7039 get();
7040 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7041 {
7042 return false;
7043 }
7044
7045 if (JSON_UNLIKELY(not parse_cbor_internal()))
7046 {
7047 return false;
7048 }
7049 key.clear();
7050 }
7051 }
7052 else
7053 {
7054 while (get() != 0xFF)
7055 {
7056 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7057 {
7058 return false;
7059 }
7060
7061 if (JSON_UNLIKELY(not parse_cbor_internal()))
7062 {
7063 return false;
7064 }
7065 key.clear();
7066 }
7067 }
7068
7069 return sax->end_object();
7070 }
7071
7072 /*!
7073 @brief reads a MessagePack string
7074
7075 This function first reads starting bytes to determine the expected
7076 string length and then copies this number of bytes into a string.
7077
7078 @param[out] result created string
7079
7080 @return whether string creation completed
7081 */
get_msgpack_string(string_t & result)7082 bool get_msgpack_string(string_t& result)
7083 {
7084 if (JSON_UNLIKELY(not unexpect_eof()))
7085 {
7086 return false;
7087 }
7088
7089 switch (current)
7090 {
7091 // fixstr
7092 case 0xA0:
7093 case 0xA1:
7094 case 0xA2:
7095 case 0xA3:
7096 case 0xA4:
7097 case 0xA5:
7098 case 0xA6:
7099 case 0xA7:
7100 case 0xA8:
7101 case 0xA9:
7102 case 0xAA:
7103 case 0xAB:
7104 case 0xAC:
7105 case 0xAD:
7106 case 0xAE:
7107 case 0xAF:
7108 case 0xB0:
7109 case 0xB1:
7110 case 0xB2:
7111 case 0xB3:
7112 case 0xB4:
7113 case 0xB5:
7114 case 0xB6:
7115 case 0xB7:
7116 case 0xB8:
7117 case 0xB9:
7118 case 0xBA:
7119 case 0xBB:
7120 case 0xBC:
7121 case 0xBD:
7122 case 0xBE:
7123 case 0xBF:
7124 {
7125 return get_string(current & 0x1F, result);
7126 }
7127
7128 case 0xD9: // str 8
7129 {
7130 uint8_t len;
7131 return get_number(len) and get_string(len, result);
7132 }
7133
7134 case 0xDA: // str 16
7135 {
7136 uint16_t len;
7137 return get_number(len) and get_string(len, result);
7138 }
7139
7140 case 0xDB: // str 32
7141 {
7142 uint32_t len;
7143 return get_number(len) and get_string(len, result);
7144 }
7145
7146 default:
7147 {
7148 auto last_token = get_token_string();
7149 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token));
7150 }
7151 }
7152 }
7153
7154 /*!
7155 @param[in] len the length of the array
7156 @return whether array creation completed
7157 */
get_msgpack_array(const std::size_t len)7158 bool get_msgpack_array(const std::size_t len)
7159 {
7160 if (JSON_UNLIKELY(not sax->start_array(len)))
7161 {
7162 return false;
7163 }
7164
7165 for (std::size_t i = 0; i < len; ++i)
7166 {
7167 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7168 {
7169 return false;
7170 }
7171 }
7172
7173 return sax->end_array();
7174 }
7175
7176 /*!
7177 @param[in] len the length of the object
7178 @return whether object creation completed
7179 */
get_msgpack_object(const std::size_t len)7180 bool get_msgpack_object(const std::size_t len)
7181 {
7182 if (JSON_UNLIKELY(not sax->start_object(len)))
7183 {
7184 return false;
7185 }
7186
7187 string_t key;
7188 for (std::size_t i = 0; i < len; ++i)
7189 {
7190 get();
7191 if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7192 {
7193 return false;
7194 }
7195
7196 if (JSON_UNLIKELY(not parse_msgpack_internal()))
7197 {
7198 return false;
7199 }
7200 key.clear();
7201 }
7202
7203 return sax->end_object();
7204 }
7205
7206 /*!
7207 @brief reads a UBJSON string
7208
7209 This function is either called after reading the 'S' byte explicitly
7210 indicating a string, or in case of an object key where the 'S' byte can be
7211 left out.
7212
7213 @param[out] result created string
7214 @param[in] get_char whether a new character should be retrieved from the
7215 input (true, default) or whether the last read
7216 character should be considered instead
7217
7218 @return whether string creation completed
7219 */
get_ubjson_string(string_t & result,const bool get_char=true)7220 bool get_ubjson_string(string_t& result, const bool get_char = true)
7221 {
7222 if (get_char)
7223 {
7224 get(); // TODO: may we ignore N here?
7225 }
7226
7227 if (JSON_UNLIKELY(not unexpect_eof()))
7228 {
7229 return false;
7230 }
7231
7232 switch (current)
7233 {
7234 case 'U':
7235 {
7236 uint8_t len;
7237 return get_number(len) and get_string(len, result);
7238 }
7239
7240 case 'i':
7241 {
7242 int8_t len;
7243 return get_number(len) and get_string(len, result);
7244 }
7245
7246 case 'I':
7247 {
7248 int16_t len;
7249 return get_number(len) and get_string(len, result);
7250 }
7251
7252 case 'l':
7253 {
7254 int32_t len;
7255 return get_number(len) and get_string(len, result);
7256 }
7257
7258 case 'L':
7259 {
7260 int64_t len;
7261 return get_number(len) and get_string(len, result);
7262 }
7263
7264 default:
7265 auto last_token = get_token_string();
7266 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token));
7267 }
7268 }
7269
7270 /*!
7271 @param[out] result determined size
7272 @return whether size determination completed
7273 */
get_ubjson_size_value(std::size_t & result)7274 bool get_ubjson_size_value(std::size_t& result)
7275 {
7276 switch (get_ignore_noop())
7277 {
7278 case 'U':
7279 {
7280 uint8_t number;
7281 if (JSON_UNLIKELY(not get_number(number)))
7282 {
7283 return false;
7284 }
7285 result = static_cast<std::size_t>(number);
7286 return true;
7287 }
7288
7289 case 'i':
7290 {
7291 int8_t number;
7292 if (JSON_UNLIKELY(not get_number(number)))
7293 {
7294 return false;
7295 }
7296 result = static_cast<std::size_t>(number);
7297 return true;
7298 }
7299
7300 case 'I':
7301 {
7302 int16_t number;
7303 if (JSON_UNLIKELY(not get_number(number)))
7304 {
7305 return false;
7306 }
7307 result = static_cast<std::size_t>(number);
7308 return true;
7309 }
7310
7311 case 'l':
7312 {
7313 int32_t number;
7314 if (JSON_UNLIKELY(not get_number(number)))
7315 {
7316 return false;
7317 }
7318 result = static_cast<std::size_t>(number);
7319 return true;
7320 }
7321
7322 case 'L':
7323 {
7324 int64_t number;
7325 if (JSON_UNLIKELY(not get_number(number)))
7326 {
7327 return false;
7328 }
7329 result = static_cast<std::size_t>(number);
7330 return true;
7331 }
7332
7333 default:
7334 {
7335 auto last_token = get_token_string();
7336 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));
7337 }
7338 }
7339 }
7340
7341 /*!
7342 @brief determine the type and size for a container
7343
7344 In the optimized UBJSON format, a type and a size can be provided to allow
7345 for a more compact representation.
7346
7347 @param[out] result pair of the size and the type
7348
7349 @return whether pair creation completed
7350 */
get_ubjson_size_type(std::pair<std::size_t,int> & result)7351 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7352 {
7353 result.first = string_t::npos; // size
7354 result.second = 0; // type
7355
7356 get_ignore_noop();
7357
7358 if (current == '$')
7359 {
7360 result.second = get(); // must not ignore 'N', because 'N' maybe the type
7361 if (JSON_UNLIKELY(not unexpect_eof()))
7362 {
7363 return false;
7364 }
7365
7366 get_ignore_noop();
7367 if (JSON_UNLIKELY(current != '#'))
7368 {
7369 if (JSON_UNLIKELY(not unexpect_eof()))
7370 {
7371 return false;
7372 }
7373 auto last_token = get_token_string();
7374 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token));
7375 }
7376
7377 return get_ubjson_size_value(result.first);
7378 }
7379 else if (current == '#')
7380 {
7381 return get_ubjson_size_value(result.first);
7382 }
7383 return true;
7384 }
7385
7386 /*!
7387 @param prefix the previously read or set type prefix
7388 @return whether value creation completed
7389 */
get_ubjson_value(const int prefix)7390 bool get_ubjson_value(const int prefix)
7391 {
7392 switch (prefix)
7393 {
7394 case std::char_traits<char>::eof(): // EOF
7395 return unexpect_eof();
7396
7397 case 'T': // true
7398 return sax->boolean(true);
7399 case 'F': // false
7400 return sax->boolean(false);
7401
7402 case 'Z': // null
7403 return sax->null();
7404
7405 case 'U':
7406 {
7407 uint8_t number;
7408 return get_number(number) and sax->number_unsigned(number);
7409 }
7410
7411 case 'i':
7412 {
7413 int8_t number;
7414 return get_number(number) and sax->number_integer(number);
7415 }
7416
7417 case 'I':
7418 {
7419 int16_t number;
7420 return get_number(number) and sax->number_integer(number);
7421 }
7422
7423 case 'l':
7424 {
7425 int32_t number;
7426 return get_number(number) and sax->number_integer(number);
7427 }
7428
7429 case 'L':
7430 {
7431 int64_t number;
7432 return get_number(number) and sax->number_integer(number);
7433 }
7434
7435 case 'd':
7436 {
7437 float number;
7438 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7439 }
7440
7441 case 'D':
7442 {
7443 double number;
7444 return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7445 }
7446
7447 case 'C': // char
7448 {
7449 get();
7450 if (JSON_UNLIKELY(not unexpect_eof()))
7451 {
7452 return false;
7453 }
7454 if (JSON_UNLIKELY(current > 127))
7455 {
7456 auto last_token = get_token_string();
7457 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));
7458 }
7459 string_t s(1, static_cast<char>(current));
7460 return sax->string(s);
7461 }
7462
7463 case 'S': // string
7464 {
7465 string_t s;
7466 return get_ubjson_string(s) and sax->string(s);
7467 }
7468
7469 case '[': // array
7470 return get_ubjson_array();
7471
7472 case '{': // object
7473 return get_ubjson_object();
7474
7475 default: // anything else
7476 {
7477 auto last_token = get_token_string();
7478 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token));
7479 }
7480 }
7481 }
7482
7483 /*!
7484 @return whether array creation completed
7485 */
get_ubjson_array()7486 bool get_ubjson_array()
7487 {
7488 std::pair<std::size_t, int> size_and_type;
7489 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7490 {
7491 return false;
7492 }
7493
7494 if (size_and_type.first != string_t::npos)
7495 {
7496 if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
7497 {
7498 return false;
7499 }
7500
7501 if (size_and_type.second != 0)
7502 {
7503 if (size_and_type.second != 'N')
7504 {
7505 for (std::size_t i = 0; i < size_and_type.first; ++i)
7506 {
7507 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7508 {
7509 return false;
7510 }
7511 }
7512 }
7513 }
7514 else
7515 {
7516 for (std::size_t i = 0; i < size_and_type.first; ++i)
7517 {
7518 if (JSON_UNLIKELY(not parse_ubjson_internal()))
7519 {
7520 return false;
7521 }
7522 }
7523 }
7524 }
7525 else
7526 {
7527 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7528 {
7529 return false;
7530 }
7531
7532 while (current != ']')
7533 {
7534 if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
7535 {
7536 return false;
7537 }
7538 get_ignore_noop();
7539 }
7540 }
7541
7542 return sax->end_array();
7543 }
7544
7545 /*!
7546 @return whether object creation completed
7547 */
get_ubjson_object()7548 bool get_ubjson_object()
7549 {
7550 std::pair<std::size_t, int> size_and_type;
7551 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7552 {
7553 return false;
7554 }
7555
7556 string_t key;
7557 if (size_and_type.first != string_t::npos)
7558 {
7559 if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
7560 {
7561 return false;
7562 }
7563
7564 if (size_and_type.second != 0)
7565 {
7566 for (std::size_t i = 0; i < size_and_type.first; ++i)
7567 {
7568 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7569 {
7570 return false;
7571 }
7572 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7573 {
7574 return false;
7575 }
7576 key.clear();
7577 }
7578 }
7579 else
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 parse_ubjson_internal()))
7588 {
7589 return false;
7590 }
7591 key.clear();
7592 }
7593 }
7594 }
7595 else
7596 {
7597 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7598 {
7599 return false;
7600 }
7601
7602 while (current != '}')
7603 {
7604 if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7605 {
7606 return false;
7607 }
7608 if (JSON_UNLIKELY(not parse_ubjson_internal()))
7609 {
7610 return false;
7611 }
7612 get_ignore_noop();
7613 key.clear();
7614 }
7615 }
7616
7617 return sax->end_object();
7618 }
7619
7620 /*!
7621 @return whether the last read character is not EOF
7622 */
unexpect_eof() const7623 bool unexpect_eof() const
7624 {
7625 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
7626 {
7627 return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input"));
7628 }
7629 return true;
7630 }
7631
7632 /*!
7633 @return a string representation of the last read byte
7634 */
get_token_string() const7635 std::string get_token_string() const
7636 {
7637 char cr[3];
7638 snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
7639 return std::string{cr};
7640 }
7641
7642 private:
7643 /// input adapter
7644 input_adapter_t ia = nullptr;
7645
7646 /// the current character
7647 int current = std::char_traits<char>::eof();
7648
7649 /// the number of characters read
7650 std::size_t chars_read = 0;
7651
7652 /// whether we can assume little endianess
7653 const bool is_little_endian = little_endianess();
7654
7655 /// the SAX parser
7656 json_sax_t* sax = nullptr;
7657 };
7658 }
7659 }
7660
7661 // #include <nlohmann/detail/output/binary_writer.hpp>
7662
7663
7664 #include <algorithm> // reverse
7665 #include <array> // array
7666 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
7667 #include <cstring> // memcpy
7668 #include <limits> // numeric_limits
7669
7670 // #include <nlohmann/detail/input/binary_reader.hpp>
7671
7672 // #include <nlohmann/detail/output/output_adapters.hpp>
7673
7674
7675 namespace nlohmann
7676 {
7677 namespace detail
7678 {
7679 ///////////////////
7680 // binary writer //
7681 ///////////////////
7682
7683 /*!
7684 @brief serialization to CBOR and MessagePack values
7685 */
7686 template<typename BasicJsonType, typename CharType>
7687 class binary_writer
7688 {
7689 public:
7690 /*!
7691 @brief create a binary writer
7692
7693 @param[in] adapter output adapter to write to
7694 */
binary_writer(output_adapter_t<CharType> adapter)7695 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
7696 {
7697 assert(oa);
7698 }
7699
7700 /*!
7701 @brief[in] j JSON value to serialize
7702 */
write_cbor(const BasicJsonType & j)7703 void write_cbor(const BasicJsonType& j)
7704 {
7705 switch (j.type())
7706 {
7707 case value_t::null:
7708 {
7709 oa->write_character(static_cast<CharType>(0xF6));
7710 break;
7711 }
7712
7713 case value_t::boolean:
7714 {
7715 oa->write_character(j.m_value.boolean
7716 ? static_cast<CharType>(0xF5)
7717 : static_cast<CharType>(0xF4));
7718 break;
7719 }
7720
7721 case value_t::number_integer:
7722 {
7723 if (j.m_value.number_integer >= 0)
7724 {
7725 // CBOR does not differentiate between positive signed
7726 // integers and unsigned integers. Therefore, we used the
7727 // code from the value_t::number_unsigned case here.
7728 if (j.m_value.number_integer <= 0x17)
7729 {
7730 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7731 }
7732 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7733 {
7734 oa->write_character(static_cast<CharType>(0x18));
7735 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7736 }
7737 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
7738 {
7739 oa->write_character(static_cast<CharType>(0x19));
7740 write_number(static_cast<uint16_t>(j.m_value.number_integer));
7741 }
7742 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
7743 {
7744 oa->write_character(static_cast<CharType>(0x1A));
7745 write_number(static_cast<uint32_t>(j.m_value.number_integer));
7746 }
7747 else
7748 {
7749 oa->write_character(static_cast<CharType>(0x1B));
7750 write_number(static_cast<uint64_t>(j.m_value.number_integer));
7751 }
7752 }
7753 else
7754 {
7755 // The conversions below encode the sign in the first
7756 // byte, and the value is converted to a positive number.
7757 const auto positive_number = -1 - j.m_value.number_integer;
7758 if (j.m_value.number_integer >= -24)
7759 {
7760 write_number(static_cast<uint8_t>(0x20 + positive_number));
7761 }
7762 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
7763 {
7764 oa->write_character(static_cast<CharType>(0x38));
7765 write_number(static_cast<uint8_t>(positive_number));
7766 }
7767 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
7768 {
7769 oa->write_character(static_cast<CharType>(0x39));
7770 write_number(static_cast<uint16_t>(positive_number));
7771 }
7772 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
7773 {
7774 oa->write_character(static_cast<CharType>(0x3A));
7775 write_number(static_cast<uint32_t>(positive_number));
7776 }
7777 else
7778 {
7779 oa->write_character(static_cast<CharType>(0x3B));
7780 write_number(static_cast<uint64_t>(positive_number));
7781 }
7782 }
7783 break;
7784 }
7785
7786 case value_t::number_unsigned:
7787 {
7788 if (j.m_value.number_unsigned <= 0x17)
7789 {
7790 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7791 }
7792 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7793 {
7794 oa->write_character(static_cast<CharType>(0x18));
7795 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7796 }
7797 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7798 {
7799 oa->write_character(static_cast<CharType>(0x19));
7800 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
7801 }
7802 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7803 {
7804 oa->write_character(static_cast<CharType>(0x1A));
7805 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
7806 }
7807 else
7808 {
7809 oa->write_character(static_cast<CharType>(0x1B));
7810 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
7811 }
7812 break;
7813 }
7814
7815 case value_t::number_float:
7816 {
7817 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
7818 write_number(j.m_value.number_float);
7819 break;
7820 }
7821
7822 case value_t::string:
7823 {
7824 // step 1: write control byte and the string length
7825 const auto N = j.m_value.string->size();
7826 if (N <= 0x17)
7827 {
7828 write_number(static_cast<uint8_t>(0x60 + N));
7829 }
7830 else if (N <= (std::numeric_limits<uint8_t>::max)())
7831 {
7832 oa->write_character(static_cast<CharType>(0x78));
7833 write_number(static_cast<uint8_t>(N));
7834 }
7835 else if (N <= (std::numeric_limits<uint16_t>::max)())
7836 {
7837 oa->write_character(static_cast<CharType>(0x79));
7838 write_number(static_cast<uint16_t>(N));
7839 }
7840 else if (N <= (std::numeric_limits<uint32_t>::max)())
7841 {
7842 oa->write_character(static_cast<CharType>(0x7A));
7843 write_number(static_cast<uint32_t>(N));
7844 }
7845 // LCOV_EXCL_START
7846 else if (N <= (std::numeric_limits<uint64_t>::max)())
7847 {
7848 oa->write_character(static_cast<CharType>(0x7B));
7849 write_number(static_cast<uint64_t>(N));
7850 }
7851 // LCOV_EXCL_STOP
7852
7853 // step 2: write the string
7854 oa->write_characters(
7855 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
7856 j.m_value.string->size());
7857 break;
7858 }
7859
7860 case value_t::array:
7861 {
7862 // step 1: write control byte and the array size
7863 const auto N = j.m_value.array->size();
7864 if (N <= 0x17)
7865 {
7866 write_number(static_cast<uint8_t>(0x80 + N));
7867 }
7868 else if (N <= (std::numeric_limits<uint8_t>::max)())
7869 {
7870 oa->write_character(static_cast<CharType>(0x98));
7871 write_number(static_cast<uint8_t>(N));
7872 }
7873 else if (N <= (std::numeric_limits<uint16_t>::max)())
7874 {
7875 oa->write_character(static_cast<CharType>(0x99));
7876 write_number(static_cast<uint16_t>(N));
7877 }
7878 else if (N <= (std::numeric_limits<uint32_t>::max)())
7879 {
7880 oa->write_character(static_cast<CharType>(0x9A));
7881 write_number(static_cast<uint32_t>(N));
7882 }
7883 // LCOV_EXCL_START
7884 else if (N <= (std::numeric_limits<uint64_t>::max)())
7885 {
7886 oa->write_character(static_cast<CharType>(0x9B));
7887 write_number(static_cast<uint64_t>(N));
7888 }
7889 // LCOV_EXCL_STOP
7890
7891 // step 2: write each element
7892 for (const auto& el : *j.m_value.array)
7893 {
7894 write_cbor(el);
7895 }
7896 break;
7897 }
7898
7899 case value_t::object:
7900 {
7901 // step 1: write control byte and the object size
7902 const auto N = j.m_value.object->size();
7903 if (N <= 0x17)
7904 {
7905 write_number(static_cast<uint8_t>(0xA0 + N));
7906 }
7907 else if (N <= (std::numeric_limits<uint8_t>::max)())
7908 {
7909 oa->write_character(static_cast<CharType>(0xB8));
7910 write_number(static_cast<uint8_t>(N));
7911 }
7912 else if (N <= (std::numeric_limits<uint16_t>::max)())
7913 {
7914 oa->write_character(static_cast<CharType>(0xB9));
7915 write_number(static_cast<uint16_t>(N));
7916 }
7917 else if (N <= (std::numeric_limits<uint32_t>::max)())
7918 {
7919 oa->write_character(static_cast<CharType>(0xBA));
7920 write_number(static_cast<uint32_t>(N));
7921 }
7922 // LCOV_EXCL_START
7923 else if (N <= (std::numeric_limits<uint64_t>::max)())
7924 {
7925 oa->write_character(static_cast<CharType>(0xBB));
7926 write_number(static_cast<uint64_t>(N));
7927 }
7928 // LCOV_EXCL_STOP
7929
7930 // step 2: write each element
7931 for (const auto& el : *j.m_value.object)
7932 {
7933 write_cbor(el.first);
7934 write_cbor(el.second);
7935 }
7936 break;
7937 }
7938
7939 default:
7940 break;
7941 }
7942 }
7943
7944 /*!
7945 @brief[in] j JSON value to serialize
7946 */
write_msgpack(const BasicJsonType & j)7947 void write_msgpack(const BasicJsonType& j)
7948 {
7949 switch (j.type())
7950 {
7951 case value_t::null: // nil
7952 {
7953 oa->write_character(static_cast<CharType>(0xC0));
7954 break;
7955 }
7956
7957 case value_t::boolean: // true and false
7958 {
7959 oa->write_character(j.m_value.boolean
7960 ? static_cast<CharType>(0xC3)
7961 : static_cast<CharType>(0xC2));
7962 break;
7963 }
7964
7965 case value_t::number_integer:
7966 {
7967 if (j.m_value.number_integer >= 0)
7968 {
7969 // MessagePack does not differentiate between positive
7970 // signed integers and unsigned integers. Therefore, we used
7971 // the code from the value_t::number_unsigned case here.
7972 if (j.m_value.number_unsigned < 128)
7973 {
7974 // positive fixnum
7975 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7976 }
7977 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7978 {
7979 // uint 8
7980 oa->write_character(static_cast<CharType>(0xCC));
7981 write_number(static_cast<uint8_t>(j.m_value.number_integer));
7982 }
7983 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7984 {
7985 // uint 16
7986 oa->write_character(static_cast<CharType>(0xCD));
7987 write_number(static_cast<uint16_t>(j.m_value.number_integer));
7988 }
7989 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7990 {
7991 // uint 32
7992 oa->write_character(static_cast<CharType>(0xCE));
7993 write_number(static_cast<uint32_t>(j.m_value.number_integer));
7994 }
7995 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7996 {
7997 // uint 64
7998 oa->write_character(static_cast<CharType>(0xCF));
7999 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8000 }
8001 }
8002 else
8003 {
8004 if (j.m_value.number_integer >= -32)
8005 {
8006 // negative fixnum
8007 write_number(static_cast<int8_t>(j.m_value.number_integer));
8008 }
8009 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
8010 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8011 {
8012 // int 8
8013 oa->write_character(static_cast<CharType>(0xD0));
8014 write_number(static_cast<int8_t>(j.m_value.number_integer));
8015 }
8016 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
8017 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8018 {
8019 // int 16
8020 oa->write_character(static_cast<CharType>(0xD1));
8021 write_number(static_cast<int16_t>(j.m_value.number_integer));
8022 }
8023 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
8024 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8025 {
8026 // int 32
8027 oa->write_character(static_cast<CharType>(0xD2));
8028 write_number(static_cast<int32_t>(j.m_value.number_integer));
8029 }
8030 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
8031 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
8032 {
8033 // int 64
8034 oa->write_character(static_cast<CharType>(0xD3));
8035 write_number(static_cast<int64_t>(j.m_value.number_integer));
8036 }
8037 }
8038 break;
8039 }
8040
8041 case value_t::number_unsigned:
8042 {
8043 if (j.m_value.number_unsigned < 128)
8044 {
8045 // positive fixnum
8046 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8047 }
8048 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8049 {
8050 // uint 8
8051 oa->write_character(static_cast<CharType>(0xCC));
8052 write_number(static_cast<uint8_t>(j.m_value.number_integer));
8053 }
8054 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8055 {
8056 // uint 16
8057 oa->write_character(static_cast<CharType>(0xCD));
8058 write_number(static_cast<uint16_t>(j.m_value.number_integer));
8059 }
8060 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8061 {
8062 // uint 32
8063 oa->write_character(static_cast<CharType>(0xCE));
8064 write_number(static_cast<uint32_t>(j.m_value.number_integer));
8065 }
8066 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8067 {
8068 // uint 64
8069 oa->write_character(static_cast<CharType>(0xCF));
8070 write_number(static_cast<uint64_t>(j.m_value.number_integer));
8071 }
8072 break;
8073 }
8074
8075 case value_t::number_float:
8076 {
8077 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8078 write_number(j.m_value.number_float);
8079 break;
8080 }
8081
8082 case value_t::string:
8083 {
8084 // step 1: write control byte and the string length
8085 const auto N = j.m_value.string->size();
8086 if (N <= 31)
8087 {
8088 // fixstr
8089 write_number(static_cast<uint8_t>(0xA0 | N));
8090 }
8091 else if (N <= (std::numeric_limits<uint8_t>::max)())
8092 {
8093 // str 8
8094 oa->write_character(static_cast<CharType>(0xD9));
8095 write_number(static_cast<uint8_t>(N));
8096 }
8097 else if (N <= (std::numeric_limits<uint16_t>::max)())
8098 {
8099 // str 16
8100 oa->write_character(static_cast<CharType>(0xDA));
8101 write_number(static_cast<uint16_t>(N));
8102 }
8103 else if (N <= (std::numeric_limits<uint32_t>::max)())
8104 {
8105 // str 32
8106 oa->write_character(static_cast<CharType>(0xDB));
8107 write_number(static_cast<uint32_t>(N));
8108 }
8109
8110 // step 2: write the string
8111 oa->write_characters(
8112 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8113 j.m_value.string->size());
8114 break;
8115 }
8116
8117 case value_t::array:
8118 {
8119 // step 1: write control byte and the array size
8120 const auto N = j.m_value.array->size();
8121 if (N <= 15)
8122 {
8123 // fixarray
8124 write_number(static_cast<uint8_t>(0x90 | N));
8125 }
8126 else if (N <= (std::numeric_limits<uint16_t>::max)())
8127 {
8128 // array 16
8129 oa->write_character(static_cast<CharType>(0xDC));
8130 write_number(static_cast<uint16_t>(N));
8131 }
8132 else if (N <= (std::numeric_limits<uint32_t>::max)())
8133 {
8134 // array 32
8135 oa->write_character(static_cast<CharType>(0xDD));
8136 write_number(static_cast<uint32_t>(N));
8137 }
8138
8139 // step 2: write each element
8140 for (const auto& el : *j.m_value.array)
8141 {
8142 write_msgpack(el);
8143 }
8144 break;
8145 }
8146
8147 case value_t::object:
8148 {
8149 // step 1: write control byte and the object size
8150 const auto N = j.m_value.object->size();
8151 if (N <= 15)
8152 {
8153 // fixmap
8154 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8155 }
8156 else if (N <= (std::numeric_limits<uint16_t>::max)())
8157 {
8158 // map 16
8159 oa->write_character(static_cast<CharType>(0xDE));
8160 write_number(static_cast<uint16_t>(N));
8161 }
8162 else if (N <= (std::numeric_limits<uint32_t>::max)())
8163 {
8164 // map 32
8165 oa->write_character(static_cast<CharType>(0xDF));
8166 write_number(static_cast<uint32_t>(N));
8167 }
8168
8169 // step 2: write each element
8170 for (const auto& el : *j.m_value.object)
8171 {
8172 write_msgpack(el.first);
8173 write_msgpack(el.second);
8174 }
8175 break;
8176 }
8177
8178 default:
8179 break;
8180 }
8181 }
8182
8183 /*!
8184 @param[in] j JSON value to serialize
8185 @param[in] use_count whether to use '#' prefixes (optimized format)
8186 @param[in] use_type whether to use '$' prefixes (optimized format)
8187 @param[in] add_prefix whether prefixes need to be used for this value
8188 */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)8189 void write_ubjson(const BasicJsonType& j, const bool use_count,
8190 const bool use_type, const bool add_prefix = true)
8191 {
8192 switch (j.type())
8193 {
8194 case value_t::null:
8195 {
8196 if (add_prefix)
8197 {
8198 oa->write_character(static_cast<CharType>('Z'));
8199 }
8200 break;
8201 }
8202
8203 case value_t::boolean:
8204 {
8205 if (add_prefix)
8206 oa->write_character(j.m_value.boolean
8207 ? static_cast<CharType>('T')
8208 : static_cast<CharType>('F'));
8209 break;
8210 }
8211
8212 case value_t::number_integer:
8213 {
8214 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
8215 break;
8216 }
8217
8218 case value_t::number_unsigned:
8219 {
8220 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
8221 break;
8222 }
8223
8224 case value_t::number_float:
8225 {
8226 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
8227 break;
8228 }
8229
8230 case value_t::string:
8231 {
8232 if (add_prefix)
8233 {
8234 oa->write_character(static_cast<CharType>('S'));
8235 }
8236 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
8237 oa->write_characters(
8238 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8239 j.m_value.string->size());
8240 break;
8241 }
8242
8243 case value_t::array:
8244 {
8245 if (add_prefix)
8246 {
8247 oa->write_character(static_cast<CharType>('['));
8248 }
8249
8250 bool prefix_required = true;
8251 if (use_type and not j.m_value.array->empty())
8252 {
8253 assert(use_count);
8254 const CharType first_prefix = ubjson_prefix(j.front());
8255 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
8256 [this, first_prefix](const BasicJsonType & v)
8257 {
8258 return ubjson_prefix(v) == first_prefix;
8259 });
8260
8261 if (same_prefix)
8262 {
8263 prefix_required = false;
8264 oa->write_character(static_cast<CharType>('$'));
8265 oa->write_character(first_prefix);
8266 }
8267 }
8268
8269 if (use_count)
8270 {
8271 oa->write_character(static_cast<CharType>('#'));
8272 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
8273 }
8274
8275 for (const auto& el : *j.m_value.array)
8276 {
8277 write_ubjson(el, use_count, use_type, prefix_required);
8278 }
8279
8280 if (not use_count)
8281 {
8282 oa->write_character(static_cast<CharType>(']'));
8283 }
8284
8285 break;
8286 }
8287
8288 case value_t::object:
8289 {
8290 if (add_prefix)
8291 {
8292 oa->write_character(static_cast<CharType>('{'));
8293 }
8294
8295 bool prefix_required = true;
8296 if (use_type and not j.m_value.object->empty())
8297 {
8298 assert(use_count);
8299 const CharType first_prefix = ubjson_prefix(j.front());
8300 const bool same_prefix = std::all_of(j.begin(), j.end(),
8301 [this, first_prefix](const BasicJsonType & v)
8302 {
8303 return ubjson_prefix(v) == first_prefix;
8304 });
8305
8306 if (same_prefix)
8307 {
8308 prefix_required = false;
8309 oa->write_character(static_cast<CharType>('$'));
8310 oa->write_character(first_prefix);
8311 }
8312 }
8313
8314 if (use_count)
8315 {
8316 oa->write_character(static_cast<CharType>('#'));
8317 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
8318 }
8319
8320 for (const auto& el : *j.m_value.object)
8321 {
8322 write_number_with_ubjson_prefix(el.first.size(), true);
8323 oa->write_characters(
8324 reinterpret_cast<const CharType*>(el.first.c_str()),
8325 el.first.size());
8326 write_ubjson(el.second, use_count, use_type, prefix_required);
8327 }
8328
8329 if (not use_count)
8330 {
8331 oa->write_character(static_cast<CharType>('}'));
8332 }
8333
8334 break;
8335 }
8336
8337 default:
8338 break;
8339 }
8340 }
8341
8342 private:
8343 /*
8344 @brief write a number to output input
8345
8346 @param[in] n number of type @a NumberType
8347 @tparam NumberType the type of the number
8348
8349 @note This function needs to respect the system's endianess, because bytes
8350 in CBOR, MessagePack, and UBJSON are stored in network order (big
8351 endian) and therefore need reordering on little endian systems.
8352 */
8353 template<typename NumberType>
write_number(const NumberType n)8354 void write_number(const NumberType n)
8355 {
8356 // step 1: write number to array of length NumberType
8357 std::array<CharType, sizeof(NumberType)> vec;
8358 std::memcpy(vec.data(), &n, sizeof(NumberType));
8359
8360 // step 2: write array to output (with possible reordering)
8361 if (is_little_endian)
8362 {
8363 // reverse byte order prior to conversion if necessary
8364 std::reverse(vec.begin(), vec.end());
8365 }
8366
8367 oa->write_characters(vec.data(), sizeof(NumberType));
8368 }
8369
8370 // UBJSON: write number (floating point)
8371 template<typename NumberType, typename std::enable_if<
8372 std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8373 void write_number_with_ubjson_prefix(const NumberType n,
8374 const bool add_prefix)
8375 {
8376 if (add_prefix)
8377 {
8378 oa->write_character(get_ubjson_float_prefix(n));
8379 }
8380 write_number(n);
8381 }
8382
8383 // UBJSON: write number (unsigned integer)
8384 template<typename NumberType, typename std::enable_if<
8385 std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8386 void write_number_with_ubjson_prefix(const NumberType n,
8387 const bool add_prefix)
8388 {
8389 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
8390 {
8391 if (add_prefix)
8392 {
8393 oa->write_character(static_cast<CharType>('i')); // int8
8394 }
8395 write_number(static_cast<uint8_t>(n));
8396 }
8397 else if (n <= (std::numeric_limits<uint8_t>::max)())
8398 {
8399 if (add_prefix)
8400 {
8401 oa->write_character(static_cast<CharType>('U')); // uint8
8402 }
8403 write_number(static_cast<uint8_t>(n));
8404 }
8405 else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
8406 {
8407 if (add_prefix)
8408 {
8409 oa->write_character(static_cast<CharType>('I')); // int16
8410 }
8411 write_number(static_cast<int16_t>(n));
8412 }
8413 else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
8414 {
8415 if (add_prefix)
8416 {
8417 oa->write_character(static_cast<CharType>('l')); // int32
8418 }
8419 write_number(static_cast<int32_t>(n));
8420 }
8421 else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
8422 {
8423 if (add_prefix)
8424 {
8425 oa->write_character(static_cast<CharType>('L')); // int64
8426 }
8427 write_number(static_cast<int64_t>(n));
8428 }
8429 else
8430 {
8431 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8432 }
8433 }
8434
8435 // UBJSON: write number (signed integer)
8436 template<typename NumberType, typename std::enable_if<
8437 std::is_signed<NumberType>::value and
8438 not std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)8439 void write_number_with_ubjson_prefix(const NumberType n,
8440 const bool add_prefix)
8441 {
8442 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
8443 {
8444 if (add_prefix)
8445 {
8446 oa->write_character(static_cast<CharType>('i')); // int8
8447 }
8448 write_number(static_cast<int8_t>(n));
8449 }
8450 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)()))
8451 {
8452 if (add_prefix)
8453 {
8454 oa->write_character(static_cast<CharType>('U')); // uint8
8455 }
8456 write_number(static_cast<uint8_t>(n));
8457 }
8458 else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
8459 {
8460 if (add_prefix)
8461 {
8462 oa->write_character(static_cast<CharType>('I')); // int16
8463 }
8464 write_number(static_cast<int16_t>(n));
8465 }
8466 else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
8467 {
8468 if (add_prefix)
8469 {
8470 oa->write_character(static_cast<CharType>('l')); // int32
8471 }
8472 write_number(static_cast<int32_t>(n));
8473 }
8474 else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
8475 {
8476 if (add_prefix)
8477 {
8478 oa->write_character(static_cast<CharType>('L')); // int64
8479 }
8480 write_number(static_cast<int64_t>(n));
8481 }
8482 // LCOV_EXCL_START
8483 else
8484 {
8485 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8486 }
8487 // LCOV_EXCL_STOP
8488 }
8489
8490 /*!
8491 @brief determine the type prefix of container values
8492
8493 @note This function does not need to be 100% accurate when it comes to
8494 integer limits. In case a number exceeds the limits of int64_t,
8495 this will be detected by a later call to function
8496 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
8497 value that does not fit the previous limits.
8498 */
ubjson_prefix(const BasicJsonType & j) const8499 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
8500 {
8501 switch (j.type())
8502 {
8503 case value_t::null:
8504 return 'Z';
8505
8506 case value_t::boolean:
8507 return j.m_value.boolean ? 'T' : 'F';
8508
8509 case value_t::number_integer:
8510 {
8511 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8512 {
8513 return 'i';
8514 }
8515 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)())
8516 {
8517 return 'U';
8518 }
8519 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)())
8520 {
8521 return 'I';
8522 }
8523 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)())
8524 {
8525 return 'l';
8526 }
8527 else // no check and assume int64_t (see note above)
8528 {
8529 return 'L';
8530 }
8531 }
8532
8533 case value_t::number_unsigned:
8534 {
8535 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
8536 {
8537 return 'i';
8538 }
8539 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8540 {
8541 return 'U';
8542 }
8543 else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
8544 {
8545 return 'I';
8546 }
8547 else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
8548 {
8549 return 'l';
8550 }
8551 else // no check and assume int64_t (see note above)
8552 {
8553 return 'L';
8554 }
8555 }
8556
8557 case value_t::number_float:
8558 return get_ubjson_float_prefix(j.m_value.number_float);
8559
8560 case value_t::string:
8561 return 'S';
8562
8563 case value_t::array:
8564 return '[';
8565
8566 case value_t::object:
8567 return '{';
8568
8569 default: // discarded values
8570 return 'N';
8571 }
8572 }
8573
get_cbor_float_prefix(float)8574 static constexpr CharType get_cbor_float_prefix(float)
8575 {
8576 return static_cast<CharType>(0xFA); // Single-Precision Float
8577 }
8578
get_cbor_float_prefix(double)8579 static constexpr CharType get_cbor_float_prefix(double)
8580 {
8581 return static_cast<CharType>(0xFB); // Double-Precision Float
8582 }
8583
get_msgpack_float_prefix(float)8584 static constexpr CharType get_msgpack_float_prefix(float)
8585 {
8586 return static_cast<CharType>(0xCA); // float 32
8587 }
8588
get_msgpack_float_prefix(double)8589 static constexpr CharType get_msgpack_float_prefix(double)
8590 {
8591 return static_cast<CharType>(0xCB); // float 64
8592 }
8593
get_ubjson_float_prefix(float)8594 static constexpr CharType get_ubjson_float_prefix(float)
8595 {
8596 return 'd'; // float 32
8597 }
8598
get_ubjson_float_prefix(double)8599 static constexpr CharType get_ubjson_float_prefix(double)
8600 {
8601 return 'D'; // float 64
8602 }
8603
8604 private:
8605 /// whether we can assume little endianess
8606 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
8607
8608 /// the output
8609 output_adapter_t<CharType> oa = nullptr;
8610 };
8611 }
8612 }
8613
8614 // #include <nlohmann/detail/output/serializer.hpp>
8615
8616
8617 #include <algorithm> // reverse, remove, fill, find, none_of
8618 #include <array> // array
8619 #include <cassert> // assert
8620 #include <ciso646> // and, or
8621 #include <clocale> // localeconv, lconv
8622 #include <cmath> // labs, isfinite, isnan, signbit
8623 #include <cstddef> // size_t, ptrdiff_t
8624 #include <cstdint> // uint8_t
8625 #include <cstdio> // snprintf
8626 #include <limits> // numeric_limits
8627 #include <string> // string
8628 #include <type_traits> // is_same
8629
8630 // #include <nlohmann/detail/exceptions.hpp>
8631
8632 // #include <nlohmann/detail/conversions/to_chars.hpp>
8633
8634
8635 #include <cassert> // assert
8636 #include <ciso646> // or, and, not
8637 #include <cmath> // signbit, isfinite
8638 #include <cstdint> // intN_t, uintN_t
8639 #include <cstring> // memcpy, memmove
8640
8641 namespace nlohmann
8642 {
8643 namespace detail
8644 {
8645
8646 /*!
8647 @brief implements the Grisu2 algorithm for binary to decimal floating-point
8648 conversion.
8649
8650 This implementation is a slightly modified version of the reference
8651 implementation which may be obtained from
8652 http://florian.loitsch.com/publications (bench.tar.gz).
8653
8654 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
8655
8656 For a detailed description of the algorithm see:
8657
8658 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
8659 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
8660 Language Design and Implementation, PLDI 2010
8661 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
8662 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
8663 Design and Implementation, PLDI 1996
8664 */
8665 namespace dtoa_impl
8666 {
8667
8668 template <typename Target, typename Source>
8669 Target reinterpret_bits(const Source source)
8670 {
8671 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
8672
8673 Target target;
8674 std::memcpy(&target, &source, sizeof(Source));
8675 return target;
8676 }
8677
8678 struct diyfp // f * 2^e
8679 {
8680 static constexpr int kPrecision = 64; // = q
8681
8682 uint64_t f;
8683 int e;
8684
diyfpnlohmann::detail::dtoa_impl::diyfp8685 constexpr diyfp() noexcept : f(0), e(0) {}
diyfpnlohmann::detail::dtoa_impl::diyfp8686 constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
8687
8688 /*!
8689 @brief returns x - y
8690 @pre x.e == y.e and x.f >= y.f
8691 */
subnlohmann::detail::dtoa_impl::diyfp8692 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
8693 {
8694 assert(x.e == y.e);
8695 assert(x.f >= y.f);
8696
8697 return diyfp(x.f - y.f, x.e);
8698 }
8699
8700 /*!
8701 @brief returns x * y
8702 @note The result is rounded. (Only the upper q bits are returned.)
8703 */
mulnlohmann::detail::dtoa_impl::diyfp8704 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
8705 {
8706 static_assert(kPrecision == 64, "internal error");
8707
8708 // Computes:
8709 // f = round((x.f * y.f) / 2^q)
8710 // e = x.e + y.e + q
8711
8712 // Emulate the 64-bit * 64-bit multiplication:
8713 //
8714 // p = u * v
8715 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
8716 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
8717 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
8718 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
8719 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
8720 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
8721 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
8722 //
8723 // (Since Q might be larger than 2^32 - 1)
8724 //
8725 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
8726 //
8727 // (Q_hi + H does not overflow a 64-bit int)
8728 //
8729 // = p_lo + 2^64 p_hi
8730
8731 const uint64_t u_lo = x.f & 0xFFFFFFFF;
8732 const uint64_t u_hi = x.f >> 32;
8733 const uint64_t v_lo = y.f & 0xFFFFFFFF;
8734 const uint64_t v_hi = y.f >> 32;
8735
8736 const uint64_t p0 = u_lo * v_lo;
8737 const uint64_t p1 = u_lo * v_hi;
8738 const uint64_t p2 = u_hi * v_lo;
8739 const uint64_t p3 = u_hi * v_hi;
8740
8741 const uint64_t p0_hi = p0 >> 32;
8742 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
8743 const uint64_t p1_hi = p1 >> 32;
8744 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
8745 const uint64_t p2_hi = p2 >> 32;
8746
8747 uint64_t Q = p0_hi + p1_lo + p2_lo;
8748
8749 // The full product might now be computed as
8750 //
8751 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
8752 // p_lo = p0_lo + (Q << 32)
8753 //
8754 // But in this particular case here, the full p_lo is not required.
8755 // Effectively we only need to add the highest bit in p_lo to p_hi (and
8756 // Q_hi + 1 does not overflow).
8757
8758 Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
8759
8760 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
8761
8762 return diyfp(h, x.e + y.e + 64);
8763 }
8764
8765 /*!
8766 @brief normalize x such that the significand is >= 2^(q-1)
8767 @pre x.f != 0
8768 */
normalizenlohmann::detail::dtoa_impl::diyfp8769 static diyfp normalize(diyfp x) noexcept
8770 {
8771 assert(x.f != 0);
8772
8773 while ((x.f >> 63) == 0)
8774 {
8775 x.f <<= 1;
8776 x.e--;
8777 }
8778
8779 return x;
8780 }
8781
8782 /*!
8783 @brief normalize x such that the result has the exponent E
8784 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
8785 */
normalize_tonlohmann::detail::dtoa_impl::diyfp8786 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
8787 {
8788 const int delta = x.e - target_exponent;
8789
8790 assert(delta >= 0);
8791 assert(((x.f << delta) >> delta) == x.f);
8792
8793 return diyfp(x.f << delta, target_exponent);
8794 }
8795 };
8796
8797 struct boundaries
8798 {
8799 diyfp w;
8800 diyfp minus;
8801 diyfp plus;
8802 };
8803
8804 /*!
8805 Compute the (normalized) diyfp representing the input number 'value' and its
8806 boundaries.
8807
8808 @pre value must be finite and positive
8809 */
8810 template <typename FloatType>
compute_boundaries(FloatType value)8811 boundaries compute_boundaries(FloatType value)
8812 {
8813 assert(std::isfinite(value));
8814 assert(value > 0);
8815
8816 // Convert the IEEE representation into a diyfp.
8817 //
8818 // If v is denormal:
8819 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
8820 // If v is normalized:
8821 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
8822
8823 static_assert(std::numeric_limits<FloatType>::is_iec559,
8824 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
8825
8826 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
8827 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
8828 constexpr int kMinExp = 1 - kBias;
8829 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
8830
8831 using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
8832
8833 const uint64_t bits = reinterpret_bits<bits_type>(value);
8834 const uint64_t E = bits >> (kPrecision - 1);
8835 const uint64_t F = bits & (kHiddenBit - 1);
8836
8837 const bool is_denormal = (E == 0);
8838 const diyfp v = is_denormal
8839 ? diyfp(F, kMinExp)
8840 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
8841
8842 // Compute the boundaries m- and m+ of the floating-point value
8843 // v = f * 2^e.
8844 //
8845 // Determine v- and v+, the floating-point predecessor and successor if v,
8846 // respectively.
8847 //
8848 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
8849 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
8850 //
8851 // v+ = v + 2^e
8852 //
8853 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
8854 // between m- and m+ round to v, regardless of how the input rounding
8855 // algorithm breaks ties.
8856 //
8857 // ---+-------------+-------------+-------------+-------------+--- (A)
8858 // v- m- v m+ v+
8859 //
8860 // -----------------+------+------+-------------+-------------+--- (B)
8861 // v- m- v m+ v+
8862
8863 const bool lower_boundary_is_closer = (F == 0 and E > 1);
8864 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
8865 const diyfp m_minus = lower_boundary_is_closer
8866 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
8867 : diyfp(2 * v.f - 1, v.e - 1); // (A)
8868
8869 // Determine the normalized w+ = m+.
8870 const diyfp w_plus = diyfp::normalize(m_plus);
8871
8872 // Determine w- = m- such that e_(w-) = e_(w+).
8873 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
8874
8875 return {diyfp::normalize(v), w_minus, w_plus};
8876 }
8877
8878 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
8879 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
8880 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
8881 //
8882 // alpha <= e = e_c + e_w + q <= gamma
8883 //
8884 // or
8885 //
8886 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
8887 // <= f_c * f_w * 2^gamma
8888 //
8889 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
8890 //
8891 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
8892 //
8893 // or
8894 //
8895 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
8896 //
8897 // The choice of (alpha,gamma) determines the size of the table and the form of
8898 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
8899 // in practice:
8900 //
8901 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
8902 // processed independently: An integral part p1, and a fractional part p2:
8903 //
8904 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
8905 // = (f div 2^-e) + (f mod 2^-e) * 2^e
8906 // = p1 + p2 * 2^e
8907 //
8908 // The conversion of p1 into decimal form requires a series of divisions and
8909 // modulos by (a power of) 10. These operations are faster for 32-bit than for
8910 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
8911 // achieved by choosing
8912 //
8913 // -e >= 32 or e <= -32 := gamma
8914 //
8915 // In order to convert the fractional part
8916 //
8917 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
8918 //
8919 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
8920 // d[-i] are extracted in order:
8921 //
8922 // (10 * p2) div 2^-e = d[-1]
8923 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
8924 //
8925 // The multiplication by 10 must not overflow. It is sufficient to choose
8926 //
8927 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
8928 //
8929 // Since p2 = f mod 2^-e < 2^-e,
8930 //
8931 // -e <= 60 or e >= -60 := alpha
8932
8933 constexpr int kAlpha = -60;
8934 constexpr int kGamma = -32;
8935
8936 struct cached_power // c = f * 2^e ~= 10^k
8937 {
8938 uint64_t f;
8939 int e;
8940 int k;
8941 };
8942
8943 /*!
8944 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
8945 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
8946 satisfies (Definition 3.2 from [1])
8947
8948 alpha <= e_c + e + q <= gamma.
8949 */
get_cached_power_for_binary_exponent(int e)8950 inline cached_power get_cached_power_for_binary_exponent(int e)
8951 {
8952 // Now
8953 //
8954 // alpha <= e_c + e + q <= gamma (1)
8955 // ==> f_c * 2^alpha <= c * 2^e * 2^q
8956 //
8957 // and since the c's are normalized, 2^(q-1) <= f_c,
8958 //
8959 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
8960 // ==> 2^(alpha - e - 1) <= c
8961 //
8962 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
8963 //
8964 // k = ceil( log_10( 2^(alpha - e - 1) ) )
8965 // = ceil( (alpha - e - 1) * log_10(2) )
8966 //
8967 // From the paper:
8968 // "In theory the result of the procedure could be wrong since c is rounded,
8969 // and the computation itself is approximated [...]. In practice, however,
8970 // this simple function is sufficient."
8971 //
8972 // For IEEE double precision floating-point numbers converted into
8973 // normalized diyfp's w = f * 2^e, with q = 64,
8974 //
8975 // e >= -1022 (min IEEE exponent)
8976 // -52 (p - 1)
8977 // -52 (p - 1, possibly normalize denormal IEEE numbers)
8978 // -11 (normalize the diyfp)
8979 // = -1137
8980 //
8981 // and
8982 //
8983 // e <= +1023 (max IEEE exponent)
8984 // -52 (p - 1)
8985 // -11 (normalize the diyfp)
8986 // = 960
8987 //
8988 // This binary exponent range [-1137,960] results in a decimal exponent
8989 // range [-307,324]. One does not need to store a cached power for each
8990 // k in this range. For each such k it suffices to find a cached power
8991 // such that the exponent of the product lies in [alpha,gamma].
8992 // This implies that the difference of the decimal exponents of adjacent
8993 // table entries must be less than or equal to
8994 //
8995 // floor( (gamma - alpha) * log_10(2) ) = 8.
8996 //
8997 // (A smaller distance gamma-alpha would require a larger table.)
8998
8999 // NB:
9000 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
9001
9002 constexpr int kCachedPowersSize = 79;
9003 constexpr int kCachedPowersMinDecExp = -300;
9004 constexpr int kCachedPowersDecStep = 8;
9005
9006 static constexpr cached_power kCachedPowers[] =
9007 {
9008 { 0xAB70FE17C79AC6CA, -1060, -300 },
9009 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
9010 { 0xBE5691EF416BD60C, -1007, -284 },
9011 { 0x8DD01FAD907FFC3C, -980, -276 },
9012 { 0xD3515C2831559A83, -954, -268 },
9013 { 0x9D71AC8FADA6C9B5, -927, -260 },
9014 { 0xEA9C227723EE8BCB, -901, -252 },
9015 { 0xAECC49914078536D, -874, -244 },
9016 { 0x823C12795DB6CE57, -847, -236 },
9017 { 0xC21094364DFB5637, -821, -228 },
9018 { 0x9096EA6F3848984F, -794, -220 },
9019 { 0xD77485CB25823AC7, -768, -212 },
9020 { 0xA086CFCD97BF97F4, -741, -204 },
9021 { 0xEF340A98172AACE5, -715, -196 },
9022 { 0xB23867FB2A35B28E, -688, -188 },
9023 { 0x84C8D4DFD2C63F3B, -661, -180 },
9024 { 0xC5DD44271AD3CDBA, -635, -172 },
9025 { 0x936B9FCEBB25C996, -608, -164 },
9026 { 0xDBAC6C247D62A584, -582, -156 },
9027 { 0xA3AB66580D5FDAF6, -555, -148 },
9028 { 0xF3E2F893DEC3F126, -529, -140 },
9029 { 0xB5B5ADA8AAFF80B8, -502, -132 },
9030 { 0x87625F056C7C4A8B, -475, -124 },
9031 { 0xC9BCFF6034C13053, -449, -116 },
9032 { 0x964E858C91BA2655, -422, -108 },
9033 { 0xDFF9772470297EBD, -396, -100 },
9034 { 0xA6DFBD9FB8E5B88F, -369, -92 },
9035 { 0xF8A95FCF88747D94, -343, -84 },
9036 { 0xB94470938FA89BCF, -316, -76 },
9037 { 0x8A08F0F8BF0F156B, -289, -68 },
9038 { 0xCDB02555653131B6, -263, -60 },
9039 { 0x993FE2C6D07B7FAC, -236, -52 },
9040 { 0xE45C10C42A2B3B06, -210, -44 },
9041 { 0xAA242499697392D3, -183, -36 },
9042 { 0xFD87B5F28300CA0E, -157, -28 },
9043 { 0xBCE5086492111AEB, -130, -20 },
9044 { 0x8CBCCC096F5088CC, -103, -12 },
9045 { 0xD1B71758E219652C, -77, -4 },
9046 { 0x9C40000000000000, -50, 4 },
9047 { 0xE8D4A51000000000, -24, 12 },
9048 { 0xAD78EBC5AC620000, 3, 20 },
9049 { 0x813F3978F8940984, 30, 28 },
9050 { 0xC097CE7BC90715B3, 56, 36 },
9051 { 0x8F7E32CE7BEA5C70, 83, 44 },
9052 { 0xD5D238A4ABE98068, 109, 52 },
9053 { 0x9F4F2726179A2245, 136, 60 },
9054 { 0xED63A231D4C4FB27, 162, 68 },
9055 { 0xB0DE65388CC8ADA8, 189, 76 },
9056 { 0x83C7088E1AAB65DB, 216, 84 },
9057 { 0xC45D1DF942711D9A, 242, 92 },
9058 { 0x924D692CA61BE758, 269, 100 },
9059 { 0xDA01EE641A708DEA, 295, 108 },
9060 { 0xA26DA3999AEF774A, 322, 116 },
9061 { 0xF209787BB47D6B85, 348, 124 },
9062 { 0xB454E4A179DD1877, 375, 132 },
9063 { 0x865B86925B9BC5C2, 402, 140 },
9064 { 0xC83553C5C8965D3D, 428, 148 },
9065 { 0x952AB45CFA97A0B3, 455, 156 },
9066 { 0xDE469FBD99A05FE3, 481, 164 },
9067 { 0xA59BC234DB398C25, 508, 172 },
9068 { 0xF6C69A72A3989F5C, 534, 180 },
9069 { 0xB7DCBF5354E9BECE, 561, 188 },
9070 { 0x88FCF317F22241E2, 588, 196 },
9071 { 0xCC20CE9BD35C78A5, 614, 204 },
9072 { 0x98165AF37B2153DF, 641, 212 },
9073 { 0xE2A0B5DC971F303A, 667, 220 },
9074 { 0xA8D9D1535CE3B396, 694, 228 },
9075 { 0xFB9B7CD9A4A7443C, 720, 236 },
9076 { 0xBB764C4CA7A44410, 747, 244 },
9077 { 0x8BAB8EEFB6409C1A, 774, 252 },
9078 { 0xD01FEF10A657842C, 800, 260 },
9079 { 0x9B10A4E5E9913129, 827, 268 },
9080 { 0xE7109BFBA19C0C9D, 853, 276 },
9081 { 0xAC2820D9623BF429, 880, 284 },
9082 { 0x80444B5E7AA7CF85, 907, 292 },
9083 { 0xBF21E44003ACDD2D, 933, 300 },
9084 { 0x8E679C2F5E44FF8F, 960, 308 },
9085 { 0xD433179D9C8CB841, 986, 316 },
9086 { 0x9E19DB92B4E31BA9, 1013, 324 },
9087 };
9088
9089 // This computation gives exactly the same results for k as
9090 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
9091 // for |e| <= 1500, but doesn't require floating-point operations.
9092 // NB: log_10(2) ~= 78913 / 2^18
9093 assert(e >= -1500);
9094 assert(e <= 1500);
9095 const int f = kAlpha - e - 1;
9096 const int k = (f * 78913) / (1 << 18) + (f > 0);
9097
9098 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
9099 assert(index >= 0);
9100 assert(index < kCachedPowersSize);
9101 static_cast<void>(kCachedPowersSize); // Fix warning.
9102
9103 const cached_power cached = kCachedPowers[index];
9104 assert(kAlpha <= cached.e + e + 64);
9105 assert(kGamma >= cached.e + e + 64);
9106
9107 return cached;
9108 }
9109
9110 /*!
9111 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
9112 For n == 0, returns 1 and sets pow10 := 1.
9113 */
find_largest_pow10(const uint32_t n,uint32_t & pow10)9114 inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
9115 {
9116 // LCOV_EXCL_START
9117 if (n >= 1000000000)
9118 {
9119 pow10 = 1000000000;
9120 return 10;
9121 }
9122 // LCOV_EXCL_STOP
9123 else if (n >= 100000000)
9124 {
9125 pow10 = 100000000;
9126 return 9;
9127 }
9128 else if (n >= 10000000)
9129 {
9130 pow10 = 10000000;
9131 return 8;
9132 }
9133 else if (n >= 1000000)
9134 {
9135 pow10 = 1000000;
9136 return 7;
9137 }
9138 else if (n >= 100000)
9139 {
9140 pow10 = 100000;
9141 return 6;
9142 }
9143 else if (n >= 10000)
9144 {
9145 pow10 = 10000;
9146 return 5;
9147 }
9148 else if (n >= 1000)
9149 {
9150 pow10 = 1000;
9151 return 4;
9152 }
9153 else if (n >= 100)
9154 {
9155 pow10 = 100;
9156 return 3;
9157 }
9158 else if (n >= 10)
9159 {
9160 pow10 = 10;
9161 return 2;
9162 }
9163 else
9164 {
9165 pow10 = 1;
9166 return 1;
9167 }
9168 }
9169
grisu2_round(char * buf,int len,uint64_t dist,uint64_t delta,uint64_t rest,uint64_t ten_k)9170 inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
9171 uint64_t rest, uint64_t ten_k)
9172 {
9173 assert(len >= 1);
9174 assert(dist <= delta);
9175 assert(rest <= delta);
9176 assert(ten_k > 0);
9177
9178 // <--------------------------- delta ---->
9179 // <---- dist --------->
9180 // --------------[------------------+-------------------]--------------
9181 // M- w M+
9182 //
9183 // ten_k
9184 // <------>
9185 // <---- rest ---->
9186 // --------------[------------------+----+--------------]--------------
9187 // w V
9188 // = buf * 10^k
9189 //
9190 // ten_k represents a unit-in-the-last-place in the decimal representation
9191 // stored in buf.
9192 // Decrement buf by ten_k while this takes buf closer to w.
9193
9194 // The tests are written in this order to avoid overflow in unsigned
9195 // integer arithmetic.
9196
9197 while (rest < dist
9198 and delta - rest >= ten_k
9199 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
9200 {
9201 assert(buf[len - 1] != '0');
9202 buf[len - 1]--;
9203 rest += ten_k;
9204 }
9205 }
9206
9207 /*!
9208 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
9209 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
9210 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)9211 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
9212 diyfp M_minus, diyfp w, diyfp M_plus)
9213 {
9214 static_assert(kAlpha >= -60, "internal error");
9215 static_assert(kGamma <= -32, "internal error");
9216
9217 // Generates the digits (and the exponent) of a decimal floating-point
9218 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
9219 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
9220 //
9221 // <--------------------------- delta ---->
9222 // <---- dist --------->
9223 // --------------[------------------+-------------------]--------------
9224 // M- w M+
9225 //
9226 // Grisu2 generates the digits of M+ from left to right and stops as soon as
9227 // V is in [M-,M+].
9228
9229 assert(M_plus.e >= kAlpha);
9230 assert(M_plus.e <= kGamma);
9231
9232 uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
9233 uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
9234
9235 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
9236 //
9237 // M+ = f * 2^e
9238 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
9239 // = ((p1 ) * 2^-e + (p2 )) * 2^e
9240 // = p1 + p2 * 2^e
9241
9242 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
9243
9244 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.)
9245 uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
9246
9247 // 1)
9248 //
9249 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
9250
9251 assert(p1 > 0);
9252
9253 uint32_t pow10;
9254 const int k = find_largest_pow10(p1, pow10);
9255
9256 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
9257 //
9258 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
9259 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
9260 //
9261 // M+ = p1 + p2 * 2^e
9262 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
9263 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
9264 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
9265 //
9266 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
9267 //
9268 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
9269 //
9270 // but stop as soon as
9271 //
9272 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
9273
9274 int n = k;
9275 while (n > 0)
9276 {
9277 // Invariants:
9278 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
9279 // pow10 = 10^(n-1) <= p1 < 10^n
9280 //
9281 const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
9282 const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
9283 //
9284 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
9285 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
9286 //
9287 assert(d <= 9);
9288 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9289 //
9290 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
9291 //
9292 p1 = r;
9293 n--;
9294 //
9295 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
9296 // pow10 = 10^n
9297 //
9298
9299 // Now check if enough digits have been generated.
9300 // Compute
9301 //
9302 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
9303 //
9304 // Note:
9305 // Since rest and delta share the same exponent e, it suffices to
9306 // compare the significands.
9307 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
9308 if (rest <= delta)
9309 {
9310 // V = buffer * 10^n, with M- <= V <= M+.
9311
9312 decimal_exponent += n;
9313
9314 // We may now just stop. But instead look if the buffer could be
9315 // decremented to bring V closer to w.
9316 //
9317 // pow10 = 10^n is now 1 ulp in the decimal representation V.
9318 // The rounding procedure works with diyfp's with an implicit
9319 // exponent of e.
9320 //
9321 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
9322 //
9323 const uint64_t ten_n = uint64_t{pow10} << -one.e;
9324 grisu2_round(buffer, length, dist, delta, rest, ten_n);
9325
9326 return;
9327 }
9328
9329 pow10 /= 10;
9330 //
9331 // pow10 = 10^(n-1) <= p1 < 10^n
9332 // Invariants restored.
9333 }
9334
9335 // 2)
9336 //
9337 // The digits of the integral part have been generated:
9338 //
9339 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
9340 // = buffer + p2 * 2^e
9341 //
9342 // Now generate the digits of the fractional part p2 * 2^e.
9343 //
9344 // Note:
9345 // No decimal point is generated: the exponent is adjusted instead.
9346 //
9347 // p2 actually represents the fraction
9348 //
9349 // p2 * 2^e
9350 // = p2 / 2^-e
9351 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
9352 //
9353 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
9354 //
9355 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
9356 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
9357 //
9358 // using
9359 //
9360 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
9361 // = ( d) * 2^-e + ( r)
9362 //
9363 // or
9364 // 10^m * p2 * 2^e = d + r * 2^e
9365 //
9366 // i.e.
9367 //
9368 // M+ = buffer + p2 * 2^e
9369 // = buffer + 10^-m * (d + r * 2^e)
9370 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
9371 //
9372 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
9373
9374 assert(p2 > delta);
9375
9376 int m = 0;
9377 for (;;)
9378 {
9379 // Invariant:
9380 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
9381 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
9382 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
9383 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
9384 //
9385 assert(p2 <= UINT64_MAX / 10);
9386 p2 *= 10;
9387 const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
9388 const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
9389 //
9390 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
9391 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
9392 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
9393 //
9394 assert(d <= 9);
9395 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9396 //
9397 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
9398 //
9399 p2 = r;
9400 m++;
9401 //
9402 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
9403 // Invariant restored.
9404
9405 // Check if enough digits have been generated.
9406 //
9407 // 10^-m * p2 * 2^e <= delta * 2^e
9408 // p2 * 2^e <= 10^m * delta * 2^e
9409 // p2 <= 10^m * delta
9410 delta *= 10;
9411 dist *= 10;
9412 if (p2 <= delta)
9413 {
9414 break;
9415 }
9416 }
9417
9418 // V = buffer * 10^-m, with M- <= V <= M+.
9419
9420 decimal_exponent -= m;
9421
9422 // 1 ulp in the decimal representation is now 10^-m.
9423 // Since delta and dist are now scaled by 10^m, we need to do the
9424 // same with ulp in order to keep the units in sync.
9425 //
9426 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
9427 //
9428 const uint64_t ten_m = one.f;
9429 grisu2_round(buffer, length, dist, delta, p2, ten_m);
9430
9431 // By construction this algorithm generates the shortest possible decimal
9432 // number (Loitsch, Theorem 6.2) which rounds back to w.
9433 // For an input number of precision p, at least
9434 //
9435 // N = 1 + ceil(p * log_10(2))
9436 //
9437 // decimal digits are sufficient to identify all binary floating-point
9438 // numbers (Matula, "In-and-Out conversions").
9439 // This implies that the algorithm does not produce more than N decimal
9440 // digits.
9441 //
9442 // N = 17 for p = 53 (IEEE double precision)
9443 // N = 9 for p = 24 (IEEE single precision)
9444 }
9445
9446 /*!
9447 v = buf * 10^decimal_exponent
9448 len is the length of the buffer (number of decimal digits)
9449 The buffer must be large enough, i.e. >= max_digits10.
9450 */
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)9451 inline void grisu2(char* buf, int& len, int& decimal_exponent,
9452 diyfp m_minus, diyfp v, diyfp m_plus)
9453 {
9454 assert(m_plus.e == m_minus.e);
9455 assert(m_plus.e == v.e);
9456
9457 // --------(-----------------------+-----------------------)-------- (A)
9458 // m- v m+
9459 //
9460 // --------------------(-----------+-----------------------)-------- (B)
9461 // m- v m+
9462 //
9463 // First scale v (and m- and m+) such that the exponent is in the range
9464 // [alpha, gamma].
9465
9466 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
9467
9468 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
9469
9470 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
9471 const diyfp w = diyfp::mul(v, c_minus_k);
9472 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
9473 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
9474
9475 // ----(---+---)---------------(---+---)---------------(---+---)----
9476 // w- w w+
9477 // = c*m- = c*v = c*m+
9478 //
9479 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
9480 // w+ are now off by a small amount.
9481 // In fact:
9482 //
9483 // w - v * 10^k < 1 ulp
9484 //
9485 // To account for this inaccuracy, add resp. subtract 1 ulp.
9486 //
9487 // --------+---[---------------(---+---)---------------]---+--------
9488 // w- M- w M+ w+
9489 //
9490 // Now any number in [M-, M+] (bounds included) will round to w when input,
9491 // regardless of how the input rounding algorithm breaks ties.
9492 //
9493 // And digit_gen generates the shortest possible such number in [M-, M+].
9494 // Note that this does not mean that Grisu2 always generates the shortest
9495 // possible number in the interval (m-, m+).
9496 const diyfp M_minus(w_minus.f + 1, w_minus.e);
9497 const diyfp M_plus (w_plus.f - 1, w_plus.e );
9498
9499 decimal_exponent = -cached.k; // = -(-k) = k
9500
9501 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
9502 }
9503
9504 /*!
9505 v = buf * 10^decimal_exponent
9506 len is the length of the buffer (number of decimal digits)
9507 The buffer must be large enough, i.e. >= max_digits10.
9508 */
9509 template <typename FloatType>
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)9510 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
9511 {
9512 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
9513 "internal error: not enough precision");
9514
9515 assert(std::isfinite(value));
9516 assert(value > 0);
9517
9518 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
9519 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
9520 // decimal representations are not exactly "short".
9521 //
9522 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
9523 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
9524 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
9525 // does.
9526 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
9527 // representation using the corresponding std::from_chars function recovers value exactly". That
9528 // indicates that single precision floating-point numbers should be recovered using
9529 // 'std::strtof'.
9530 //
9531 // NB: If the neighbors are computed for single-precision numbers, there is a single float
9532 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
9533 // value is off by 1 ulp.
9534 #if 0
9535 const boundaries w = compute_boundaries(static_cast<double>(value));
9536 #else
9537 const boundaries w = compute_boundaries(value);
9538 #endif
9539
9540 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
9541 }
9542
9543 /*!
9544 @brief appends a decimal representation of e to buf
9545 @return a pointer to the element following the exponent.
9546 @pre -1000 < e < 1000
9547 */
append_exponent(char * buf,int e)9548 inline char* append_exponent(char* buf, int e)
9549 {
9550 assert(e > -1000);
9551 assert(e < 1000);
9552
9553 if (e < 0)
9554 {
9555 e = -e;
9556 *buf++ = '-';
9557 }
9558 else
9559 {
9560 *buf++ = '+';
9561 }
9562
9563 uint32_t k = static_cast<uint32_t>(e);
9564 if (k < 10)
9565 {
9566 // Always print at least two digits in the exponent.
9567 // This is for compatibility with printf("%g").
9568 *buf++ = '0';
9569 *buf++ = static_cast<char>('0' + k);
9570 }
9571 else if (k < 100)
9572 {
9573 *buf++ = static_cast<char>('0' + k / 10);
9574 k %= 10;
9575 *buf++ = static_cast<char>('0' + k);
9576 }
9577 else
9578 {
9579 *buf++ = static_cast<char>('0' + k / 100);
9580 k %= 100;
9581 *buf++ = static_cast<char>('0' + k / 10);
9582 k %= 10;
9583 *buf++ = static_cast<char>('0' + k);
9584 }
9585
9586 return buf;
9587 }
9588
9589 /*!
9590 @brief prettify v = buf * 10^decimal_exponent
9591
9592 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
9593 notation. Otherwise it will be printed in exponential notation.
9594
9595 @pre min_exp < 0
9596 @pre max_exp > 0
9597 */
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)9598 inline char* format_buffer(char* buf, int len, int decimal_exponent,
9599 int min_exp, int max_exp)
9600 {
9601 assert(min_exp < 0);
9602 assert(max_exp > 0);
9603
9604 const int k = len;
9605 const int n = len + decimal_exponent;
9606
9607 // v = buf * 10^(n-k)
9608 // k is the length of the buffer (number of decimal digits)
9609 // n is the position of the decimal point relative to the start of the buffer.
9610
9611 if (k <= n and n <= max_exp)
9612 {
9613 // digits[000]
9614 // len <= max_exp + 2
9615
9616 std::memset(buf + k, '0', static_cast<size_t>(n - k));
9617 // Make it look like a floating-point number (#362, #378)
9618 buf[n + 0] = '.';
9619 buf[n + 1] = '0';
9620 return buf + (n + 2);
9621 }
9622
9623 if (0 < n and n <= max_exp)
9624 {
9625 // dig.its
9626 // len <= max_digits10 + 1
9627
9628 assert(k > n);
9629
9630 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
9631 buf[n] = '.';
9632 return buf + (k + 1);
9633 }
9634
9635 if (min_exp < n and n <= 0)
9636 {
9637 // 0.[000]digits
9638 // len <= 2 + (-min_exp - 1) + max_digits10
9639
9640 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
9641 buf[0] = '0';
9642 buf[1] = '.';
9643 std::memset(buf + 2, '0', static_cast<size_t>(-n));
9644 return buf + (2 + (-n) + k);
9645 }
9646
9647 if (k == 1)
9648 {
9649 // dE+123
9650 // len <= 1 + 5
9651
9652 buf += 1;
9653 }
9654 else
9655 {
9656 // d.igitsE+123
9657 // len <= max_digits10 + 1 + 5
9658
9659 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
9660 buf[1] = '.';
9661 buf += 1 + k;
9662 }
9663
9664 *buf++ = 'e';
9665 return append_exponent(buf, n - 1);
9666 }
9667
9668 } // namespace dtoa_impl
9669
9670 /*!
9671 @brief generates a decimal representation of the floating-point number value in [first, last).
9672
9673 The format of the resulting decimal representation is similar to printf's %g
9674 format. Returns an iterator pointing past-the-end of the decimal representation.
9675
9676 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
9677 @note The buffer must be large enough.
9678 @note The result is NOT null-terminated.
9679 */
9680 template <typename FloatType>
to_chars(char * first,char * last,FloatType value)9681 char* to_chars(char* first, char* last, FloatType value)
9682 {
9683 static_cast<void>(last); // maybe unused - fix warning
9684 assert(std::isfinite(value));
9685
9686 // Use signbit(value) instead of (value < 0) since signbit works for -0.
9687 if (std::signbit(value))
9688 {
9689 value = -value;
9690 *first++ = '-';
9691 }
9692
9693 if (value == 0) // +-0
9694 {
9695 *first++ = '0';
9696 // Make it look like a floating-point number (#362, #378)
9697 *first++ = '.';
9698 *first++ = '0';
9699 return first;
9700 }
9701
9702 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
9703
9704 // Compute v = buffer * 10^decimal_exponent.
9705 // The decimal digits are stored in the buffer, which needs to be interpreted
9706 // as an unsigned decimal integer.
9707 // len is the length of the buffer, i.e. the number of decimal digits.
9708 int len = 0;
9709 int decimal_exponent = 0;
9710 dtoa_impl::grisu2(first, len, decimal_exponent, value);
9711
9712 assert(len <= std::numeric_limits<FloatType>::max_digits10);
9713
9714 // Format the buffer like printf("%.*g", prec, value)
9715 constexpr int kMinExp = -4;
9716 // Use digits10 here to increase compatibility with version 2.
9717 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
9718
9719 assert(last - first >= kMaxExp + 2);
9720 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
9721 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
9722
9723 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
9724 }
9725
9726 } // namespace detail
9727 } // namespace nlohmann
9728
9729 // #include <nlohmann/detail/macro_scope.hpp>
9730
9731 // #include <nlohmann/detail/meta/cpp_future.hpp>
9732
9733 // #include <nlohmann/detail/output/output_adapters.hpp>
9734
9735 // #include <nlohmann/detail/value_t.hpp>
9736
9737
9738 namespace nlohmann
9739 {
9740 namespace detail
9741 {
9742 ///////////////////
9743 // serialization //
9744 ///////////////////
9745
9746 template<typename BasicJsonType>
9747 class serializer
9748 {
9749 using string_t = typename BasicJsonType::string_t;
9750 using number_float_t = typename BasicJsonType::number_float_t;
9751 using number_integer_t = typename BasicJsonType::number_integer_t;
9752 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9753 static constexpr uint8_t UTF8_ACCEPT = 0;
9754 static constexpr uint8_t UTF8_REJECT = 1;
9755
9756 public:
9757 /*!
9758 @param[in] s output stream to serialize to
9759 @param[in] ichar indentation character to use
9760 */
serializer(output_adapter_t<char> s,const char ichar)9761 serializer(output_adapter_t<char> s, const char ichar)
9762 : o(std::move(s)), loc(std::localeconv()),
9763 thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep)),
9764 decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point)),
9765 indent_char(ichar), indent_string(512, indent_char)
9766 {}
9767
9768 // delete because of pointer members
9769 serializer(const serializer&) = delete;
9770 serializer& operator=(const serializer&) = delete;
9771
9772 /*!
9773 @brief internal implementation of the serialization function
9774
9775 This function is called by the public member function dump and organizes
9776 the serialization internally. The indentation level is propagated as
9777 additional parameter. In case of arrays and objects, the function is
9778 called recursively.
9779
9780 - strings and object keys are escaped using `escape_string()`
9781 - integer numbers are converted implicitly via `operator<<`
9782 - floating-point numbers are converted to a string using `"%g"` format
9783
9784 @param[in] val value to serialize
9785 @param[in] pretty_print whether the output shall be pretty-printed
9786 @param[in] indent_step the indent level
9787 @param[in] current_indent the current indent level (only used internally)
9788 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)9789 void dump(const BasicJsonType& val, const bool pretty_print,
9790 const bool ensure_ascii,
9791 const unsigned int indent_step,
9792 const unsigned int current_indent = 0)
9793 {
9794 switch (val.m_type)
9795 {
9796 case value_t::object:
9797 {
9798 if (val.m_value.object->empty())
9799 {
9800 o->write_characters("{}", 2);
9801 return;
9802 }
9803
9804 if (pretty_print)
9805 {
9806 o->write_characters("{\n", 2);
9807
9808 // variable to hold indentation for recursive calls
9809 const auto new_indent = current_indent + indent_step;
9810 if (JSON_UNLIKELY(indent_string.size() < new_indent))
9811 {
9812 indent_string.resize(indent_string.size() * 2, ' ');
9813 }
9814
9815 // first n-1 elements
9816 auto i = val.m_value.object->cbegin();
9817 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9818 {
9819 o->write_characters(indent_string.c_str(), new_indent);
9820 o->write_character('\"');
9821 dump_escaped(i->first, ensure_ascii);
9822 o->write_characters("\": ", 3);
9823 dump(i->second, true, ensure_ascii, indent_step, new_indent);
9824 o->write_characters(",\n", 2);
9825 }
9826
9827 // last element
9828 assert(i != val.m_value.object->cend());
9829 assert(std::next(i) == val.m_value.object->cend());
9830 o->write_characters(indent_string.c_str(), new_indent);
9831 o->write_character('\"');
9832 dump_escaped(i->first, ensure_ascii);
9833 o->write_characters("\": ", 3);
9834 dump(i->second, true, ensure_ascii, indent_step, new_indent);
9835
9836 o->write_character('\n');
9837 o->write_characters(indent_string.c_str(), current_indent);
9838 o->write_character('}');
9839 }
9840 else
9841 {
9842 o->write_character('{');
9843
9844 // first n-1 elements
9845 auto i = val.m_value.object->cbegin();
9846 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9847 {
9848 o->write_character('\"');
9849 dump_escaped(i->first, ensure_ascii);
9850 o->write_characters("\":", 2);
9851 dump(i->second, false, ensure_ascii, indent_step, current_indent);
9852 o->write_character(',');
9853 }
9854
9855 // last element
9856 assert(i != val.m_value.object->cend());
9857 assert(std::next(i) == val.m_value.object->cend());
9858 o->write_character('\"');
9859 dump_escaped(i->first, ensure_ascii);
9860 o->write_characters("\":", 2);
9861 dump(i->second, false, ensure_ascii, indent_step, current_indent);
9862
9863 o->write_character('}');
9864 }
9865
9866 return;
9867 }
9868
9869 case value_t::array:
9870 {
9871 if (val.m_value.array->empty())
9872 {
9873 o->write_characters("[]", 2);
9874 return;
9875 }
9876
9877 if (pretty_print)
9878 {
9879 o->write_characters("[\n", 2);
9880
9881 // variable to hold indentation for recursive calls
9882 const auto new_indent = current_indent + indent_step;
9883 if (JSON_UNLIKELY(indent_string.size() < new_indent))
9884 {
9885 indent_string.resize(indent_string.size() * 2, ' ');
9886 }
9887
9888 // first n-1 elements
9889 for (auto i = val.m_value.array->cbegin();
9890 i != val.m_value.array->cend() - 1; ++i)
9891 {
9892 o->write_characters(indent_string.c_str(), new_indent);
9893 dump(*i, true, ensure_ascii, indent_step, new_indent);
9894 o->write_characters(",\n", 2);
9895 }
9896
9897 // last element
9898 assert(not val.m_value.array->empty());
9899 o->write_characters(indent_string.c_str(), new_indent);
9900 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
9901
9902 o->write_character('\n');
9903 o->write_characters(indent_string.c_str(), current_indent);
9904 o->write_character(']');
9905 }
9906 else
9907 {
9908 o->write_character('[');
9909
9910 // first n-1 elements
9911 for (auto i = val.m_value.array->cbegin();
9912 i != val.m_value.array->cend() - 1; ++i)
9913 {
9914 dump(*i, false, ensure_ascii, indent_step, current_indent);
9915 o->write_character(',');
9916 }
9917
9918 // last element
9919 assert(not val.m_value.array->empty());
9920 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
9921
9922 o->write_character(']');
9923 }
9924
9925 return;
9926 }
9927
9928 case value_t::string:
9929 {
9930 o->write_character('\"');
9931 dump_escaped(*val.m_value.string, ensure_ascii);
9932 o->write_character('\"');
9933 return;
9934 }
9935
9936 case value_t::boolean:
9937 {
9938 if (val.m_value.boolean)
9939 {
9940 o->write_characters("true", 4);
9941 }
9942 else
9943 {
9944 o->write_characters("false", 5);
9945 }
9946 return;
9947 }
9948
9949 case value_t::number_integer:
9950 {
9951 dump_integer(val.m_value.number_integer);
9952 return;
9953 }
9954
9955 case value_t::number_unsigned:
9956 {
9957 dump_integer(val.m_value.number_unsigned);
9958 return;
9959 }
9960
9961 case value_t::number_float:
9962 {
9963 dump_float(val.m_value.number_float);
9964 return;
9965 }
9966
9967 case value_t::discarded:
9968 {
9969 o->write_characters("<discarded>", 11);
9970 return;
9971 }
9972
9973 case value_t::null:
9974 {
9975 o->write_characters("null", 4);
9976 return;
9977 }
9978 }
9979 }
9980
9981 private:
9982 /*!
9983 @brief dump escaped string
9984
9985 Escape a string by replacing certain special characters by a sequence of an
9986 escape character (backslash) and another character and other control
9987 characters by a sequence of "\u" followed by a four-digit hex
9988 representation. The escaped string is written to output stream @a o.
9989
9990 @param[in] s the string to escape
9991 @param[in] ensure_ascii whether to escape non-ASCII characters with
9992 \uXXXX sequences
9993
9994 @complexity Linear in the length of string @a s.
9995 */
dump_escaped(const string_t & s,const bool ensure_ascii)9996 void dump_escaped(const string_t& s, const bool ensure_ascii)
9997 {
9998 uint32_t codepoint;
9999 uint8_t state = UTF8_ACCEPT;
10000 std::size_t bytes = 0; // number of bytes written to string_buffer
10001
10002 for (std::size_t i = 0; i < s.size(); ++i)
10003 {
10004 const auto byte = static_cast<uint8_t>(s[i]);
10005
10006 switch (decode(state, codepoint, byte))
10007 {
10008 case UTF8_ACCEPT: // decode found a new code point
10009 {
10010 switch (codepoint)
10011 {
10012 case 0x08: // backspace
10013 {
10014 string_buffer[bytes++] = '\\';
10015 string_buffer[bytes++] = 'b';
10016 break;
10017 }
10018
10019 case 0x09: // horizontal tab
10020 {
10021 string_buffer[bytes++] = '\\';
10022 string_buffer[bytes++] = 't';
10023 break;
10024 }
10025
10026 case 0x0A: // newline
10027 {
10028 string_buffer[bytes++] = '\\';
10029 string_buffer[bytes++] = 'n';
10030 break;
10031 }
10032
10033 case 0x0C: // formfeed
10034 {
10035 string_buffer[bytes++] = '\\';
10036 string_buffer[bytes++] = 'f';
10037 break;
10038 }
10039
10040 case 0x0D: // carriage return
10041 {
10042 string_buffer[bytes++] = '\\';
10043 string_buffer[bytes++] = 'r';
10044 break;
10045 }
10046
10047 case 0x22: // quotation mark
10048 {
10049 string_buffer[bytes++] = '\\';
10050 string_buffer[bytes++] = '\"';
10051 break;
10052 }
10053
10054 case 0x5C: // reverse solidus
10055 {
10056 string_buffer[bytes++] = '\\';
10057 string_buffer[bytes++] = '\\';
10058 break;
10059 }
10060
10061 default:
10062 {
10063 // escape control characters (0x00..0x1F) or, if
10064 // ensure_ascii parameter is used, non-ASCII characters
10065 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
10066 {
10067 if (codepoint <= 0xFFFF)
10068 {
10069 std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
10070 static_cast<uint16_t>(codepoint));
10071 bytes += 6;
10072 }
10073 else
10074 {
10075 std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
10076 static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
10077 static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
10078 bytes += 12;
10079 }
10080 }
10081 else
10082 {
10083 // copy byte to buffer (all previous bytes
10084 // been copied have in default case above)
10085 string_buffer[bytes++] = s[i];
10086 }
10087 break;
10088 }
10089 }
10090
10091 // write buffer and reset index; there must be 13 bytes
10092 // left, as this is the maximal number of bytes to be
10093 // written ("\uxxxx\uxxxx\0") for one code point
10094 if (string_buffer.size() - bytes < 13)
10095 {
10096 o->write_characters(string_buffer.data(), bytes);
10097 bytes = 0;
10098 }
10099 break;
10100 }
10101
10102 case UTF8_REJECT: // decode found invalid UTF-8 byte
10103 {
10104 std::string sn(3, '\0');
10105 snprintf(&sn[0], sn.size(), "%.2X", byte);
10106 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
10107 }
10108
10109 default: // decode found yet incomplete multi-byte code point
10110 {
10111 if (not ensure_ascii)
10112 {
10113 // code point will not be escaped - copy byte to buffer
10114 string_buffer[bytes++] = s[i];
10115 }
10116 break;
10117 }
10118 }
10119 }
10120
10121 if (JSON_LIKELY(state == UTF8_ACCEPT))
10122 {
10123 // write buffer
10124 if (bytes > 0)
10125 {
10126 o->write_characters(string_buffer.data(), bytes);
10127 }
10128 }
10129 else
10130 {
10131 // we finish reading, but do not accept: string was incomplete
10132 std::string sn(3, '\0');
10133 snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
10134 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
10135 }
10136 }
10137
10138 /*!
10139 @brief dump an integer
10140
10141 Dump a given integer to output stream @a o. Works internally with
10142 @a number_buffer.
10143
10144 @param[in] x integer number (signed or unsigned) to dump
10145 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
10146 */
10147 template<typename NumberType, detail::enable_if_t<
10148 std::is_same<NumberType, number_unsigned_t>::value or
10149 std::is_same<NumberType, number_integer_t>::value,
10150 int> = 0>
dump_integer(NumberType x)10151 void dump_integer(NumberType x)
10152 {
10153 // special case for "0"
10154 if (x == 0)
10155 {
10156 o->write_character('0');
10157 return;
10158 }
10159
10160 const bool is_negative = not (x >= 0); // see issue #755
10161 std::size_t i = 0;
10162
10163 while (x != 0)
10164 {
10165 // spare 1 byte for '\0'
10166 assert(i < number_buffer.size() - 1);
10167
10168 const auto digit = std::labs(static_cast<long>(x % 10));
10169 number_buffer[i++] = static_cast<char>('0' + digit);
10170 x /= 10;
10171 }
10172
10173 if (is_negative)
10174 {
10175 // make sure there is capacity for the '-'
10176 assert(i < number_buffer.size() - 2);
10177 number_buffer[i++] = '-';
10178 }
10179
10180 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
10181 o->write_characters(number_buffer.data(), i);
10182 }
10183
10184 /*!
10185 @brief dump a floating-point number
10186
10187 Dump a given floating-point number to output stream @a o. Works internally
10188 with @a number_buffer.
10189
10190 @param[in] x floating-point number to dump
10191 */
dump_float(number_float_t x)10192 void dump_float(number_float_t x)
10193 {
10194 // NaN / inf
10195 if (not std::isfinite(x))
10196 {
10197 o->write_characters("null", 4);
10198 return;
10199 }
10200
10201 // If number_float_t is an IEEE-754 single or double precision number,
10202 // use the Grisu2 algorithm to produce short numbers which are
10203 // guaranteed to round-trip, using strtof and strtod, resp.
10204 //
10205 // NB: The test below works if <long double> == <double>.
10206 static constexpr bool is_ieee_single_or_double
10207 = (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
10208 (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);
10209
10210 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
10211 }
10212
dump_float(number_float_t x,std::true_type)10213 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
10214 {
10215 char* begin = number_buffer.data();
10216 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
10217
10218 o->write_characters(begin, static_cast<size_t>(end - begin));
10219 }
10220
dump_float(number_float_t x,std::false_type)10221 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
10222 {
10223 // get number of digits for a float -> text -> float round-trip
10224 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
10225
10226 // the actual conversion
10227 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
10228
10229 // negative value indicates an error
10230 assert(len > 0);
10231 // check if buffer was large enough
10232 assert(static_cast<std::size_t>(len) < number_buffer.size());
10233
10234 // erase thousands separator
10235 if (thousands_sep != '\0')
10236 {
10237 const auto end = std::remove(number_buffer.begin(),
10238 number_buffer.begin() + len, thousands_sep);
10239 std::fill(end, number_buffer.end(), '\0');
10240 assert((end - number_buffer.begin()) <= len);
10241 len = (end - number_buffer.begin());
10242 }
10243
10244 // convert decimal point to '.'
10245 if (decimal_point != '\0' and decimal_point != '.')
10246 {
10247 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
10248 if (dec_pos != number_buffer.end())
10249 {
10250 *dec_pos = '.';
10251 }
10252 }
10253
10254 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
10255
10256 // determine if need to append ".0"
10257 const bool value_is_int_like =
10258 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
10259 [](char c)
10260 {
10261 return (c == '.' or c == 'e');
10262 });
10263
10264 if (value_is_int_like)
10265 {
10266 o->write_characters(".0", 2);
10267 }
10268 }
10269
10270 /*!
10271 @brief check whether a string is UTF-8 encoded
10272
10273 The function checks each byte of a string whether it is UTF-8 encoded. The
10274 result of the check is stored in the @a state parameter. The function must
10275 be called initially with state 0 (accept). State 1 means the string must
10276 be rejected, because the current byte is not allowed. If the string is
10277 completely processed, but the state is non-zero, the string ended
10278 prematurely; that is, the last byte indicated more bytes should have
10279 followed.
10280
10281 @param[in,out] state the state of the decoding
10282 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
10283 @param[in] byte next byte to decode
10284 @return new state
10285
10286 @note The function has been edited: a std::array is used.
10287
10288 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
10289 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
10290 */
decode(uint8_t & state,uint32_t & codep,const uint8_t byte)10291 static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
10292 {
10293 static const std::array<uint8_t, 400> utf8d =
10294 {
10295 {
10296 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
10297 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
10298 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
10299 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
10300 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
10301 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
10302 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
10303 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
10304 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
10305 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
10306 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
10307 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
10308 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
10309 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
10310 }
10311 };
10312
10313 const uint8_t type = utf8d[byte];
10314
10315 codep = (state != UTF8_ACCEPT)
10316 ? (byte & 0x3fu) | (codep << 6)
10317 : static_cast<uint32_t>(0xff >> type) & (byte);
10318
10319 state = utf8d[256u + state * 16u + type];
10320 return state;
10321 }
10322
10323 private:
10324 /// the output of the serializer
10325 output_adapter_t<char> o = nullptr;
10326
10327 /// a (hopefully) large enough character buffer
10328 std::array<char, 64> number_buffer{{}};
10329
10330 /// the locale
10331 const std::lconv* loc = nullptr;
10332 /// the locale's thousand separator character
10333 const char thousands_sep = '\0';
10334 /// the locale's decimal point character
10335 const char decimal_point = '\0';
10336
10337 /// string buffer
10338 std::array<char, 512> string_buffer{{}};
10339
10340 /// the indentation character
10341 const char indent_char;
10342 /// the indentation string
10343 string_t indent_string;
10344 };
10345 }
10346 }
10347
10348 // #include <nlohmann/detail/json_ref.hpp>
10349
10350
10351 #include <initializer_list>
10352 #include <utility>
10353
10354 namespace nlohmann
10355 {
10356 namespace detail
10357 {
10358 template<typename BasicJsonType>
10359 class json_ref
10360 {
10361 public:
10362 using value_type = BasicJsonType;
10363
json_ref(value_type && value)10364 json_ref(value_type&& value)
10365 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
10366 {}
10367
json_ref(const value_type & value)10368 json_ref(const value_type& value)
10369 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
10370 {}
10371
json_ref(std::initializer_list<json_ref> init)10372 json_ref(std::initializer_list<json_ref> init)
10373 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
10374 {}
10375
10376 template<class... Args>
json_ref(Args &&...args)10377 json_ref(Args&& ... args)
10378 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
10379 {}
10380
10381 // class should be movable only
10382 json_ref(json_ref&&) = default;
10383 json_ref(const json_ref&) = delete;
10384 json_ref& operator=(const json_ref&) = delete;
10385
moved_or_copied() const10386 value_type moved_or_copied() const
10387 {
10388 if (is_rvalue)
10389 {
10390 return std::move(*value_ref);
10391 }
10392 return *value_ref;
10393 }
10394
operator *() const10395 value_type const& operator*() const
10396 {
10397 return *static_cast<value_type const*>(value_ref);
10398 }
10399
operator ->() const10400 value_type const* operator->() const
10401 {
10402 return static_cast<value_type const*>(value_ref);
10403 }
10404
10405 private:
10406 mutable value_type owned_value = nullptr;
10407 value_type* value_ref = nullptr;
10408 const bool is_rvalue;
10409 };
10410 }
10411 }
10412
10413 // #include <nlohmann/detail/json_pointer.hpp>
10414
10415
10416 #include <cassert> // assert
10417 #include <numeric> // accumulate
10418 #include <string> // string
10419 #include <vector> // vector
10420
10421 // #include <nlohmann/detail/macro_scope.hpp>
10422
10423 // #include <nlohmann/detail/exceptions.hpp>
10424
10425 // #include <nlohmann/detail/value_t.hpp>
10426
10427
10428 namespace nlohmann
10429 {
10430 template<typename BasicJsonType>
10431 class json_pointer
10432 {
10433 // allow basic_json to access private members
10434 NLOHMANN_BASIC_JSON_TPL_DECLARATION
10435 friend class basic_json;
10436
10437 public:
10438 /*!
10439 @brief create JSON pointer
10440
10441 Create a JSON pointer according to the syntax described in
10442 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
10443
10444 @param[in] s string representing the JSON pointer; if omitted, the empty
10445 string is assumed which references the whole JSON value
10446
10447 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
10448 not begin with a slash (`/`); see example below
10449
10450 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
10451 not followed by `0` (representing `~`) or `1` (representing `/`); see
10452 example below
10453
10454 @liveexample{The example shows the construction several valid JSON pointers
10455 as well as the exceptional behavior.,json_pointer}
10456
10457 @since version 2.0.0
10458 */
json_pointer(const std::string & s="")10459 explicit json_pointer(const std::string& s = "")
10460 : reference_tokens(split(s))
10461 {}
10462
10463 /*!
10464 @brief return a string representation of the JSON pointer
10465
10466 @invariant For each JSON pointer `ptr`, it holds:
10467 @code {.cpp}
10468 ptr == json_pointer(ptr.to_string());
10469 @endcode
10470
10471 @return a string representation of the JSON pointer
10472
10473 @liveexample{The example shows the result of `to_string`.,
10474 json_pointer__to_string}
10475
10476 @since version 2.0.0
10477 */
to_string() const10478 std::string to_string() const noexcept
10479 {
10480 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10481 std::string{},
10482 [](const std::string & a, const std::string & b)
10483 {
10484 return a + "/" + escape(b);
10485 });
10486 }
10487
10488 /// @copydoc to_string()
operator std::string() const10489 operator std::string() const
10490 {
10491 return to_string();
10492 }
10493
10494 /*!
10495 @param[in] s reference token to be converted into an array index
10496
10497 @return integer representation of @a s
10498
10499 @throw out_of_range.404 if string @a s could not be converted to an integer
10500 */
array_index(const std::string & s)10501 static int array_index(const std::string& s)
10502 {
10503 std::size_t processed_chars = 0;
10504 const int res = std::stoi(s, &processed_chars);
10505
10506 // check if the string was completely read
10507 if (JSON_UNLIKELY(processed_chars != s.size()))
10508 {
10509 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
10510 }
10511
10512 return res;
10513 }
10514
10515 private:
10516 /*!
10517 @brief remove and return last reference pointer
10518 @throw out_of_range.405 if JSON pointer has no parent
10519 */
pop_back()10520 std::string pop_back()
10521 {
10522 if (JSON_UNLIKELY(is_root()))
10523 {
10524 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10525 }
10526
10527 auto last = reference_tokens.back();
10528 reference_tokens.pop_back();
10529 return last;
10530 }
10531
10532 /// return whether pointer points to the root document
is_root() const10533 bool is_root() const
10534 {
10535 return reference_tokens.empty();
10536 }
10537
top() const10538 json_pointer top() const
10539 {
10540 if (JSON_UNLIKELY(is_root()))
10541 {
10542 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10543 }
10544
10545 json_pointer result = *this;
10546 result.reference_tokens = {reference_tokens[0]};
10547 return result;
10548 }
10549
10550 /*!
10551 @brief create and return a reference to the pointed to value
10552
10553 @complexity Linear in the number of reference tokens.
10554
10555 @throw parse_error.109 if array index is not a number
10556 @throw type_error.313 if value cannot be unflattened
10557 */
get_and_create(BasicJsonType & j) const10558 BasicJsonType& get_and_create(BasicJsonType& j) const
10559 {
10560 using size_type = typename BasicJsonType::size_type;
10561 auto result = &j;
10562
10563 // in case no reference tokens exist, return a reference to the JSON value
10564 // j which will be overwritten by a primitive value
10565 for (const auto& reference_token : reference_tokens)
10566 {
10567 switch (result->m_type)
10568 {
10569 case detail::value_t::null:
10570 {
10571 if (reference_token == "0")
10572 {
10573 // start a new array if reference token is 0
10574 result = &result->operator[](0);
10575 }
10576 else
10577 {
10578 // start a new object otherwise
10579 result = &result->operator[](reference_token);
10580 }
10581 break;
10582 }
10583
10584 case detail::value_t::object:
10585 {
10586 // create an entry in the object
10587 result = &result->operator[](reference_token);
10588 break;
10589 }
10590
10591 case detail::value_t::array:
10592 {
10593 // create an entry in the array
10594 JSON_TRY
10595 {
10596 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
10597 }
10598 JSON_CATCH(std::invalid_argument&)
10599 {
10600 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10601 }
10602 break;
10603 }
10604
10605 /*
10606 The following code is only reached if there exists a reference
10607 token _and_ the current value is primitive. In this case, we have
10608 an error situation, because primitive values may only occur as
10609 single value; that is, with an empty list of reference tokens.
10610 */
10611 default:
10612 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
10613 }
10614 }
10615
10616 return *result;
10617 }
10618
10619 /*!
10620 @brief return a reference to the pointed to value
10621
10622 @note This version does not throw if a value is not present, but tries to
10623 create nested values instead. For instance, calling this function
10624 with pointer `"/this/that"` on a null value is equivalent to calling
10625 `operator[]("this").operator[]("that")` on that value, effectively
10626 changing the null value to an object.
10627
10628 @param[in] ptr a JSON value
10629
10630 @return reference to the JSON value pointed to by the JSON pointer
10631
10632 @complexity Linear in the length of the JSON pointer.
10633
10634 @throw parse_error.106 if an array index begins with '0'
10635 @throw parse_error.109 if an array index was not a number
10636 @throw out_of_range.404 if the JSON pointer can not be resolved
10637 */
get_unchecked(BasicJsonType * ptr) const10638 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
10639 {
10640 using size_type = typename BasicJsonType::size_type;
10641 for (const auto& reference_token : reference_tokens)
10642 {
10643 // convert null values to arrays or objects before continuing
10644 if (ptr->m_type == detail::value_t::null)
10645 {
10646 // check if reference token is a number
10647 const bool nums =
10648 std::all_of(reference_token.begin(), reference_token.end(),
10649 [](const char x)
10650 {
10651 return (x >= '0' and x <= '9');
10652 });
10653
10654 // change value to array for numbers or "-" or to object otherwise
10655 *ptr = (nums or reference_token == "-")
10656 ? detail::value_t::array
10657 : detail::value_t::object;
10658 }
10659
10660 switch (ptr->m_type)
10661 {
10662 case detail::value_t::object:
10663 {
10664 // use unchecked object access
10665 ptr = &ptr->operator[](reference_token);
10666 break;
10667 }
10668
10669 case detail::value_t::array:
10670 {
10671 // error condition (cf. RFC 6901, Sect. 4)
10672 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10673 {
10674 JSON_THROW(detail::parse_error::create(106, 0,
10675 "array index '" + reference_token +
10676 "' must not begin with '0'"));
10677 }
10678
10679 if (reference_token == "-")
10680 {
10681 // explicitly treat "-" as index beyond the end
10682 ptr = &ptr->operator[](ptr->m_value.array->size());
10683 }
10684 else
10685 {
10686 // convert array index to number; unchecked access
10687 JSON_TRY
10688 {
10689 ptr = &ptr->operator[](
10690 static_cast<size_type>(array_index(reference_token)));
10691 }
10692 JSON_CATCH(std::invalid_argument&)
10693 {
10694 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10695 }
10696 }
10697 break;
10698 }
10699
10700 default:
10701 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10702 }
10703 }
10704
10705 return *ptr;
10706 }
10707
10708 /*!
10709 @throw parse_error.106 if an array index begins with '0'
10710 @throw parse_error.109 if an array index was not a number
10711 @throw out_of_range.402 if the array index '-' is used
10712 @throw out_of_range.404 if the JSON pointer can not be resolved
10713 */
get_checked(BasicJsonType * ptr) const10714 BasicJsonType& get_checked(BasicJsonType* ptr) const
10715 {
10716 using size_type = typename BasicJsonType::size_type;
10717 for (const auto& reference_token : reference_tokens)
10718 {
10719 switch (ptr->m_type)
10720 {
10721 case detail::value_t::object:
10722 {
10723 // note: at performs range check
10724 ptr = &ptr->at(reference_token);
10725 break;
10726 }
10727
10728 case detail::value_t::array:
10729 {
10730 if (JSON_UNLIKELY(reference_token == "-"))
10731 {
10732 // "-" always fails the range check
10733 JSON_THROW(detail::out_of_range::create(402,
10734 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10735 ") is out of range"));
10736 }
10737
10738 // error condition (cf. RFC 6901, Sect. 4)
10739 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10740 {
10741 JSON_THROW(detail::parse_error::create(106, 0,
10742 "array index '" + reference_token +
10743 "' must not begin with '0'"));
10744 }
10745
10746 // note: at performs range check
10747 JSON_TRY
10748 {
10749 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10750 }
10751 JSON_CATCH(std::invalid_argument&)
10752 {
10753 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10754 }
10755 break;
10756 }
10757
10758 default:
10759 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10760 }
10761 }
10762
10763 return *ptr;
10764 }
10765
10766 /*!
10767 @brief return a const reference to the pointed to value
10768
10769 @param[in] ptr a JSON value
10770
10771 @return const reference to the JSON value pointed to by the JSON
10772 pointer
10773
10774 @throw parse_error.106 if an array index begins with '0'
10775 @throw parse_error.109 if an array index was not a number
10776 @throw out_of_range.402 if the array index '-' is used
10777 @throw out_of_range.404 if the JSON pointer can not be resolved
10778 */
get_unchecked(const BasicJsonType * ptr) const10779 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
10780 {
10781 using size_type = typename BasicJsonType::size_type;
10782 for (const auto& reference_token : reference_tokens)
10783 {
10784 switch (ptr->m_type)
10785 {
10786 case detail::value_t::object:
10787 {
10788 // use unchecked object access
10789 ptr = &ptr->operator[](reference_token);
10790 break;
10791 }
10792
10793 case detail::value_t::array:
10794 {
10795 if (JSON_UNLIKELY(reference_token == "-"))
10796 {
10797 // "-" cannot be used for const access
10798 JSON_THROW(detail::out_of_range::create(402,
10799 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10800 ") is out of range"));
10801 }
10802
10803 // error condition (cf. RFC 6901, Sect. 4)
10804 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10805 {
10806 JSON_THROW(detail::parse_error::create(106, 0,
10807 "array index '" + reference_token +
10808 "' must not begin with '0'"));
10809 }
10810
10811 // use unchecked array access
10812 JSON_TRY
10813 {
10814 ptr = &ptr->operator[](
10815 static_cast<size_type>(array_index(reference_token)));
10816 }
10817 JSON_CATCH(std::invalid_argument&)
10818 {
10819 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10820 }
10821 break;
10822 }
10823
10824 default:
10825 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10826 }
10827 }
10828
10829 return *ptr;
10830 }
10831
10832 /*!
10833 @throw parse_error.106 if an array index begins with '0'
10834 @throw parse_error.109 if an array index was not a number
10835 @throw out_of_range.402 if the array index '-' is used
10836 @throw out_of_range.404 if the JSON pointer can not be resolved
10837 */
get_checked(const BasicJsonType * ptr) const10838 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
10839 {
10840 using size_type = typename BasicJsonType::size_type;
10841 for (const auto& reference_token : reference_tokens)
10842 {
10843 switch (ptr->m_type)
10844 {
10845 case detail::value_t::object:
10846 {
10847 // note: at performs range check
10848 ptr = &ptr->at(reference_token);
10849 break;
10850 }
10851
10852 case detail::value_t::array:
10853 {
10854 if (JSON_UNLIKELY(reference_token == "-"))
10855 {
10856 // "-" always fails the range check
10857 JSON_THROW(detail::out_of_range::create(402,
10858 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10859 ") is out of range"));
10860 }
10861
10862 // error condition (cf. RFC 6901, Sect. 4)
10863 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10864 {
10865 JSON_THROW(detail::parse_error::create(106, 0,
10866 "array index '" + reference_token +
10867 "' must not begin with '0'"));
10868 }
10869
10870 // note: at performs range check
10871 JSON_TRY
10872 {
10873 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10874 }
10875 JSON_CATCH(std::invalid_argument&)
10876 {
10877 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10878 }
10879 break;
10880 }
10881
10882 default:
10883 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10884 }
10885 }
10886
10887 return *ptr;
10888 }
10889
10890 /*!
10891 @brief split the string input to reference tokens
10892
10893 @note This function is only called by the json_pointer constructor.
10894 All exceptions below are documented there.
10895
10896 @throw parse_error.107 if the pointer is not empty or begins with '/'
10897 @throw parse_error.108 if character '~' is not followed by '0' or '1'
10898 */
split(const std::string & reference_string)10899 static std::vector<std::string> split(const std::string& reference_string)
10900 {
10901 std::vector<std::string> result;
10902
10903 // special case: empty reference string -> no reference tokens
10904 if (reference_string.empty())
10905 {
10906 return result;
10907 }
10908
10909 // check if nonempty reference string begins with slash
10910 if (JSON_UNLIKELY(reference_string[0] != '/'))
10911 {
10912 JSON_THROW(detail::parse_error::create(107, 1,
10913 "JSON pointer must be empty or begin with '/' - was: '" +
10914 reference_string + "'"));
10915 }
10916
10917 // extract the reference tokens:
10918 // - slash: position of the last read slash (or end of string)
10919 // - start: position after the previous slash
10920 for (
10921 // search for the first slash after the first character
10922 std::size_t slash = reference_string.find_first_of('/', 1),
10923 // set the beginning of the first reference token
10924 start = 1;
10925 // we can stop if start == string::npos+1 = 0
10926 start != 0;
10927 // set the beginning of the next reference token
10928 // (will eventually be 0 if slash == std::string::npos)
10929 start = slash + 1,
10930 // find next slash
10931 slash = reference_string.find_first_of('/', start))
10932 {
10933 // use the text between the beginning of the reference token
10934 // (start) and the last slash (slash).
10935 auto reference_token = reference_string.substr(start, slash - start);
10936
10937 // check reference tokens are properly escaped
10938 for (std::size_t pos = reference_token.find_first_of('~');
10939 pos != std::string::npos;
10940 pos = reference_token.find_first_of('~', pos + 1))
10941 {
10942 assert(reference_token[pos] == '~');
10943
10944 // ~ must be followed by 0 or 1
10945 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
10946 (reference_token[pos + 1] != '0' and
10947 reference_token[pos + 1] != '1')))
10948 {
10949 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
10950 }
10951 }
10952
10953 // finally, store the reference token
10954 unescape(reference_token);
10955 result.push_back(reference_token);
10956 }
10957
10958 return result;
10959 }
10960
10961 /*!
10962 @brief replace all occurrences of a substring by another string
10963
10964 @param[in,out] s the string to manipulate; changed so that all
10965 occurrences of @a f are replaced with @a t
10966 @param[in] f the substring to replace with @a t
10967 @param[in] t the string to replace @a f
10968
10969 @pre The search string @a f must not be empty. **This precondition is
10970 enforced with an assertion.**
10971
10972 @since version 2.0.0
10973 */
replace_substring(std::string & s,const std::string & f,const std::string & t)10974 static void replace_substring(std::string& s, const std::string& f,
10975 const std::string& t)
10976 {
10977 assert(not f.empty());
10978 for (auto pos = s.find(f); // find first occurrence of f
10979 pos != std::string::npos; // make sure f was found
10980 s.replace(pos, f.size(), t), // replace with t, and
10981 pos = s.find(f, pos + t.size())) // find next occurrence of f
10982 {}
10983 }
10984
10985 /// escape "~"" to "~0" and "/" to "~1"
escape(std::string s)10986 static std::string escape(std::string s)
10987 {
10988 replace_substring(s, "~", "~0");
10989 replace_substring(s, "/", "~1");
10990 return s;
10991 }
10992
10993 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)10994 static void unescape(std::string& s)
10995 {
10996 replace_substring(s, "~1", "/");
10997 replace_substring(s, "~0", "~");
10998 }
10999
11000 /*!
11001 @param[in] reference_string the reference string to the current value
11002 @param[in] value the value to consider
11003 @param[in,out] result the result object to insert values to
11004
11005 @note Empty objects or arrays are flattened to `null`.
11006 */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)11007 static void flatten(const std::string& reference_string,
11008 const BasicJsonType& value,
11009 BasicJsonType& result)
11010 {
11011 switch (value.m_type)
11012 {
11013 case detail::value_t::array:
11014 {
11015 if (value.m_value.array->empty())
11016 {
11017 // flatten empty array as null
11018 result[reference_string] = nullptr;
11019 }
11020 else
11021 {
11022 // iterate array and use index as reference string
11023 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11024 {
11025 flatten(reference_string + "/" + std::to_string(i),
11026 value.m_value.array->operator[](i), result);
11027 }
11028 }
11029 break;
11030 }
11031
11032 case detail::value_t::object:
11033 {
11034 if (value.m_value.object->empty())
11035 {
11036 // flatten empty object as null
11037 result[reference_string] = nullptr;
11038 }
11039 else
11040 {
11041 // iterate object and use keys as reference string
11042 for (const auto& element : *value.m_value.object)
11043 {
11044 flatten(reference_string + "/" + escape(element.first), element.second, result);
11045 }
11046 }
11047 break;
11048 }
11049
11050 default:
11051 {
11052 // add primitive value with its reference string
11053 result[reference_string] = value;
11054 break;
11055 }
11056 }
11057 }
11058
11059 /*!
11060 @param[in] value flattened JSON
11061
11062 @return unflattened JSON
11063
11064 @throw parse_error.109 if array index is not a number
11065 @throw type_error.314 if value is not an object
11066 @throw type_error.315 if object values are not primitive
11067 @throw type_error.313 if value cannot be unflattened
11068 */
11069 static BasicJsonType
unflatten(const BasicJsonType & value)11070 unflatten(const BasicJsonType& value)
11071 {
11072 if (JSON_UNLIKELY(not value.is_object()))
11073 {
11074 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11075 }
11076
11077 BasicJsonType result;
11078
11079 // iterate the JSON object values
11080 for (const auto& element : *value.m_value.object)
11081 {
11082 if (JSON_UNLIKELY(not element.second.is_primitive()))
11083 {
11084 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11085 }
11086
11087 // assign value to reference pointed to by JSON pointer; Note that if
11088 // the JSON pointer is "" (i.e., points to the whole value), function
11089 // get_and_create returns a reference to result itself. An assignment
11090 // will then create a primitive value.
11091 json_pointer(element.first).get_and_create(result) = element.second;
11092 }
11093
11094 return result;
11095 }
11096
operator ==(json_pointer const & lhs,json_pointer const & rhs)11097 friend bool operator==(json_pointer const& lhs,
11098 json_pointer const& rhs) noexcept
11099 {
11100 return (lhs.reference_tokens == rhs.reference_tokens);
11101 }
11102
operator !=(json_pointer const & lhs,json_pointer const & rhs)11103 friend bool operator!=(json_pointer const& lhs,
11104 json_pointer const& rhs) noexcept
11105 {
11106 return not (lhs == rhs);
11107 }
11108
11109 /// the reference tokens
11110 std::vector<std::string> reference_tokens;
11111 };
11112 }
11113
11114 // #include <nlohmann/adl_serializer.hpp>
11115
11116
11117 #include <utility>
11118
11119 // #include <nlohmann/detail/conversions/from_json.hpp>
11120
11121 // #include <nlohmann/detail/conversions/to_json.hpp>
11122
11123
11124 namespace nlohmann
11125 {
11126 template<typename, typename>
11127 struct adl_serializer
11128 {
11129 /*!
11130 @brief convert a JSON value to any value type
11131
11132 This function is usually called by the `get()` function of the
11133 @ref basic_json class (either explicit or via conversion operators).
11134
11135 @param[in] j JSON value to read from
11136 @param[in,out] val value to write to
11137 */
11138 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer11139 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
11140 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) -> decltype(
11141 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()
11142 )
11143 {
11144 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
11145 }
11146
11147 /*!
11148 @brief convert any value type to a JSON value
11149
11150 This function is usually called by the constructors of the @ref basic_json
11151 class.
11152
11153 @param[in,out] j JSON value to write to
11154 @param[in] val value to read from
11155 */
11156 template <typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer11157 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
11158 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
11159 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
11160 void())
11161 {
11162 ::nlohmann::to_json(j, std::forward<ValueType>(val));
11163 }
11164 };
11165 }
11166
11167
11168 /*!
11169 @brief namespace for Niels Lohmann
11170 @see https://github.com/nlohmann
11171 @since version 1.0.0
11172 */
11173 namespace nlohmann
11174 {
11175
11176 /*!
11177 @brief a class to store JSON values
11178
11179 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
11180 in @ref object_t)
11181 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
11182 in @ref array_t)
11183 @tparam StringType type for JSON strings and object keys (`std::string` by
11184 default; will be used in @ref string_t)
11185 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
11186 in @ref boolean_t)
11187 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
11188 default; will be used in @ref number_integer_t)
11189 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
11190 `uint64_t` by default; will be used in @ref number_unsigned_t)
11191 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
11192 default; will be used in @ref number_float_t)
11193 @tparam AllocatorType type of the allocator to use (`std::allocator` by
11194 default)
11195 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
11196 and `from_json()` (@ref adl_serializer by default)
11197
11198 @requirement The class satisfies the following concept requirements:
11199 - Basic
11200 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
11201 JSON values can be default constructed. The result will be a JSON null
11202 value.
11203 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
11204 A JSON value can be constructed from an rvalue argument.
11205 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
11206 A JSON value can be copy-constructed from an lvalue expression.
11207 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
11208 A JSON value van be assigned from an rvalue argument.
11209 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
11210 A JSON value can be copy-assigned from an lvalue expression.
11211 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
11212 JSON values can be destructed.
11213 - Layout
11214 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
11215 JSON values have
11216 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
11217 All non-static data members are private and standard layout types, the
11218 class has no virtual functions or (virtual) base classes.
11219 - Library-wide
11220 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
11221 JSON values can be compared with `==`, see @ref
11222 operator==(const_reference,const_reference).
11223 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
11224 JSON values can be compared with `<`, see @ref
11225 operator<(const_reference,const_reference).
11226 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
11227 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
11228 other compatible types, using unqualified function call @ref swap().
11229 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
11230 JSON values can be compared against `std::nullptr_t` objects which are used
11231 to model the `null` value.
11232 - Container
11233 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
11234 JSON values can be used like STL containers and provide iterator access.
11235 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
11236 JSON values can be used like STL containers and provide reverse iterator
11237 access.
11238
11239 @invariant The member variables @a m_value and @a m_type have the following
11240 relationship:
11241 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
11242 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
11243 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
11244 The invariants are checked by member function assert_invariant().
11245
11246 @internal
11247 @note ObjectType trick from http://stackoverflow.com/a/9860911
11248 @endinternal
11249
11250 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
11251 Format](http://rfc7159.net/rfc7159)
11252
11253 @since version 1.0.0
11254
11255 @nosubgrouping
11256 */
11257 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11258 class basic_json
11259 {
11260 private:
11261 template<detail::value_t> friend struct detail::external_constructor;
11262 friend ::nlohmann::json_pointer<basic_json>;
11263 friend ::nlohmann::detail::parser<basic_json>;
11264 friend ::nlohmann::detail::serializer<basic_json>;
11265 template<typename BasicJsonType>
11266 friend class ::nlohmann::detail::iter_impl;
11267 template<typename BasicJsonType, typename CharType>
11268 friend class ::nlohmann::detail::binary_writer;
11269 template<typename BasicJsonType, typename SAX>
11270 friend class ::nlohmann::detail::binary_reader;
11271 template<typename BasicJsonType>
11272 friend class ::nlohmann::detail::json_sax_dom_parser;
11273 template<typename BasicJsonType>
11274 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
11275
11276 /// workaround type for MSVC
11277 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
11278
11279 // convenience aliases for types residing in namespace detail;
11280 using lexer = ::nlohmann::detail::lexer<basic_json>;
11281 using parser = ::nlohmann::detail::parser<basic_json>;
11282
11283 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
11284 template<typename BasicJsonType>
11285 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
11286 template<typename BasicJsonType>
11287 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
11288 template<typename Iterator>
11289 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
11290 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
11291
11292 template<typename CharType>
11293 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
11294
11295 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
11296 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
11297
11298 using serializer = ::nlohmann::detail::serializer<basic_json>;
11299
11300 public:
11301 using value_t = detail::value_t;
11302 /// JSON Pointer, see @ref nlohmann::json_pointer
11303 using json_pointer = ::nlohmann::json_pointer<basic_json>;
11304 template<typename T, typename SFINAE>
11305 using json_serializer = JSONSerializer<T, SFINAE>;
11306 /// helper type for initializer lists of basic_json values
11307 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
11308
11309 using input_format_t = detail::input_format_t;
11310 /// SAX interface type, see @ref nlohmann::json_sax
11311 using json_sax_t = json_sax<basic_json>;
11312
11313 ////////////////
11314 // exceptions //
11315 ////////////////
11316
11317 /// @name exceptions
11318 /// Classes to implement user-defined exceptions.
11319 /// @{
11320
11321 /// @copydoc detail::exception
11322 using exception = detail::exception;
11323 /// @copydoc detail::parse_error
11324 using parse_error = detail::parse_error;
11325 /// @copydoc detail::invalid_iterator
11326 using invalid_iterator = detail::invalid_iterator;
11327 /// @copydoc detail::type_error
11328 using type_error = detail::type_error;
11329 /// @copydoc detail::out_of_range
11330 using out_of_range = detail::out_of_range;
11331 /// @copydoc detail::other_error
11332 using other_error = detail::other_error;
11333
11334 /// @}
11335
11336
11337 /////////////////////
11338 // container types //
11339 /////////////////////
11340
11341 /// @name container types
11342 /// The canonic container types to use @ref basic_json like any other STL
11343 /// container.
11344 /// @{
11345
11346 /// the type of elements in a basic_json container
11347 using value_type = basic_json;
11348
11349 /// the type of an element reference
11350 using reference = value_type&;
11351 /// the type of an element const reference
11352 using const_reference = const value_type&;
11353
11354 /// a type to represent differences between iterators
11355 using difference_type = std::ptrdiff_t;
11356 /// a type to represent container sizes
11357 using size_type = std::size_t;
11358
11359 /// the allocator type
11360 using allocator_type = AllocatorType<basic_json>;
11361
11362 /// the type of an element pointer
11363 using pointer = typename std::allocator_traits<allocator_type>::pointer;
11364 /// the type of an element const pointer
11365 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
11366
11367 /// an iterator for a basic_json container
11368 using iterator = iter_impl<basic_json>;
11369 /// a const iterator for a basic_json container
11370 using const_iterator = iter_impl<const basic_json>;
11371 /// a reverse iterator for a basic_json container
11372 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
11373 /// a const reverse iterator for a basic_json container
11374 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
11375
11376 /// @}
11377
11378
11379 /*!
11380 @brief returns the allocator associated with the container
11381 */
get_allocator()11382 static allocator_type get_allocator()
11383 {
11384 return allocator_type();
11385 }
11386
11387 /*!
11388 @brief returns version information on the library
11389
11390 This function returns a JSON object with information about the library,
11391 including the version number and information on the platform and compiler.
11392
11393 @return JSON object holding version information
11394 key | description
11395 ----------- | ---------------
11396 `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).
11397 `copyright` | The copyright line for the library as string.
11398 `name` | The name of the library as string.
11399 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
11400 `url` | The URL of the project as string.
11401 `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).
11402
11403 @liveexample{The following code shows an example output of the `meta()`
11404 function.,meta}
11405
11406 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
11407 changes to any JSON value.
11408
11409 @complexity Constant.
11410
11411 @since 2.1.0
11412 */
meta()11413 static basic_json meta()
11414 {
11415 basic_json result;
11416
11417 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
11418 result["name"] = "JSON for Modern C++";
11419 result["url"] = "https://github.com/nlohmann/json";
11420 result["version"]["string"] =
11421 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
11422 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
11423 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
11424 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
11425 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
11426 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
11427
11428 #ifdef _WIN32
11429 result["platform"] = "win32";
11430 #elif defined __linux__
11431 result["platform"] = "linux";
11432 #elif defined __APPLE__
11433 result["platform"] = "apple";
11434 #elif defined __unix__
11435 result["platform"] = "unix";
11436 #else
11437 result["platform"] = "unknown";
11438 #endif
11439
11440 #if defined(__ICC) || defined(__INTEL_COMPILER)
11441 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
11442 #elif defined(__clang__)
11443 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
11444 #elif defined(__GNUC__) || defined(__GNUG__)
11445 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
11446 #elif defined(__HP_cc) || defined(__HP_aCC)
11447 result["compiler"] = "hp"
11448 #elif defined(__IBMCPP__)
11449 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
11450 #elif defined(_MSC_VER)
11451 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
11452 #elif defined(__PGI)
11453 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
11454 #elif defined(__SUNPRO_CC)
11455 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
11456 #else
11457 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
11458 #endif
11459
11460 #ifdef __cplusplus
11461 result["compiler"]["c++"] = std::to_string(__cplusplus);
11462 #else
11463 result["compiler"]["c++"] = "unknown";
11464 #endif
11465 return result;
11466 }
11467
11468
11469 ///////////////////////////
11470 // JSON value data types //
11471 ///////////////////////////
11472
11473 /// @name JSON value data types
11474 /// The data types to store a JSON value. These types are derived from
11475 /// the template arguments passed to class @ref basic_json.
11476 /// @{
11477
11478 #if defined(JSON_HAS_CPP_14)
11479 // Use transparent comparator if possible, combined with perfect forwarding
11480 // on find() and count() calls prevents unnecessary string construction.
11481 using object_comparator_t = std::less<>;
11482 #else
11483 using object_comparator_t = std::less<StringType>;
11484 #endif
11485
11486 /*!
11487 @brief a type for an object
11488
11489 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
11490 > An object is an unordered collection of zero or more name/value pairs,
11491 > where a name is a string and a value is a string, number, boolean, null,
11492 > object, or array.
11493
11494 To store objects in C++, a type is defined by the template parameters
11495 described below.
11496
11497 @tparam ObjectType the container to store objects (e.g., `std::map` or
11498 `std::unordered_map`)
11499 @tparam StringType the type of the keys or names (e.g., `std::string`).
11500 The comparison function `std::less<StringType>` is used to order elements
11501 inside the container.
11502 @tparam AllocatorType the allocator to use for objects (e.g.,
11503 `std::allocator`)
11504
11505 #### Default type
11506
11507 With the default values for @a ObjectType (`std::map`), @a StringType
11508 (`std::string`), and @a AllocatorType (`std::allocator`), the default
11509 value for @a object_t is:
11510
11511 @code {.cpp}
11512 std::map<
11513 std::string, // key_type
11514 basic_json, // value_type
11515 std::less<std::string>, // key_compare
11516 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
11517 >
11518 @endcode
11519
11520 #### Behavior
11521
11522 The choice of @a object_t influences the behavior of the JSON class. With
11523 the default type, objects have the following behavior:
11524
11525 - When all names are unique, objects will be interoperable in the sense
11526 that all software implementations receiving that object will agree on
11527 the name-value mappings.
11528 - When the names within an object are not unique, it is unspecified which
11529 one of the values for a given key will be chosen. For instance,
11530 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
11531 `{"key": 2}`.
11532 - Internally, name/value pairs are stored in lexicographical order of the
11533 names. Objects will also be serialized (see @ref dump) in this order.
11534 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
11535 and serialized as `{"a": 2, "b": 1}`.
11536 - When comparing objects, the order of the name/value pairs is irrelevant.
11537 This makes objects interoperable in the sense that they will not be
11538 affected by these differences. For instance, `{"b": 1, "a": 2}` and
11539 `{"a": 2, "b": 1}` will be treated as equal.
11540
11541 #### Limits
11542
11543 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11544 > An implementation may set limits on the maximum depth of nesting.
11545
11546 In this class, the object's limit of nesting is not explicitly constrained.
11547 However, a maximum depth of nesting may be introduced by the compiler or
11548 runtime environment. A theoretical limit can be queried by calling the
11549 @ref max_size function of a JSON object.
11550
11551 #### Storage
11552
11553 Objects are stored as pointers in a @ref basic_json type. That is, for any
11554 access to object values, a pointer of type `object_t*` must be
11555 dereferenced.
11556
11557 @sa @ref array_t -- type for an array value
11558
11559 @since version 1.0.0
11560
11561 @note The order name/value pairs are added to the object is *not*
11562 preserved by the library. Therefore, iterating an object may return
11563 name/value pairs in a different order than they were originally stored. In
11564 fact, keys will be traversed in alphabetical order as `std::map` with
11565 `std::less` is used by default. Please note this behavior conforms to [RFC
11566 7159](http://rfc7159.net/rfc7159), because any order implements the
11567 specified "unordered" nature of JSON objects.
11568 */
11569 using object_t = ObjectType<StringType,
11570 basic_json,
11571 object_comparator_t,
11572 AllocatorType<std::pair<const StringType,
11573 basic_json>>>;
11574
11575 /*!
11576 @brief a type for an array
11577
11578 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
11579 > An array is an ordered sequence of zero or more values.
11580
11581 To store objects in C++, a type is defined by the template parameters
11582 explained below.
11583
11584 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
11585 `std::list`)
11586 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
11587
11588 #### Default type
11589
11590 With the default values for @a ArrayType (`std::vector`) and @a
11591 AllocatorType (`std::allocator`), the default value for @a array_t is:
11592
11593 @code {.cpp}
11594 std::vector<
11595 basic_json, // value_type
11596 std::allocator<basic_json> // allocator_type
11597 >
11598 @endcode
11599
11600 #### Limits
11601
11602 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11603 > An implementation may set limits on the maximum depth of nesting.
11604
11605 In this class, the array's limit of nesting is not explicitly constrained.
11606 However, a maximum depth of nesting may be introduced by the compiler or
11607 runtime environment. A theoretical limit can be queried by calling the
11608 @ref max_size function of a JSON array.
11609
11610 #### Storage
11611
11612 Arrays are stored as pointers in a @ref basic_json type. That is, for any
11613 access to array values, a pointer of type `array_t*` must be dereferenced.
11614
11615 @sa @ref object_t -- type for an object value
11616
11617 @since version 1.0.0
11618 */
11619 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
11620
11621 /*!
11622 @brief a type for a string
11623
11624 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
11625 > A string is a sequence of zero or more Unicode characters.
11626
11627 To store objects in C++, a type is defined by the template parameter
11628 described below. Unicode values are split by the JSON class into
11629 byte-sized characters during deserialization.
11630
11631 @tparam StringType the container to store strings (e.g., `std::string`).
11632 Note this container is used for keys/names in objects, see @ref object_t.
11633
11634 #### Default type
11635
11636 With the default values for @a StringType (`std::string`), the default
11637 value for @a string_t is:
11638
11639 @code {.cpp}
11640 std::string
11641 @endcode
11642
11643 #### Encoding
11644
11645 Strings are stored in UTF-8 encoding. Therefore, functions like
11646 `std::string::size()` or `std::string::length()` return the number of
11647 bytes in the string rather than the number of characters or glyphs.
11648
11649 #### String comparison
11650
11651 [RFC 7159](http://rfc7159.net/rfc7159) states:
11652 > Software implementations are typically required to test names of object
11653 > members for equality. Implementations that transform the textual
11654 > representation into sequences of Unicode code units and then perform the
11655 > comparison numerically, code unit by code unit, are interoperable in the
11656 > sense that implementations will agree in all cases on equality or
11657 > inequality of two strings. For example, implementations that compare
11658 > strings with escaped characters unconverted may incorrectly find that
11659 > `"a\\b"` and `"a\u005Cb"` are not equal.
11660
11661 This implementation is interoperable as it does compare strings code unit
11662 by code unit.
11663
11664 #### Storage
11665
11666 String values are stored as pointers in a @ref basic_json type. That is,
11667 for any access to string values, a pointer of type `string_t*` must be
11668 dereferenced.
11669
11670 @since version 1.0.0
11671 */
11672 using string_t = StringType;
11673
11674 /*!
11675 @brief a type for a boolean
11676
11677 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
11678 type which differentiates the two literals `true` and `false`.
11679
11680 To store objects in C++, a type is defined by the template parameter @a
11681 BooleanType which chooses the type to use.
11682
11683 #### Default type
11684
11685 With the default values for @a BooleanType (`bool`), the default value for
11686 @a boolean_t is:
11687
11688 @code {.cpp}
11689 bool
11690 @endcode
11691
11692 #### Storage
11693
11694 Boolean values are stored directly inside a @ref basic_json type.
11695
11696 @since version 1.0.0
11697 */
11698 using boolean_t = BooleanType;
11699
11700 /*!
11701 @brief a type for a number (integer)
11702
11703 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11704 > The representation of numbers is similar to that used in most
11705 > programming languages. A number is represented in base 10 using decimal
11706 > digits. It contains an integer component that may be prefixed with an
11707 > optional minus sign, which may be followed by a fraction part and/or an
11708 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11709 > cannot be represented in the grammar below (such as Infinity and NaN)
11710 > are not permitted.
11711
11712 This description includes both integer and floating-point numbers.
11713 However, C++ allows more precise storage if it is known whether the number
11714 is a signed integer, an unsigned integer or a floating-point number.
11715 Therefore, three different types, @ref number_integer_t, @ref
11716 number_unsigned_t and @ref number_float_t are used.
11717
11718 To store integer numbers in C++, a type is defined by the template
11719 parameter @a NumberIntegerType which chooses the type to use.
11720
11721 #### Default type
11722
11723 With the default values for @a NumberIntegerType (`int64_t`), the default
11724 value for @a number_integer_t is:
11725
11726 @code {.cpp}
11727 int64_t
11728 @endcode
11729
11730 #### Default behavior
11731
11732 - The restrictions about leading zeros is not enforced in C++. Instead,
11733 leading zeros in integer literals lead to an interpretation as octal
11734 number. Internally, the value will be stored as decimal number. For
11735 instance, the C++ integer literal `010` will be serialized to `8`.
11736 During deserialization, leading zeros yield an error.
11737 - Not-a-number (NaN) values will be serialized to `null`.
11738
11739 #### Limits
11740
11741 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11742 > An implementation may set limits on the range and precision of numbers.
11743
11744 When the default type is used, the maximal integer number that can be
11745 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
11746 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
11747 that are out of range will yield over/underflow when used in a
11748 constructor. During deserialization, too large or small integer numbers
11749 will be automatically be stored as @ref number_unsigned_t or @ref
11750 number_float_t.
11751
11752 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11753 > Note that when such software is used, numbers that are integers and are
11754 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11755 > that implementations will agree exactly on their numeric values.
11756
11757 As this range is a subrange of the exactly supported range [INT64_MIN,
11758 INT64_MAX], this class's integer type is interoperable.
11759
11760 #### Storage
11761
11762 Integer number values are stored directly inside a @ref basic_json type.
11763
11764 @sa @ref number_float_t -- type for number values (floating-point)
11765
11766 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11767
11768 @since version 1.0.0
11769 */
11770 using number_integer_t = NumberIntegerType;
11771
11772 /*!
11773 @brief a type for a number (unsigned)
11774
11775 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11776 > The representation of numbers is similar to that used in most
11777 > programming languages. A number is represented in base 10 using decimal
11778 > digits. It contains an integer component that may be prefixed with an
11779 > optional minus sign, which may be followed by a fraction part and/or an
11780 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11781 > cannot be represented in the grammar below (such as Infinity and NaN)
11782 > are not permitted.
11783
11784 This description includes both integer and floating-point numbers.
11785 However, C++ allows more precise storage if it is known whether the number
11786 is a signed integer, an unsigned integer or a floating-point number.
11787 Therefore, three different types, @ref number_integer_t, @ref
11788 number_unsigned_t and @ref number_float_t are used.
11789
11790 To store unsigned integer numbers in C++, a type is defined by the
11791 template parameter @a NumberUnsignedType which chooses the type to use.
11792
11793 #### Default type
11794
11795 With the default values for @a NumberUnsignedType (`uint64_t`), the
11796 default value for @a number_unsigned_t is:
11797
11798 @code {.cpp}
11799 uint64_t
11800 @endcode
11801
11802 #### Default behavior
11803
11804 - The restrictions about leading zeros is not enforced in C++. Instead,
11805 leading zeros in integer literals lead to an interpretation as octal
11806 number. Internally, the value will be stored as decimal number. For
11807 instance, the C++ integer literal `010` will be serialized to `8`.
11808 During deserialization, leading zeros yield an error.
11809 - Not-a-number (NaN) values will be serialized to `null`.
11810
11811 #### Limits
11812
11813 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11814 > An implementation may set limits on the range and precision of numbers.
11815
11816 When the default type is used, the maximal integer number that can be
11817 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
11818 number that can be stored is `0`. Integer numbers that are out of range
11819 will yield over/underflow when used in a constructor. During
11820 deserialization, too large or small integer numbers will be automatically
11821 be stored as @ref number_integer_t or @ref number_float_t.
11822
11823 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11824 > Note that when such software is used, numbers that are integers and are
11825 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11826 > that implementations will agree exactly on their numeric values.
11827
11828 As this range is a subrange (when considered in conjunction with the
11829 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
11830 this class's integer type is interoperable.
11831
11832 #### Storage
11833
11834 Integer number values are stored directly inside a @ref basic_json type.
11835
11836 @sa @ref number_float_t -- type for number values (floating-point)
11837 @sa @ref number_integer_t -- type for number values (integer)
11838
11839 @since version 2.0.0
11840 */
11841 using number_unsigned_t = NumberUnsignedType;
11842
11843 /*!
11844 @brief a type for a number (floating-point)
11845
11846 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11847 > The representation of numbers is similar to that used in most
11848 > programming languages. A number is represented in base 10 using decimal
11849 > digits. It contains an integer component that may be prefixed with an
11850 > optional minus sign, which may be followed by a fraction part and/or an
11851 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11852 > cannot be represented in the grammar below (such as Infinity and NaN)
11853 > are not permitted.
11854
11855 This description includes both integer and floating-point numbers.
11856 However, C++ allows more precise storage if it is known whether the number
11857 is a signed integer, an unsigned integer or a floating-point number.
11858 Therefore, three different types, @ref number_integer_t, @ref
11859 number_unsigned_t and @ref number_float_t are used.
11860
11861 To store floating-point numbers in C++, a type is defined by the template
11862 parameter @a NumberFloatType which chooses the type to use.
11863
11864 #### Default type
11865
11866 With the default values for @a NumberFloatType (`double`), the default
11867 value for @a number_float_t is:
11868
11869 @code {.cpp}
11870 double
11871 @endcode
11872
11873 #### Default behavior
11874
11875 - The restrictions about leading zeros is not enforced in C++. Instead,
11876 leading zeros in floating-point literals will be ignored. Internally,
11877 the value will be stored as decimal number. For instance, the C++
11878 floating-point literal `01.2` will be serialized to `1.2`. During
11879 deserialization, leading zeros yield an error.
11880 - Not-a-number (NaN) values will be serialized to `null`.
11881
11882 #### Limits
11883
11884 [RFC 7159](http://rfc7159.net/rfc7159) states:
11885 > This specification allows implementations to set limits on the range and
11886 > precision of numbers accepted. Since software that implements IEEE
11887 > 754-2008 binary64 (double precision) numbers is generally available and
11888 > widely used, good interoperability can be achieved by implementations
11889 > that expect no more precision or range than these provide, in the sense
11890 > that implementations will approximate JSON numbers within the expected
11891 > precision.
11892
11893 This implementation does exactly follow this approach, as it uses double
11894 precision floating-point numbers. Note values smaller than
11895 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
11896 will be stored as NaN internally and be serialized to `null`.
11897
11898 #### Storage
11899
11900 Floating-point number values are stored directly inside a @ref basic_json
11901 type.
11902
11903 @sa @ref number_integer_t -- type for number values (integer)
11904
11905 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11906
11907 @since version 1.0.0
11908 */
11909 using number_float_t = NumberFloatType;
11910
11911 /// @}
11912
11913 private:
11914
11915 /// helper for exception-safe object creation
11916 template<typename T, typename... Args>
create(Args &&...args)11917 static T* create(Args&& ... args)
11918 {
11919 AllocatorType<T> alloc;
11920 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
11921
11922 auto deleter = [&](T * object)
11923 {
11924 AllocatorTraits::deallocate(alloc, object, 1);
11925 };
11926 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
11927 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
11928 assert(object != nullptr);
11929 return object.release();
11930 }
11931
11932 ////////////////////////
11933 // JSON value storage //
11934 ////////////////////////
11935
11936 /*!
11937 @brief a JSON value
11938
11939 The actual storage for a JSON value of the @ref basic_json class. This
11940 union combines the different storage types for the JSON value types
11941 defined in @ref value_t.
11942
11943 JSON type | value_t type | used type
11944 --------- | --------------- | ------------------------
11945 object | object | pointer to @ref object_t
11946 array | array | pointer to @ref array_t
11947 string | string | pointer to @ref string_t
11948 boolean | boolean | @ref boolean_t
11949 number | number_integer | @ref number_integer_t
11950 number | number_unsigned | @ref number_unsigned_t
11951 number | number_float | @ref number_float_t
11952 null | null | *no value is stored*
11953
11954 @note Variable-length types (objects, arrays, and strings) are stored as
11955 pointers. The size of the union should not exceed 64 bits if the default
11956 value types are used.
11957
11958 @since version 1.0.0
11959 */
11960 union json_value
11961 {
11962 /// object (stored with pointer to save storage)
11963 object_t* object;
11964 /// array (stored with pointer to save storage)
11965 array_t* array;
11966 /// string (stored with pointer to save storage)
11967 string_t* string;
11968 /// boolean
11969 boolean_t boolean;
11970 /// number (integer)
11971 number_integer_t number_integer;
11972 /// number (unsigned integer)
11973 number_unsigned_t number_unsigned;
11974 /// number (floating-point)
11975 number_float_t number_float;
11976
11977 /// default constructor (for null values)
11978 json_value() = default;
11979 /// constructor for booleans
json_value(boolean_t v)11980 json_value(boolean_t v) noexcept : boolean(v) {}
11981 /// constructor for numbers (integer)
json_value(number_integer_t v)11982 json_value(number_integer_t v) noexcept : number_integer(v) {}
11983 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)11984 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
11985 /// constructor for numbers (floating-point)
json_value(number_float_t v)11986 json_value(number_float_t v) noexcept : number_float(v) {}
11987 /// constructor for empty values of a given type
json_value(value_t t)11988 json_value(value_t t)
11989 {
11990 switch (t)
11991 {
11992 case value_t::object:
11993 {
11994 object = create<object_t>();
11995 break;
11996 }
11997
11998 case value_t::array:
11999 {
12000 array = create<array_t>();
12001 break;
12002 }
12003
12004 case value_t::string:
12005 {
12006 string = create<string_t>("");
12007 break;
12008 }
12009
12010 case value_t::boolean:
12011 {
12012 boolean = boolean_t(false);
12013 break;
12014 }
12015
12016 case value_t::number_integer:
12017 {
12018 number_integer = number_integer_t(0);
12019 break;
12020 }
12021
12022 case value_t::number_unsigned:
12023 {
12024 number_unsigned = number_unsigned_t(0);
12025 break;
12026 }
12027
12028 case value_t::number_float:
12029 {
12030 number_float = number_float_t(0.0);
12031 break;
12032 }
12033
12034 case value_t::null:
12035 {
12036 object = nullptr; // silence warning, see #821
12037 break;
12038 }
12039
12040 default:
12041 {
12042 object = nullptr; // silence warning, see #821
12043 if (JSON_UNLIKELY(t == value_t::null))
12044 {
12045 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.3.0")); // LCOV_EXCL_LINE
12046 }
12047 break;
12048 }
12049 }
12050 }
12051
12052 /// constructor for strings
json_value(const string_t & value)12053 json_value(const string_t& value)
12054 {
12055 string = create<string_t>(value);
12056 }
12057
12058 /// constructor for rvalue strings
json_value(string_t && value)12059 json_value(string_t&& value)
12060 {
12061 string = create<string_t>(std::move(value));
12062 }
12063
12064 /// constructor for objects
json_value(const object_t & value)12065 json_value(const object_t& value)
12066 {
12067 object = create<object_t>(value);
12068 }
12069
12070 /// constructor for rvalue objects
json_value(object_t && value)12071 json_value(object_t&& value)
12072 {
12073 object = create<object_t>(std::move(value));
12074 }
12075
12076 /// constructor for arrays
json_value(const array_t & value)12077 json_value(const array_t& value)
12078 {
12079 array = create<array_t>(value);
12080 }
12081
12082 /// constructor for rvalue arrays
json_value(array_t && value)12083 json_value(array_t&& value)
12084 {
12085 array = create<array_t>(std::move(value));
12086 }
12087
destroy(value_t t)12088 void destroy(value_t t) noexcept
12089 {
12090 switch (t)
12091 {
12092 case value_t::object:
12093 {
12094 AllocatorType<object_t> alloc;
12095 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
12096 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
12097 break;
12098 }
12099
12100 case value_t::array:
12101 {
12102 AllocatorType<array_t> alloc;
12103 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
12104 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
12105 break;
12106 }
12107
12108 case value_t::string:
12109 {
12110 AllocatorType<string_t> alloc;
12111 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
12112 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
12113 break;
12114 }
12115
12116 default:
12117 {
12118 break;
12119 }
12120 }
12121 }
12122 };
12123
12124 /*!
12125 @brief checks the class invariants
12126
12127 This function asserts the class invariants. It needs to be called at the
12128 end of every constructor to make sure that created objects respect the
12129 invariant. Furthermore, it has to be called each time the type of a JSON
12130 value is changed, because the invariant expresses a relationship between
12131 @a m_type and @a m_value.
12132 */
assert_invariant() const12133 void assert_invariant() const noexcept
12134 {
12135 assert(m_type != value_t::object or m_value.object != nullptr);
12136 assert(m_type != value_t::array or m_value.array != nullptr);
12137 assert(m_type != value_t::string or m_value.string != nullptr);
12138 }
12139
12140 public:
12141 //////////////////////////
12142 // JSON parser callback //
12143 //////////////////////////
12144
12145 /*!
12146 @brief parser event types
12147
12148 The parser callback distinguishes the following events:
12149 - `object_start`: the parser read `{` and started to process a JSON object
12150 - `key`: the parser read a key of a value in an object
12151 - `object_end`: the parser read `}` and finished processing a JSON object
12152 - `array_start`: the parser read `[` and started to process a JSON array
12153 - `array_end`: the parser read `]` and finished processing a JSON array
12154 - `value`: the parser finished reading a JSON value
12155
12156 @image html callback_events.png "Example when certain parse events are triggered"
12157
12158 @sa @ref parser_callback_t for more information and examples
12159 */
12160 using parse_event_t = typename parser::parse_event_t;
12161
12162 /*!
12163 @brief per-element parser callback type
12164
12165 With a parser callback function, the result of parsing a JSON text can be
12166 influenced. When passed to @ref parse, it is called on certain events
12167 (passed as @ref parse_event_t via parameter @a event) with a set recursion
12168 depth @a depth and context JSON value @a parsed. The return value of the
12169 callback function is a boolean indicating whether the element that emitted
12170 the callback shall be kept or not.
12171
12172 We distinguish six scenarios (determined by the event type) in which the
12173 callback function can be called. The following table describes the values
12174 of the parameters @a depth, @a event, and @a parsed.
12175
12176 parameter @a event | description | parameter @a depth | parameter @a parsed
12177 ------------------ | ----------- | ------------------ | -------------------
12178 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
12179 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
12180 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
12181 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
12182 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
12183 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
12184
12185 @image html callback_events.png "Example when certain parse events are triggered"
12186
12187 Discarding a value (i.e., returning `false`) has different effects
12188 depending on the context in which function was called:
12189
12190 - Discarded values in structured types are skipped. That is, the parser
12191 will behave as if the discarded value was never read.
12192 - In case a value outside a structured type is skipped, it is replaced
12193 with `null`. This case happens if the top-level element is skipped.
12194
12195 @param[in] depth the depth of the recursion during parsing
12196
12197 @param[in] event an event of type parse_event_t indicating the context in
12198 the callback function has been called
12199
12200 @param[in,out] parsed the current intermediate parse result; note that
12201 writing to this value has no effect for parse_event_t::key events
12202
12203 @return Whether the JSON value which called the function during parsing
12204 should be kept (`true`) or not (`false`). In the latter case, it is either
12205 skipped completely or replaced by an empty discarded object.
12206
12207 @sa @ref parse for examples
12208
12209 @since version 1.0.0
12210 */
12211 using parser_callback_t = typename parser::parser_callback_t;
12212
12213 //////////////////
12214 // constructors //
12215 //////////////////
12216
12217 /// @name constructors and destructors
12218 /// Constructors of class @ref basic_json, copy/move constructor, copy
12219 /// assignment, static functions creating objects, and the destructor.
12220 /// @{
12221
12222 /*!
12223 @brief create an empty value with a given type
12224
12225 Create an empty JSON value with a given type. The value will be default
12226 initialized with an empty value which depends on the type:
12227
12228 Value type | initial value
12229 ----------- | -------------
12230 null | `null`
12231 boolean | `false`
12232 string | `""`
12233 number | `0`
12234 object | `{}`
12235 array | `[]`
12236
12237 @param[in] v the type of the value to create
12238
12239 @complexity Constant.
12240
12241 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12242 changes to any JSON value.
12243
12244 @liveexample{The following code shows the constructor for different @ref
12245 value_t values,basic_json__value_t}
12246
12247 @sa @ref clear() -- restores the postcondition of this constructor
12248
12249 @since version 1.0.0
12250 */
basic_json(const value_t v)12251 basic_json(const value_t v)
12252 : m_type(v), m_value(v)
12253 {
12254 assert_invariant();
12255 }
12256
12257 /*!
12258 @brief create a null object
12259
12260 Create a `null` JSON value. It either takes a null pointer as parameter
12261 (explicitly creating `null`) or no parameter (implicitly creating `null`).
12262 The passed null pointer itself is not read -- it is only used to choose
12263 the right constructor.
12264
12265 @complexity Constant.
12266
12267 @exceptionsafety No-throw guarantee: this constructor never throws
12268 exceptions.
12269
12270 @liveexample{The following code shows the constructor with and without a
12271 null pointer parameter.,basic_json__nullptr_t}
12272
12273 @since version 1.0.0
12274 */
basic_json(std::nullptr_t=nullptr)12275 basic_json(std::nullptr_t = nullptr) noexcept
12276 : basic_json(value_t::null)
12277 {
12278 assert_invariant();
12279 }
12280
12281 /*!
12282 @brief create a JSON value
12283
12284 This is a "catch all" constructor for all compatible JSON types; that is,
12285 types for which a `to_json()` method exists. The constructor forwards the
12286 parameter @a val to that method (to `json_serializer<U>::to_json` method
12287 with `U = uncvref_t<CompatibleType>`, to be exact).
12288
12289 Template type @a CompatibleType includes, but is not limited to, the
12290 following types:
12291 - **arrays**: @ref array_t and all kinds of compatible containers such as
12292 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
12293 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
12294 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
12295 which a @ref basic_json value can be constructed.
12296 - **objects**: @ref object_t and all kinds of compatible associative
12297 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
12298 and `std::unordered_multimap` with a `key_type` compatible to
12299 @ref string_t and a `value_type` from which a @ref basic_json value can
12300 be constructed.
12301 - **strings**: @ref string_t, string literals, and all compatible string
12302 containers can be used.
12303 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
12304 @ref number_float_t, and all convertible number types such as `int`,
12305 `size_t`, `int64_t`, `float` or `double` can be used.
12306 - **boolean**: @ref boolean_t / `bool` can be used.
12307
12308 See the examples below.
12309
12310 @tparam CompatibleType a type such that:
12311 - @a CompatibleType is not derived from `std::istream`,
12312 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
12313 constructors),
12314 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
12315 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
12316 @ref json_pointer, @ref iterator, etc ...)
12317 - @ref @ref json_serializer<U> has a
12318 `to_json(basic_json_t&, CompatibleType&&)` method
12319
12320 @tparam U = `uncvref_t<CompatibleType>`
12321
12322 @param[in] val the value to be forwarded to the respective constructor
12323
12324 @complexity Usually linear in the size of the passed @a val, also
12325 depending on the implementation of the called `to_json()`
12326 method.
12327
12328 @exceptionsafety Depends on the called constructor. For types directly
12329 supported by the library (i.e., all types for which no `to_json()` function
12330 was provided), strong guarantee holds: if an exception is thrown, there are
12331 no changes to any JSON value.
12332
12333 @liveexample{The following code shows the constructor with several
12334 compatible types.,basic_json__CompatibleType}
12335
12336 @since version 2.1.0
12337 */
12338 template <typename CompatibleType,
12339 typename U = detail::uncvref_t<CompatibleType>,
12340 detail::enable_if_t<
12341 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val)12342 basic_json(CompatibleType && val) noexcept(noexcept(
12343 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
12344 std::forward<CompatibleType>(val))))
12345 {
12346 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
12347 assert_invariant();
12348 }
12349
12350 /*!
12351 @brief create a JSON value from an existing one
12352
12353 This is a constructor for existing @ref basic_json types.
12354 It does not hijack copy/move constructors, since the parameter has different
12355 template arguments than the current ones.
12356
12357 The constructor tries to convert the internal @ref m_value of the parameter.
12358
12359 @tparam BasicJsonType a type such that:
12360 - @a BasicJsonType is a @ref basic_json type.
12361 - @a BasicJsonType has different template arguments than @ref basic_json_t.
12362
12363 @param[in] val the @ref basic_json value to be converted.
12364
12365 @complexity Usually linear in the size of the passed @a val, also
12366 depending on the implementation of the called `to_json()`
12367 method.
12368
12369 @exceptionsafety Depends on the called constructor. For types directly
12370 supported by the library (i.e., all types for which no `to_json()` function
12371 was provided), strong guarantee holds: if an exception is thrown, there are
12372 no changes to any JSON value.
12373
12374 @since version 3.2.0
12375 */
12376 template <typename BasicJsonType,
12377 detail::enable_if_t<
12378 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType & val)12379 basic_json(const BasicJsonType& val)
12380 {
12381 using other_boolean_t = typename BasicJsonType::boolean_t;
12382 using other_number_float_t = typename BasicJsonType::number_float_t;
12383 using other_number_integer_t = typename BasicJsonType::number_integer_t;
12384 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12385 using other_string_t = typename BasicJsonType::string_t;
12386 using other_object_t = typename BasicJsonType::object_t;
12387 using other_array_t = typename BasicJsonType::array_t;
12388
12389 switch (val.type())
12390 {
12391 case value_t::boolean:
12392 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
12393 break;
12394 case value_t::number_float:
12395 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
12396 break;
12397 case value_t::number_integer:
12398 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
12399 break;
12400 case value_t::number_unsigned:
12401 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
12402 break;
12403 case value_t::string:
12404 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
12405 break;
12406 case value_t::object:
12407 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
12408 break;
12409 case value_t::array:
12410 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
12411 break;
12412 case value_t::null:
12413 *this = nullptr;
12414 break;
12415 case value_t::discarded:
12416 m_type = value_t::discarded;
12417 break;
12418 }
12419 assert_invariant();
12420 }
12421
12422 /*!
12423 @brief create a container (array or object) from an initializer list
12424
12425 Creates a JSON value of type array or object from the passed initializer
12426 list @a init. In case @a type_deduction is `true` (default), the type of
12427 the JSON value to be created is deducted from the initializer list @a init
12428 according to the following rules:
12429
12430 1. If the list is empty, an empty JSON object value `{}` is created.
12431 2. If the list consists of pairs whose first element is a string, a JSON
12432 object value is created where the first elements of the pairs are
12433 treated as keys and the second elements are as values.
12434 3. In all other cases, an array is created.
12435
12436 The rules aim to create the best fit between a C++ initializer list and
12437 JSON values. The rationale is as follows:
12438
12439 1. The empty initializer list is written as `{}` which is exactly an empty
12440 JSON object.
12441 2. C++ has no way of describing mapped types other than to list a list of
12442 pairs. As JSON requires that keys must be of type string, rule 2 is the
12443 weakest constraint one can pose on initializer lists to interpret them
12444 as an object.
12445 3. In all other cases, the initializer list could not be interpreted as
12446 JSON object type, so interpreting it as JSON array type is safe.
12447
12448 With the rules described above, the following JSON values cannot be
12449 expressed by an initializer list:
12450
12451 - the empty array (`[]`): use @ref array(initializer_list_t)
12452 with an empty initializer list in this case
12453 - arrays whose elements satisfy rule 2: use @ref
12454 array(initializer_list_t) with the same initializer list
12455 in this case
12456
12457 @note When used without parentheses around an empty initializer list, @ref
12458 basic_json() is called instead of this function, yielding the JSON null
12459 value.
12460
12461 @param[in] init initializer list with JSON values
12462
12463 @param[in] type_deduction internal parameter; when set to `true`, the type
12464 of the JSON value is deducted from the initializer list @a init; when set
12465 to `false`, the type provided via @a manual_type is forced. This mode is
12466 used by the functions @ref array(initializer_list_t) and
12467 @ref object(initializer_list_t).
12468
12469 @param[in] manual_type internal parameter; when @a type_deduction is set
12470 to `false`, the created JSON value will use the provided type (only @ref
12471 value_t::array and @ref value_t::object are valid); when @a type_deduction
12472 is set to `true`, this parameter has no effect
12473
12474 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
12475 `value_t::object`, but @a init contains an element which is not a pair
12476 whose first element is a string. In this case, the constructor could not
12477 create an object. If @a type_deduction would have be `true`, an array
12478 would have been created. See @ref object(initializer_list_t)
12479 for an example.
12480
12481 @complexity Linear in the size of the initializer list @a init.
12482
12483 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12484 changes to any JSON value.
12485
12486 @liveexample{The example below shows how JSON values are created from
12487 initializer lists.,basic_json__list_init_t}
12488
12489 @sa @ref array(initializer_list_t) -- create a JSON array
12490 value from an initializer list
12491 @sa @ref object(initializer_list_t) -- create a JSON object
12492 value from an initializer list
12493
12494 @since version 1.0.0
12495 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)12496 basic_json(initializer_list_t init,
12497 bool type_deduction = true,
12498 value_t manual_type = value_t::array)
12499 {
12500 // check if each element is an array with two elements whose first
12501 // element is a string
12502 bool is_an_object = std::all_of(init.begin(), init.end(),
12503 [](const detail::json_ref<basic_json>& element_ref)
12504 {
12505 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
12506 });
12507
12508 // adjust type if type deduction is not wanted
12509 if (not type_deduction)
12510 {
12511 // if array is wanted, do not create an object though possible
12512 if (manual_type == value_t::array)
12513 {
12514 is_an_object = false;
12515 }
12516
12517 // if object is wanted but impossible, throw an exception
12518 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
12519 {
12520 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
12521 }
12522 }
12523
12524 if (is_an_object)
12525 {
12526 // the initializer list is a list of pairs -> create object
12527 m_type = value_t::object;
12528 m_value = value_t::object;
12529
12530 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
12531 {
12532 auto element = element_ref.moved_or_copied();
12533 m_value.object->emplace(
12534 std::move(*((*element.m_value.array)[0].m_value.string)),
12535 std::move((*element.m_value.array)[1]));
12536 });
12537 }
12538 else
12539 {
12540 // the initializer list describes an array -> create array
12541 m_type = value_t::array;
12542 m_value.array = create<array_t>(init.begin(), init.end());
12543 }
12544
12545 assert_invariant();
12546 }
12547
12548 /*!
12549 @brief explicitly create an array from an initializer list
12550
12551 Creates a JSON array value from a given initializer list. That is, given a
12552 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
12553 initializer list is empty, the empty array `[]` is created.
12554
12555 @note This function is only needed to express two edge cases that cannot
12556 be realized with the initializer list constructor (@ref
12557 basic_json(initializer_list_t, bool, value_t)). These cases
12558 are:
12559 1. creating an array whose elements are all pairs whose first element is a
12560 string -- in this case, the initializer list constructor would create an
12561 object, taking the first elements as keys
12562 2. creating an empty array -- passing the empty initializer list to the
12563 initializer list constructor yields an empty object
12564
12565 @param[in] init initializer list with JSON values to create an array from
12566 (optional)
12567
12568 @return JSON array value
12569
12570 @complexity Linear in the size of @a init.
12571
12572 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12573 changes to any JSON value.
12574
12575 @liveexample{The following code shows an example for the `array`
12576 function.,array}
12577
12578 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12579 create a JSON value from an initializer list
12580 @sa @ref object(initializer_list_t) -- create a JSON object
12581 value from an initializer list
12582
12583 @since version 1.0.0
12584 */
array(initializer_list_t init={})12585 static basic_json array(initializer_list_t init = {})
12586 {
12587 return basic_json(init, false, value_t::array);
12588 }
12589
12590 /*!
12591 @brief explicitly create an object from an initializer list
12592
12593 Creates a JSON object value from a given initializer list. The initializer
12594 lists elements must be pairs, and their first elements must be strings. If
12595 the initializer list is empty, the empty object `{}` is created.
12596
12597 @note This function is only added for symmetry reasons. In contrast to the
12598 related function @ref array(initializer_list_t), there are
12599 no cases which can only be expressed by this function. That is, any
12600 initializer list @a init can also be passed to the initializer list
12601 constructor @ref basic_json(initializer_list_t, bool, value_t).
12602
12603 @param[in] init initializer list to create an object from (optional)
12604
12605 @return JSON object value
12606
12607 @throw type_error.301 if @a init is not a list of pairs whose first
12608 elements are strings. In this case, no object can be created. When such a
12609 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
12610 an array would have been created from the passed initializer list @a init.
12611 See example below.
12612
12613 @complexity Linear in the size of @a init.
12614
12615 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12616 changes to any JSON value.
12617
12618 @liveexample{The following code shows an example for the `object`
12619 function.,object}
12620
12621 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12622 create a JSON value from an initializer list
12623 @sa @ref array(initializer_list_t) -- create a JSON array
12624 value from an initializer list
12625
12626 @since version 1.0.0
12627 */
object(initializer_list_t init={})12628 static basic_json object(initializer_list_t init = {})
12629 {
12630 return basic_json(init, false, value_t::object);
12631 }
12632
12633 /*!
12634 @brief construct an array with count copies of given value
12635
12636 Constructs a JSON array value by creating @a cnt copies of a passed value.
12637 In case @a cnt is `0`, an empty array is created.
12638
12639 @param[in] cnt the number of JSON copies of @a val to create
12640 @param[in] val the JSON value to copy
12641
12642 @post `std::distance(begin(),end()) == cnt` holds.
12643
12644 @complexity Linear in @a cnt.
12645
12646 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12647 changes to any JSON value.
12648
12649 @liveexample{The following code shows examples for the @ref
12650 basic_json(size_type\, const basic_json&)
12651 constructor.,basic_json__size_type_basic_json}
12652
12653 @since version 1.0.0
12654 */
basic_json(size_type cnt,const basic_json & val)12655 basic_json(size_type cnt, const basic_json& val)
12656 : m_type(value_t::array)
12657 {
12658 m_value.array = create<array_t>(cnt, val);
12659 assert_invariant();
12660 }
12661
12662 /*!
12663 @brief construct a JSON container given an iterator range
12664
12665 Constructs the JSON value with the contents of the range `[first, last)`.
12666 The semantics depends on the different types a JSON value can have:
12667 - In case of a null type, invalid_iterator.206 is thrown.
12668 - In case of other primitive types (number, boolean, or string), @a first
12669 must be `begin()` and @a last must be `end()`. In this case, the value is
12670 copied. Otherwise, invalid_iterator.204 is thrown.
12671 - In case of structured types (array, object), the constructor behaves as
12672 similar versions for `std::vector` or `std::map`; that is, a JSON array
12673 or object is constructed from the values in the range.
12674
12675 @tparam InputIT an input iterator type (@ref iterator or @ref
12676 const_iterator)
12677
12678 @param[in] first begin of the range to copy from (included)
12679 @param[in] last end of the range to copy from (excluded)
12680
12681 @pre Iterators @a first and @a last must be initialized. **This
12682 precondition is enforced with an assertion (see warning).** If
12683 assertions are switched off, a violation of this precondition yields
12684 undefined behavior.
12685
12686 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
12687 checked efficiently. Only certain edge cases are detected; see the
12688 description of the exceptions below. A violation of this precondition
12689 yields undefined behavior.
12690
12691 @warning A precondition is enforced with a runtime assertion that will
12692 result in calling `std::abort` if this precondition is not met.
12693 Assertions can be disabled by defining `NDEBUG` at compile time.
12694 See https://en.cppreference.com/w/cpp/error/assert for more
12695 information.
12696
12697 @throw invalid_iterator.201 if iterators @a first and @a last are not
12698 compatible (i.e., do not belong to the same JSON value). In this case,
12699 the range `[first, last)` is undefined.
12700 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
12701 primitive type (number, boolean, or string), but @a first does not point
12702 to the first element any more. In this case, the range `[first, last)` is
12703 undefined. See example code below.
12704 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
12705 null value. In this case, the range `[first, last)` is undefined.
12706
12707 @complexity Linear in distance between @a first and @a last.
12708
12709 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12710 changes to any JSON value.
12711
12712 @liveexample{The example below shows several ways to create JSON values by
12713 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
12714
12715 @since version 1.0.0
12716 */
12717 template<class InputIT, typename std::enable_if<
12718 std::is_same<InputIT, typename basic_json_t::iterator>::value or
12719 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)12720 basic_json(InputIT first, InputIT last)
12721 {
12722 assert(first.m_object != nullptr);
12723 assert(last.m_object != nullptr);
12724
12725 // make sure iterator fits the current value
12726 if (JSON_UNLIKELY(first.m_object != last.m_object))
12727 {
12728 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
12729 }
12730
12731 // copy type from first iterator
12732 m_type = first.m_object->m_type;
12733
12734 // check if iterator range is complete for primitive values
12735 switch (m_type)
12736 {
12737 case value_t::boolean:
12738 case value_t::number_float:
12739 case value_t::number_integer:
12740 case value_t::number_unsigned:
12741 case value_t::string:
12742 {
12743 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
12744 or not last.m_it.primitive_iterator.is_end()))
12745 {
12746 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
12747 }
12748 break;
12749 }
12750
12751 default:
12752 break;
12753 }
12754
12755 switch (m_type)
12756 {
12757 case value_t::number_integer:
12758 {
12759 m_value.number_integer = first.m_object->m_value.number_integer;
12760 break;
12761 }
12762
12763 case value_t::number_unsigned:
12764 {
12765 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
12766 break;
12767 }
12768
12769 case value_t::number_float:
12770 {
12771 m_value.number_float = first.m_object->m_value.number_float;
12772 break;
12773 }
12774
12775 case value_t::boolean:
12776 {
12777 m_value.boolean = first.m_object->m_value.boolean;
12778 break;
12779 }
12780
12781 case value_t::string:
12782 {
12783 m_value = *first.m_object->m_value.string;
12784 break;
12785 }
12786
12787 case value_t::object:
12788 {
12789 m_value.object = create<object_t>(first.m_it.object_iterator,
12790 last.m_it.object_iterator);
12791 break;
12792 }
12793
12794 case value_t::array:
12795 {
12796 m_value.array = create<array_t>(first.m_it.array_iterator,
12797 last.m_it.array_iterator);
12798 break;
12799 }
12800
12801 default:
12802 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
12803 std::string(first.m_object->type_name())));
12804 }
12805
12806 assert_invariant();
12807 }
12808
12809
12810 ///////////////////////////////////////
12811 // other constructors and destructor //
12812 ///////////////////////////////////////
12813
12814 /// @private
basic_json(const detail::json_ref<basic_json> & ref)12815 basic_json(const detail::json_ref<basic_json>& ref)
12816 : basic_json(ref.moved_or_copied())
12817 {}
12818
12819 /*!
12820 @brief copy constructor
12821
12822 Creates a copy of a given JSON value.
12823
12824 @param[in] other the JSON value to copy
12825
12826 @post `*this == other`
12827
12828 @complexity Linear in the size of @a other.
12829
12830 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12831 changes to any JSON value.
12832
12833 @requirement This function helps `basic_json` satisfying the
12834 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12835 requirements:
12836 - The complexity is linear.
12837 - As postcondition, it holds: `other == basic_json(other)`.
12838
12839 @liveexample{The following code shows an example for the copy
12840 constructor.,basic_json__basic_json}
12841
12842 @since version 1.0.0
12843 */
basic_json(const basic_json & other)12844 basic_json(const basic_json& other)
12845 : m_type(other.m_type)
12846 {
12847 // check of passed value is valid
12848 other.assert_invariant();
12849
12850 switch (m_type)
12851 {
12852 case value_t::object:
12853 {
12854 m_value = *other.m_value.object;
12855 break;
12856 }
12857
12858 case value_t::array:
12859 {
12860 m_value = *other.m_value.array;
12861 break;
12862 }
12863
12864 case value_t::string:
12865 {
12866 m_value = *other.m_value.string;
12867 break;
12868 }
12869
12870 case value_t::boolean:
12871 {
12872 m_value = other.m_value.boolean;
12873 break;
12874 }
12875
12876 case value_t::number_integer:
12877 {
12878 m_value = other.m_value.number_integer;
12879 break;
12880 }
12881
12882 case value_t::number_unsigned:
12883 {
12884 m_value = other.m_value.number_unsigned;
12885 break;
12886 }
12887
12888 case value_t::number_float:
12889 {
12890 m_value = other.m_value.number_float;
12891 break;
12892 }
12893
12894 default:
12895 break;
12896 }
12897
12898 assert_invariant();
12899 }
12900
12901 /*!
12902 @brief move constructor
12903
12904 Move constructor. Constructs a JSON value with the contents of the given
12905 value @a other using move semantics. It "steals" the resources from @a
12906 other and leaves it as JSON null value.
12907
12908 @param[in,out] other value to move to this object
12909
12910 @post `*this` has the same value as @a other before the call.
12911 @post @a other is a JSON null value.
12912
12913 @complexity Constant.
12914
12915 @exceptionsafety No-throw guarantee: this constructor never throws
12916 exceptions.
12917
12918 @requirement This function helps `basic_json` satisfying the
12919 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
12920 requirements.
12921
12922 @liveexample{The code below shows the move constructor explicitly called
12923 via std::move.,basic_json__moveconstructor}
12924
12925 @since version 1.0.0
12926 */
basic_json(basic_json && other)12927 basic_json(basic_json&& other) noexcept
12928 : m_type(std::move(other.m_type)),
12929 m_value(std::move(other.m_value))
12930 {
12931 // check that passed value is valid
12932 other.assert_invariant();
12933
12934 // invalidate payload
12935 other.m_type = value_t::null;
12936 other.m_value = {};
12937
12938 assert_invariant();
12939 }
12940
12941 /*!
12942 @brief copy assignment
12943
12944 Copy assignment operator. Copies a JSON value via the "copy and swap"
12945 strategy: It is expressed in terms of the copy constructor, destructor,
12946 and the `swap()` member function.
12947
12948 @param[in] other value to copy from
12949
12950 @complexity Linear.
12951
12952 @requirement This function helps `basic_json` satisfying the
12953 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12954 requirements:
12955 - The complexity is linear.
12956
12957 @liveexample{The code below shows and example for the copy assignment. It
12958 creates a copy of value `a` which is then swapped with `b`. Finally\, the
12959 copy of `a` (which is the null value after the swap) is
12960 destroyed.,basic_json__copyassignment}
12961
12962 @since version 1.0.0
12963 */
operator =(basic_json other)12964 reference& operator=(basic_json other) noexcept (
12965 std::is_nothrow_move_constructible<value_t>::value and
12966 std::is_nothrow_move_assignable<value_t>::value and
12967 std::is_nothrow_move_constructible<json_value>::value and
12968 std::is_nothrow_move_assignable<json_value>::value
12969 )
12970 {
12971 // check that passed value is valid
12972 other.assert_invariant();
12973
12974 using std::swap;
12975 swap(m_type, other.m_type);
12976 swap(m_value, other.m_value);
12977
12978 assert_invariant();
12979 return *this;
12980 }
12981
12982 /*!
12983 @brief destructor
12984
12985 Destroys the JSON value and frees all allocated memory.
12986
12987 @complexity Linear.
12988
12989 @requirement This function helps `basic_json` satisfying the
12990 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12991 requirements:
12992 - The complexity is linear.
12993 - All stored elements are destroyed and all memory is freed.
12994
12995 @since version 1.0.0
12996 */
~basic_json()12997 ~basic_json() noexcept
12998 {
12999 assert_invariant();
13000 m_value.destroy(m_type);
13001 }
13002
13003 /// @}
13004
13005 public:
13006 ///////////////////////
13007 // object inspection //
13008 ///////////////////////
13009
13010 /// @name object inspection
13011 /// Functions to inspect the type of a JSON value.
13012 /// @{
13013
13014 /*!
13015 @brief serialization
13016
13017 Serialization function for JSON values. The function tries to mimic
13018 Python's `json.dumps()` function, and currently supports its @a indent
13019 and @a ensure_ascii parameters.
13020
13021 @param[in] indent If indent is nonnegative, then array elements and object
13022 members will be pretty-printed with that indent level. An indent level of
13023 `0` will only insert newlines. `-1` (the default) selects the most compact
13024 representation.
13025 @param[in] indent_char The character to use for indentation if @a indent is
13026 greater than `0`. The default is ` ` (space).
13027 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
13028 in the output are escaped with `\uXXXX` sequences, and the result consists
13029 of ASCII characters only.
13030
13031 @return string containing the serialization of the JSON value
13032
13033 @throw type_error.316 if a string stored inside the JSON value is not
13034 UTF-8 encoded
13035
13036 @complexity Linear.
13037
13038 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13039 changes in the JSON value.
13040
13041 @liveexample{The following example shows the effect of different @a indent\,
13042 @a indent_char\, and @a ensure_ascii parameters to the result of the
13043 serialization.,dump}
13044
13045 @see https://docs.python.org/2/library/json.html#json.dump
13046
13047 @since version 1.0.0; indentation character @a indent_char, option
13048 @a ensure_ascii and exceptions added in version 3.0.0
13049 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false) const13050 string_t dump(const int indent = -1, const char indent_char = ' ',
13051 const bool ensure_ascii = false) const
13052 {
13053 string_t result;
13054 serializer s(detail::output_adapter<char, string_t>(result), indent_char);
13055
13056 if (indent >= 0)
13057 {
13058 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
13059 }
13060 else
13061 {
13062 s.dump(*this, false, ensure_ascii, 0);
13063 }
13064
13065 return result;
13066 }
13067
13068 /*!
13069 @brief return the type of the JSON value (explicit)
13070
13071 Return the type of the JSON value as a value from the @ref value_t
13072 enumeration.
13073
13074 @return the type of the JSON value
13075 Value type | return value
13076 ------------------------- | -------------------------
13077 null | value_t::null
13078 boolean | value_t::boolean
13079 string | value_t::string
13080 number (integer) | value_t::number_integer
13081 number (unsigned integer) | value_t::number_unsigned
13082 number (floating-point) | value_t::number_float
13083 object | value_t::object
13084 array | value_t::array
13085 discarded | value_t::discarded
13086
13087 @complexity Constant.
13088
13089 @exceptionsafety No-throw guarantee: this member function never throws
13090 exceptions.
13091
13092 @liveexample{The following code exemplifies `type()` for all JSON
13093 types.,type}
13094
13095 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
13096 @sa @ref type_name() -- return the type as string
13097
13098 @since version 1.0.0
13099 */
type() const13100 constexpr value_t type() const noexcept
13101 {
13102 return m_type;
13103 }
13104
13105 /*!
13106 @brief return whether type is primitive
13107
13108 This function returns true if and only if the JSON type is primitive
13109 (string, number, boolean, or null).
13110
13111 @return `true` if type is primitive (string, number, boolean, or null),
13112 `false` otherwise.
13113
13114 @complexity Constant.
13115
13116 @exceptionsafety No-throw guarantee: this member function never throws
13117 exceptions.
13118
13119 @liveexample{The following code exemplifies `is_primitive()` for all JSON
13120 types.,is_primitive}
13121
13122 @sa @ref is_structured() -- returns whether JSON value is structured
13123 @sa @ref is_null() -- returns whether JSON value is `null`
13124 @sa @ref is_string() -- returns whether JSON value is a string
13125 @sa @ref is_boolean() -- returns whether JSON value is a boolean
13126 @sa @ref is_number() -- returns whether JSON value is a number
13127
13128 @since version 1.0.0
13129 */
is_primitive() const13130 constexpr bool is_primitive() const noexcept
13131 {
13132 return is_null() or is_string() or is_boolean() or is_number();
13133 }
13134
13135 /*!
13136 @brief return whether type is structured
13137
13138 This function returns true if and only if the JSON type is structured
13139 (array or object).
13140
13141 @return `true` if type is structured (array or object), `false` otherwise.
13142
13143 @complexity Constant.
13144
13145 @exceptionsafety No-throw guarantee: this member function never throws
13146 exceptions.
13147
13148 @liveexample{The following code exemplifies `is_structured()` for all JSON
13149 types.,is_structured}
13150
13151 @sa @ref is_primitive() -- returns whether value is primitive
13152 @sa @ref is_array() -- returns whether value is an array
13153 @sa @ref is_object() -- returns whether value is an object
13154
13155 @since version 1.0.0
13156 */
is_structured() const13157 constexpr bool is_structured() const noexcept
13158 {
13159 return is_array() or is_object();
13160 }
13161
13162 /*!
13163 @brief return whether value is null
13164
13165 This function returns true if and only if the JSON value is null.
13166
13167 @return `true` if type is null, `false` otherwise.
13168
13169 @complexity Constant.
13170
13171 @exceptionsafety No-throw guarantee: this member function never throws
13172 exceptions.
13173
13174 @liveexample{The following code exemplifies `is_null()` for all JSON
13175 types.,is_null}
13176
13177 @since version 1.0.0
13178 */
is_null() const13179 constexpr bool is_null() const noexcept
13180 {
13181 return (m_type == value_t::null);
13182 }
13183
13184 /*!
13185 @brief return whether value is a boolean
13186
13187 This function returns true if and only if the JSON value is a boolean.
13188
13189 @return `true` if type is boolean, `false` otherwise.
13190
13191 @complexity Constant.
13192
13193 @exceptionsafety No-throw guarantee: this member function never throws
13194 exceptions.
13195
13196 @liveexample{The following code exemplifies `is_boolean()` for all JSON
13197 types.,is_boolean}
13198
13199 @since version 1.0.0
13200 */
is_boolean() const13201 constexpr bool is_boolean() const noexcept
13202 {
13203 return (m_type == value_t::boolean);
13204 }
13205
13206 /*!
13207 @brief return whether value is a number
13208
13209 This function returns true if and only if the JSON value is a number. This
13210 includes both integer (signed and unsigned) and floating-point values.
13211
13212 @return `true` if type is number (regardless whether integer, unsigned
13213 integer or floating-type), `false` otherwise.
13214
13215 @complexity Constant.
13216
13217 @exceptionsafety No-throw guarantee: this member function never throws
13218 exceptions.
13219
13220 @liveexample{The following code exemplifies `is_number()` for all JSON
13221 types.,is_number}
13222
13223 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13224 integer number
13225 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13226 number
13227 @sa @ref is_number_float() -- check if value is a floating-point number
13228
13229 @since version 1.0.0
13230 */
is_number() const13231 constexpr bool is_number() const noexcept
13232 {
13233 return is_number_integer() or is_number_float();
13234 }
13235
13236 /*!
13237 @brief return whether value is an integer number
13238
13239 This function returns true if and only if the JSON value is a signed or
13240 unsigned integer number. This excludes floating-point values.
13241
13242 @return `true` if type is an integer or unsigned integer number, `false`
13243 otherwise.
13244
13245 @complexity Constant.
13246
13247 @exceptionsafety No-throw guarantee: this member function never throws
13248 exceptions.
13249
13250 @liveexample{The following code exemplifies `is_number_integer()` for all
13251 JSON types.,is_number_integer}
13252
13253 @sa @ref is_number() -- check if value is a number
13254 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13255 number
13256 @sa @ref is_number_float() -- check if value is a floating-point number
13257
13258 @since version 1.0.0
13259 */
is_number_integer() const13260 constexpr bool is_number_integer() const noexcept
13261 {
13262 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
13263 }
13264
13265 /*!
13266 @brief return whether value is an unsigned integer number
13267
13268 This function returns true if and only if the JSON value is an unsigned
13269 integer number. This excludes floating-point and signed integer values.
13270
13271 @return `true` if type is an unsigned integer number, `false` otherwise.
13272
13273 @complexity Constant.
13274
13275 @exceptionsafety No-throw guarantee: this member function never throws
13276 exceptions.
13277
13278 @liveexample{The following code exemplifies `is_number_unsigned()` for all
13279 JSON types.,is_number_unsigned}
13280
13281 @sa @ref is_number() -- check if value is a number
13282 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13283 integer number
13284 @sa @ref is_number_float() -- check if value is a floating-point number
13285
13286 @since version 2.0.0
13287 */
is_number_unsigned() const13288 constexpr bool is_number_unsigned() const noexcept
13289 {
13290 return (m_type == value_t::number_unsigned);
13291 }
13292
13293 /*!
13294 @brief return whether value is a floating-point number
13295
13296 This function returns true if and only if the JSON value is a
13297 floating-point number. This excludes signed and unsigned integer values.
13298
13299 @return `true` if type is a floating-point number, `false` otherwise.
13300
13301 @complexity Constant.
13302
13303 @exceptionsafety No-throw guarantee: this member function never throws
13304 exceptions.
13305
13306 @liveexample{The following code exemplifies `is_number_float()` for all
13307 JSON types.,is_number_float}
13308
13309 @sa @ref is_number() -- check if value is number
13310 @sa @ref is_number_integer() -- check if value is an integer number
13311 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13312 number
13313
13314 @since version 1.0.0
13315 */
is_number_float() const13316 constexpr bool is_number_float() const noexcept
13317 {
13318 return (m_type == value_t::number_float);
13319 }
13320
13321 /*!
13322 @brief return whether value is an object
13323
13324 This function returns true if and only if the JSON value is an object.
13325
13326 @return `true` if type is object, `false` otherwise.
13327
13328 @complexity Constant.
13329
13330 @exceptionsafety No-throw guarantee: this member function never throws
13331 exceptions.
13332
13333 @liveexample{The following code exemplifies `is_object()` for all JSON
13334 types.,is_object}
13335
13336 @since version 1.0.0
13337 */
is_object() const13338 constexpr bool is_object() const noexcept
13339 {
13340 return (m_type == value_t::object);
13341 }
13342
13343 /*!
13344 @brief return whether value is an array
13345
13346 This function returns true if and only if the JSON value is an array.
13347
13348 @return `true` if type is array, `false` otherwise.
13349
13350 @complexity Constant.
13351
13352 @exceptionsafety No-throw guarantee: this member function never throws
13353 exceptions.
13354
13355 @liveexample{The following code exemplifies `is_array()` for all JSON
13356 types.,is_array}
13357
13358 @since version 1.0.0
13359 */
is_array() const13360 constexpr bool is_array() const noexcept
13361 {
13362 return (m_type == value_t::array);
13363 }
13364
13365 /*!
13366 @brief return whether value is a string
13367
13368 This function returns true if and only if the JSON value is a string.
13369
13370 @return `true` if type is string, `false` otherwise.
13371
13372 @complexity Constant.
13373
13374 @exceptionsafety No-throw guarantee: this member function never throws
13375 exceptions.
13376
13377 @liveexample{The following code exemplifies `is_string()` for all JSON
13378 types.,is_string}
13379
13380 @since version 1.0.0
13381 */
is_string() const13382 constexpr bool is_string() const noexcept
13383 {
13384 return (m_type == value_t::string);
13385 }
13386
13387 /*!
13388 @brief return whether value is discarded
13389
13390 This function returns true if and only if the JSON value was discarded
13391 during parsing with a callback function (see @ref parser_callback_t).
13392
13393 @note This function will always be `false` for JSON values after parsing.
13394 That is, discarded values can only occur during parsing, but will be
13395 removed when inside a structured value or replaced by null in other cases.
13396
13397 @return `true` if type is discarded, `false` otherwise.
13398
13399 @complexity Constant.
13400
13401 @exceptionsafety No-throw guarantee: this member function never throws
13402 exceptions.
13403
13404 @liveexample{The following code exemplifies `is_discarded()` for all JSON
13405 types.,is_discarded}
13406
13407 @since version 1.0.0
13408 */
is_discarded() const13409 constexpr bool is_discarded() const noexcept
13410 {
13411 return (m_type == value_t::discarded);
13412 }
13413
13414 /*!
13415 @brief return the type of the JSON value (implicit)
13416
13417 Implicitly return the type of the JSON value as a value from the @ref
13418 value_t enumeration.
13419
13420 @return the type of the JSON value
13421
13422 @complexity Constant.
13423
13424 @exceptionsafety No-throw guarantee: this member function never throws
13425 exceptions.
13426
13427 @liveexample{The following code exemplifies the @ref value_t operator for
13428 all JSON types.,operator__value_t}
13429
13430 @sa @ref type() -- return the type of the JSON value (explicit)
13431 @sa @ref type_name() -- return the type as string
13432
13433 @since version 1.0.0
13434 */
operator value_t() const13435 constexpr operator value_t() const noexcept
13436 {
13437 return m_type;
13438 }
13439
13440 /// @}
13441
13442 private:
13443 //////////////////
13444 // value access //
13445 //////////////////
13446
13447 /// get a boolean (explicit)
get_impl(boolean_t *) const13448 boolean_t get_impl(boolean_t* /*unused*/) const
13449 {
13450 if (JSON_LIKELY(is_boolean()))
13451 {
13452 return m_value.boolean;
13453 }
13454
13455 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
13456 }
13457
13458 /// get a pointer to the value (object)
get_impl_ptr(object_t *)13459 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
13460 {
13461 return is_object() ? m_value.object : nullptr;
13462 }
13463
13464 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const13465 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
13466 {
13467 return is_object() ? m_value.object : nullptr;
13468 }
13469
13470 /// get a pointer to the value (array)
get_impl_ptr(array_t *)13471 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
13472 {
13473 return is_array() ? m_value.array : nullptr;
13474 }
13475
13476 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const13477 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
13478 {
13479 return is_array() ? m_value.array : nullptr;
13480 }
13481
13482 /// get a pointer to the value (string)
get_impl_ptr(string_t *)13483 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
13484 {
13485 return is_string() ? m_value.string : nullptr;
13486 }
13487
13488 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const13489 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
13490 {
13491 return is_string() ? m_value.string : nullptr;
13492 }
13493
13494 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)13495 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
13496 {
13497 return is_boolean() ? &m_value.boolean : nullptr;
13498 }
13499
13500 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const13501 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
13502 {
13503 return is_boolean() ? &m_value.boolean : nullptr;
13504 }
13505
13506 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)13507 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
13508 {
13509 return is_number_integer() ? &m_value.number_integer : nullptr;
13510 }
13511
13512 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const13513 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
13514 {
13515 return is_number_integer() ? &m_value.number_integer : nullptr;
13516 }
13517
13518 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)13519 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
13520 {
13521 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13522 }
13523
13524 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const13525 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
13526 {
13527 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13528 }
13529
13530 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)13531 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
13532 {
13533 return is_number_float() ? &m_value.number_float : nullptr;
13534 }
13535
13536 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const13537 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
13538 {
13539 return is_number_float() ? &m_value.number_float : nullptr;
13540 }
13541
13542 /*!
13543 @brief helper function to implement get_ref()
13544
13545 This function helps to implement get_ref() without code duplication for
13546 const and non-const overloads
13547
13548 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
13549
13550 @throw type_error.303 if ReferenceType does not match underlying value
13551 type of the current JSON
13552 */
13553 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)13554 static ReferenceType get_ref_impl(ThisType& obj)
13555 {
13556 // delegate the call to get_ptr<>()
13557 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
13558
13559 if (JSON_LIKELY(ptr != nullptr))
13560 {
13561 return *ptr;
13562 }
13563
13564 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
13565 }
13566
13567 public:
13568 /// @name value access
13569 /// Direct access to the stored value of a JSON value.
13570 /// @{
13571
13572 /*!
13573 @brief get special-case overload
13574
13575 This overloads avoids a lot of template boilerplate, it can be seen as the
13576 identity method
13577
13578 @tparam BasicJsonType == @ref basic_json
13579
13580 @return a copy of *this
13581
13582 @complexity Constant.
13583
13584 @since version 2.1.0
13585 */
13586 template<typename BasicJsonType, detail::enable_if_t<
13587 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
13588 int> = 0>
get() const13589 basic_json get() const
13590 {
13591 return *this;
13592 }
13593
13594 /*!
13595 @brief get special-case overload
13596
13597 This overloads converts the current @ref basic_json in a different
13598 @ref basic_json type
13599
13600 @tparam BasicJsonType == @ref basic_json
13601
13602 @return a copy of *this, converted into @tparam BasicJsonType
13603
13604 @complexity Depending on the implementation of the called `from_json()`
13605 method.
13606
13607 @since version 3.2.0
13608 */
13609 template<typename BasicJsonType, detail::enable_if_t<
13610 not std::is_same<BasicJsonType, basic_json>::value and
13611 detail::is_basic_json<BasicJsonType>::value, int> = 0>
13612 BasicJsonType get() const
13613 {
13614 return *this;
13615 }
13616
13617 /*!
13618 @brief get a value (explicit)
13619
13620 Explicit type conversion between the JSON value and a compatible value
13621 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13622 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13623 The value is converted by calling the @ref json_serializer<ValueType>
13624 `from_json()` method.
13625
13626 The function is equivalent to executing
13627 @code {.cpp}
13628 ValueType ret;
13629 JSONSerializer<ValueType>::from_json(*this, ret);
13630 return ret;
13631 @endcode
13632
13633 This overloads is chosen if:
13634 - @a ValueType is not @ref basic_json,
13635 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13636 `void from_json(const basic_json&, ValueType&)`, and
13637 - @ref json_serializer<ValueType> does not have a `from_json()` method of
13638 the form `ValueType from_json(const basic_json&)`
13639
13640 @tparam ValueTypeCV the provided value type
13641 @tparam ValueType the returned value type
13642
13643 @return copy of the JSON value, converted to @a ValueType
13644
13645 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13646
13647 @liveexample{The example below shows several conversions from JSON values
13648 to other types. There a few things to note: (1) Floating-point numbers can
13649 be converted to integers\, (2) A JSON array can be converted to a standard
13650 `std::vector<short>`\, (3) A JSON object can be converted to C++
13651 associative containers such as `std::unordered_map<std::string\,
13652 json>`.,get__ValueType_const}
13653
13654 @since version 2.1.0
13655 */
13656 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13657 detail::enable_if_t <
13658 not detail::is_basic_json<ValueType>::value and
13659 detail::has_from_json<basic_json_t, ValueType>::value and
13660 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13661 int> = 0>
13662 ValueType get() const noexcept(noexcept(
13663 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
13664 {
13665 // we cannot static_assert on ValueTypeCV being non-const, because
13666 // there is support for get<const basic_json_t>(), which is why we
13667 // still need the uncvref
13668 static_assert(not std::is_reference<ValueTypeCV>::value,
13669 "get() cannot be used with reference types, you might want to use get_ref()");
13670 static_assert(std::is_default_constructible<ValueType>::value,
13671 "types must be DefaultConstructible when used with get()");
13672
13673 ValueType ret;
13674 JSONSerializer<ValueType>::from_json(*this, ret);
13675 return ret;
13676 }
13677
13678 /*!
13679 @brief get a value (explicit); special case
13680
13681 Explicit type conversion between the JSON value and a compatible value
13682 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13683 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13684 The value is converted by calling the @ref json_serializer<ValueType>
13685 `from_json()` method.
13686
13687 The function is equivalent to executing
13688 @code {.cpp}
13689 return JSONSerializer<ValueTypeCV>::from_json(*this);
13690 @endcode
13691
13692 This overloads is chosen if:
13693 - @a ValueType is not @ref basic_json and
13694 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13695 `ValueType from_json(const basic_json&)`
13696
13697 @note If @ref json_serializer<ValueType> has both overloads of
13698 `from_json()`, this one is chosen.
13699
13700 @tparam ValueTypeCV the provided value type
13701 @tparam ValueType the returned value type
13702
13703 @return copy of the JSON value, converted to @a ValueType
13704
13705 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13706
13707 @since version 2.1.0
13708 */
13709 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13710 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
13711 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13712 int> = 0>
13713 ValueType get() const noexcept(noexcept(
13714 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
13715 {
13716 static_assert(not std::is_reference<ValueTypeCV>::value,
13717 "get() cannot be used with reference types, you might want to use get_ref()");
13718 return JSONSerializer<ValueTypeCV>::from_json(*this);
13719 }
13720
13721 /*!
13722 @brief get a value (explicit)
13723
13724 Explicit type conversion between the JSON value and a compatible value.
13725 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
13726 `from_json()` method.
13727
13728 The function is equivalent to executing
13729 @code {.cpp}
13730 ValueType v;
13731 JSONSerializer<ValueType>::from_json(*this, v);
13732 @endcode
13733
13734 This overloads is chosen if:
13735 - @a ValueType is not @ref basic_json,
13736 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13737 `void from_json(const basic_json&, ValueType&)`, and
13738
13739 @tparam ValueType the input parameter type.
13740
13741 @return the input parameter, allowing chaining calls.
13742
13743 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13744
13745 @liveexample{The example below shows several conversions from JSON values
13746 to other types. There a few things to note: (1) Floating-point numbers can
13747 be converted to integers\, (2) A JSON array can be converted to a standard
13748 `std::vector<short>`\, (3) A JSON object can be converted to C++
13749 associative containers such as `std::unordered_map<std::string\,
13750 json>`.,get_to}
13751
13752 @since version 3.3.0
13753 */
13754 template<typename ValueType,
13755 detail::enable_if_t <
13756 not detail::is_basic_json<ValueType>::value and
13757 detail::has_from_json<basic_json_t, ValueType>::value,
13758 int> = 0>
13759 ValueType & get_to(ValueType& v) const noexcept(noexcept(
13760 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
13761 {
13762 JSONSerializer<ValueType>::from_json(*this, v);
13763 return v;
13764 }
13765
13766
13767 /*!
13768 @brief get a pointer value (implicit)
13769
13770 Implicit pointer access to the internally stored JSON value. No copies are
13771 made.
13772
13773 @warning Writing data to the pointee of the result yields an undefined
13774 state.
13775
13776 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13777 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13778 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
13779 assertion.
13780
13781 @return pointer to the internally stored JSON value if the requested
13782 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13783
13784 @complexity Constant.
13785
13786 @liveexample{The example below shows how pointers to internal values of a
13787 JSON value can be requested. Note that no type conversions are made and a
13788 `nullptr` is returned if the value and the requested pointer type does not
13789 match.,get_ptr}
13790
13791 @since version 1.0.0
13792 */
13793 template<typename PointerType, typename std::enable_if<
13794 std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()13795 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
13796 {
13797 // delegate the call to get_impl_ptr<>()
13798 return get_impl_ptr(static_cast<PointerType>(nullptr));
13799 }
13800
13801 /*!
13802 @brief get a pointer value (implicit)
13803 @copydoc get_ptr()
13804 */
13805 template<typename PointerType, typename std::enable_if<
13806 std::is_pointer<PointerType>::value and
13807 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const13808 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
13809 {
13810 // delegate the call to get_impl_ptr<>() const
13811 return get_impl_ptr(static_cast<PointerType>(nullptr));
13812 }
13813
13814 /*!
13815 @brief get a pointer value (explicit)
13816
13817 Explicit pointer access to the internally stored JSON value. No copies are
13818 made.
13819
13820 @warning The pointer becomes invalid if the underlying JSON object
13821 changes.
13822
13823 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13824 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13825 @ref number_unsigned_t, or @ref number_float_t.
13826
13827 @return pointer to the internally stored JSON value if the requested
13828 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13829
13830 @complexity Constant.
13831
13832 @liveexample{The example below shows how pointers to internal values of a
13833 JSON value can be requested. Note that no type conversions are made and a
13834 `nullptr` is returned if the value and the requested pointer type does not
13835 match.,get__PointerType}
13836
13837 @sa @ref get_ptr() for explicit pointer-member access
13838
13839 @since version 1.0.0
13840 */
13841 template<typename PointerType, typename std::enable_if<
13842 std::is_pointer<PointerType>::value, int>::type = 0>
get()13843 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
13844 {
13845 // delegate the call to get_ptr
13846 return get_ptr<PointerType>();
13847 }
13848
13849 /*!
13850 @brief get a pointer value (explicit)
13851 @copydoc get()
13852 */
13853 template<typename PointerType, typename std::enable_if<
13854 std::is_pointer<PointerType>::value, int>::type = 0>
get() const13855 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
13856 {
13857 // delegate the call to get_ptr
13858 return get_ptr<PointerType>();
13859 }
13860
13861 /*!
13862 @brief get a reference value (implicit)
13863
13864 Implicit reference access to the internally stored JSON value. No copies
13865 are made.
13866
13867 @warning Writing data to the referee of the result yields an undefined
13868 state.
13869
13870 @tparam ReferenceType reference type; must be a reference to @ref array_t,
13871 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
13872 @ref number_float_t. Enforced by static assertion.
13873
13874 @return reference to the internally stored JSON value if the requested
13875 reference type @a ReferenceType fits to the JSON value; throws
13876 type_error.303 otherwise
13877
13878 @throw type_error.303 in case passed type @a ReferenceType is incompatible
13879 with the stored JSON value; see example below
13880
13881 @complexity Constant.
13882
13883 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
13884
13885 @since version 1.1.0
13886 */
13887 template<typename ReferenceType, typename std::enable_if<
13888 std::is_reference<ReferenceType>::value, int>::type = 0>
13889 ReferenceType get_ref()
13890 {
13891 // delegate call to get_ref_impl
13892 return get_ref_impl<ReferenceType>(*this);
13893 }
13894
13895 /*!
13896 @brief get a reference value (implicit)
13897 @copydoc get_ref()
13898 */
13899 template<typename ReferenceType, typename std::enable_if<
13900 std::is_reference<ReferenceType>::value and
13901 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
13902 ReferenceType get_ref() const
13903 {
13904 // delegate call to get_ref_impl
13905 return get_ref_impl<ReferenceType>(*this);
13906 }
13907
13908 /*!
13909 @brief get a value (implicit)
13910
13911 Implicit type conversion between the JSON value and a compatible value.
13912 The call is realized by calling @ref get() const.
13913
13914 @tparam ValueType non-pointer type compatible to the JSON value, for
13915 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
13916 `std::vector` types for JSON arrays. The character type of @ref string_t
13917 as well as an initializer list of this type is excluded to avoid
13918 ambiguities as these types implicitly convert to `std::string`.
13919
13920 @return copy of the JSON value, converted to type @a ValueType
13921
13922 @throw type_error.302 in case passed type @a ValueType is incompatible
13923 to the JSON value type (e.g., the JSON value is of type boolean, but a
13924 string is requested); see example below
13925
13926 @complexity Linear in the size of the JSON value.
13927
13928 @liveexample{The example below shows several conversions from JSON values
13929 to other types. There a few things to note: (1) Floating-point numbers can
13930 be converted to integers\, (2) A JSON array can be converted to a standard
13931 `std::vector<short>`\, (3) A JSON object can be converted to C++
13932 associative containers such as `std::unordered_map<std::string\,
13933 json>`.,operator__ValueType}
13934
13935 @since version 1.0.0
13936 */
13937 template < typename ValueType, typename std::enable_if <
13938 not std::is_pointer<ValueType>::value and
13939 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
13940 not std::is_same<ValueType, typename string_t::value_type>::value and
13941 not detail::is_basic_json<ValueType>::value
13942
13943 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
13944 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
13945 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
13946 and not std::is_same<ValueType, typename std::string_view>::value
13947 #endif
13948 #endif
13949 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
13950 , int >::type = 0 >
operator ValueType() const13951 operator ValueType() const
13952 {
13953 // delegate the call to get<>() const
13954 return get<ValueType>();
13955 }
13956
13957 /// @}
13958
13959
13960 ////////////////////
13961 // element access //
13962 ////////////////////
13963
13964 /// @name element access
13965 /// Access to the JSON value.
13966 /// @{
13967
13968 /*!
13969 @brief access specified array element with bounds checking
13970
13971 Returns a reference to the element at specified location @a idx, with
13972 bounds checking.
13973
13974 @param[in] idx index of the element to access
13975
13976 @return reference to the element at index @a idx
13977
13978 @throw type_error.304 if the JSON value is not an array; in this case,
13979 calling `at` with an index makes no sense. See example below.
13980 @throw out_of_range.401 if the index @a idx is out of range of the array;
13981 that is, `idx >= size()`. See example below.
13982
13983 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13984 changes in the JSON value.
13985
13986 @complexity Constant.
13987
13988 @since version 1.0.0
13989
13990 @liveexample{The example below shows how array elements can be read and
13991 written using `at()`. It also demonstrates the different exceptions that
13992 can be thrown.,at__size_type}
13993 */
at(size_type idx)13994 reference at(size_type idx)
13995 {
13996 // at only works for arrays
13997 if (JSON_LIKELY(is_array()))
13998 {
13999 JSON_TRY
14000 {
14001 return m_value.array->at(idx);
14002 }
14003 JSON_CATCH (std::out_of_range&)
14004 {
14005 // create better exception explanation
14006 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14007 }
14008 }
14009 else
14010 {
14011 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14012 }
14013 }
14014
14015 /*!
14016 @brief access specified array element with bounds checking
14017
14018 Returns a const reference to the element at specified location @a idx,
14019 with bounds checking.
14020
14021 @param[in] idx index of the element to access
14022
14023 @return const reference to the element at index @a idx
14024
14025 @throw type_error.304 if the JSON value is not an array; in this case,
14026 calling `at` with an index makes no sense. See example below.
14027 @throw out_of_range.401 if the index @a idx is out of range of the array;
14028 that is, `idx >= size()`. See example below.
14029
14030 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14031 changes in the JSON value.
14032
14033 @complexity Constant.
14034
14035 @since version 1.0.0
14036
14037 @liveexample{The example below shows how array elements can be read using
14038 `at()`. It also demonstrates the different exceptions that can be thrown.,
14039 at__size_type_const}
14040 */
at(size_type idx) const14041 const_reference at(size_type idx) const
14042 {
14043 // at only works for arrays
14044 if (JSON_LIKELY(is_array()))
14045 {
14046 JSON_TRY
14047 {
14048 return m_value.array->at(idx);
14049 }
14050 JSON_CATCH (std::out_of_range&)
14051 {
14052 // create better exception explanation
14053 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14054 }
14055 }
14056 else
14057 {
14058 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14059 }
14060 }
14061
14062 /*!
14063 @brief access specified object element with bounds checking
14064
14065 Returns a reference to the element at with specified key @a key, with
14066 bounds checking.
14067
14068 @param[in] key key of the element to access
14069
14070 @return reference to the element at key @a key
14071
14072 @throw type_error.304 if the JSON value is not an object; in this case,
14073 calling `at` with a key makes no sense. See example below.
14074 @throw out_of_range.403 if the key @a key is is not stored in the object;
14075 that is, `find(key) == end()`. See example below.
14076
14077 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14078 changes in the JSON value.
14079
14080 @complexity Logarithmic in the size of the container.
14081
14082 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14083 access by reference
14084 @sa @ref value() for access by value with a default value
14085
14086 @since version 1.0.0
14087
14088 @liveexample{The example below shows how object elements can be read and
14089 written using `at()`. It also demonstrates the different exceptions that
14090 can be thrown.,at__object_t_key_type}
14091 */
at(const typename object_t::key_type & key)14092 reference at(const typename object_t::key_type& key)
14093 {
14094 // at only works for objects
14095 if (JSON_LIKELY(is_object()))
14096 {
14097 JSON_TRY
14098 {
14099 return m_value.object->at(key);
14100 }
14101 JSON_CATCH (std::out_of_range&)
14102 {
14103 // create better exception explanation
14104 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14105 }
14106 }
14107 else
14108 {
14109 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14110 }
14111 }
14112
14113 /*!
14114 @brief access specified object element with bounds checking
14115
14116 Returns a const reference to the element at with specified key @a key,
14117 with bounds checking.
14118
14119 @param[in] key key of the element to access
14120
14121 @return const reference to the element at key @a key
14122
14123 @throw type_error.304 if the JSON value is not an object; in this case,
14124 calling `at` with a key makes no sense. See example below.
14125 @throw out_of_range.403 if the key @a key is is not stored in the object;
14126 that is, `find(key) == end()`. See example below.
14127
14128 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14129 changes in the JSON value.
14130
14131 @complexity Logarithmic in the size of the container.
14132
14133 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14134 access by reference
14135 @sa @ref value() for access by value with a default value
14136
14137 @since version 1.0.0
14138
14139 @liveexample{The example below shows how object elements can be read using
14140 `at()`. It also demonstrates the different exceptions that can be thrown.,
14141 at__object_t_key_type_const}
14142 */
at(const typename object_t::key_type & key) const14143 const_reference at(const typename object_t::key_type& key) const
14144 {
14145 // at only works for objects
14146 if (JSON_LIKELY(is_object()))
14147 {
14148 JSON_TRY
14149 {
14150 return m_value.object->at(key);
14151 }
14152 JSON_CATCH (std::out_of_range&)
14153 {
14154 // create better exception explanation
14155 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14156 }
14157 }
14158 else
14159 {
14160 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14161 }
14162 }
14163
14164 /*!
14165 @brief access specified array element
14166
14167 Returns a reference to the element at specified location @a idx.
14168
14169 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
14170 then the array is silently filled up with `null` values to make `idx` a
14171 valid reference to the last stored element.
14172
14173 @param[in] idx index of the element to access
14174
14175 @return reference to the element at index @a idx
14176
14177 @throw type_error.305 if the JSON value is not an array or null; in that
14178 cases, using the [] operator with an index makes no sense.
14179
14180 @complexity Constant if @a idx is in the range of the array. Otherwise
14181 linear in `idx - size()`.
14182
14183 @liveexample{The example below shows how array elements can be read and
14184 written using `[]` operator. Note the addition of `null`
14185 values.,operatorarray__size_type}
14186
14187 @since version 1.0.0
14188 */
operator [](size_type idx)14189 reference operator[](size_type idx)
14190 {
14191 // implicitly convert null value to an empty array
14192 if (is_null())
14193 {
14194 m_type = value_t::array;
14195 m_value.array = create<array_t>();
14196 assert_invariant();
14197 }
14198
14199 // operator[] only works for arrays
14200 if (JSON_LIKELY(is_array()))
14201 {
14202 // fill up array with null values if given idx is outside range
14203 if (idx >= m_value.array->size())
14204 {
14205 m_value.array->insert(m_value.array->end(),
14206 idx - m_value.array->size() + 1,
14207 basic_json());
14208 }
14209
14210 return m_value.array->operator[](idx);
14211 }
14212
14213 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
14214 }
14215
14216 /*!
14217 @brief access specified array element
14218
14219 Returns a const reference to the element at specified location @a idx.
14220
14221 @param[in] idx index of the element to access
14222
14223 @return const reference to the element at index @a idx
14224
14225 @throw type_error.305 if the JSON value is not an array; in that case,
14226 using the [] operator with an index makes no sense.
14227
14228 @complexity Constant.
14229
14230 @liveexample{The example below shows how array elements can be read using
14231 the `[]` operator.,operatorarray__size_type_const}
14232
14233 @since version 1.0.0
14234 */
operator [](size_type idx) const14235 const_reference operator[](size_type idx) const
14236 {
14237 // const operator[] only works for arrays
14238 if (JSON_LIKELY(is_array()))
14239 {
14240 return m_value.array->operator[](idx);
14241 }
14242
14243 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
14244 }
14245
14246 /*!
14247 @brief access specified object element
14248
14249 Returns a reference to the element at with specified key @a key.
14250
14251 @note If @a key is not found in the object, then it is silently added to
14252 the object and filled with a `null` value to make `key` a valid reference.
14253 In case the value was `null` before, it is converted to an object.
14254
14255 @param[in] key key of the element to access
14256
14257 @return reference to the element at key @a key
14258
14259 @throw type_error.305 if the JSON value is not an object or null; in that
14260 cases, using the [] operator with a key makes no sense.
14261
14262 @complexity Logarithmic in the size of the container.
14263
14264 @liveexample{The example below shows how object elements can be read and
14265 written using the `[]` operator.,operatorarray__key_type}
14266
14267 @sa @ref at(const typename object_t::key_type&) for access by reference
14268 with range checking
14269 @sa @ref value() for access by value with a default value
14270
14271 @since version 1.0.0
14272 */
operator [](const typename object_t::key_type & key)14273 reference operator[](const typename object_t::key_type& key)
14274 {
14275 // implicitly convert null value to an empty object
14276 if (is_null())
14277 {
14278 m_type = value_t::object;
14279 m_value.object = create<object_t>();
14280 assert_invariant();
14281 }
14282
14283 // operator[] only works for objects
14284 if (JSON_LIKELY(is_object()))
14285 {
14286 return m_value.object->operator[](key);
14287 }
14288
14289 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14290 }
14291
14292 /*!
14293 @brief read-only access specified object element
14294
14295 Returns a const reference to the element at with specified key @a key. No
14296 bounds checking is performed.
14297
14298 @warning If the element with key @a key does not exist, the behavior is
14299 undefined.
14300
14301 @param[in] key key of the element to access
14302
14303 @return const reference to the element at key @a key
14304
14305 @pre The element with key @a key must exist. **This precondition is
14306 enforced with an assertion.**
14307
14308 @throw type_error.305 if the JSON value is not an object; in that case,
14309 using the [] operator with a key makes no sense.
14310
14311 @complexity Logarithmic in the size of the container.
14312
14313 @liveexample{The example below shows how object elements can be read using
14314 the `[]` operator.,operatorarray__key_type_const}
14315
14316 @sa @ref at(const typename object_t::key_type&) for access by reference
14317 with range checking
14318 @sa @ref value() for access by value with a default value
14319
14320 @since version 1.0.0
14321 */
operator [](const typename object_t::key_type & key) const14322 const_reference operator[](const typename object_t::key_type& key) const
14323 {
14324 // const operator[] only works for objects
14325 if (JSON_LIKELY(is_object()))
14326 {
14327 assert(m_value.object->find(key) != m_value.object->end());
14328 return m_value.object->find(key)->second;
14329 }
14330
14331 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14332 }
14333
14334 /*!
14335 @brief access specified object element
14336
14337 Returns a reference to the element at with specified key @a key.
14338
14339 @note If @a key is not found in the object, then it is silently added to
14340 the object and filled with a `null` value to make `key` a valid reference.
14341 In case the value was `null` before, it is converted to an object.
14342
14343 @param[in] key key of the element to access
14344
14345 @return reference to the element at key @a key
14346
14347 @throw type_error.305 if the JSON value is not an object or null; in that
14348 cases, using the [] operator with a key makes no sense.
14349
14350 @complexity Logarithmic in the size of the container.
14351
14352 @liveexample{The example below shows how object elements can be read and
14353 written using the `[]` operator.,operatorarray__key_type}
14354
14355 @sa @ref at(const typename object_t::key_type&) for access by reference
14356 with range checking
14357 @sa @ref value() for access by value with a default value
14358
14359 @since version 1.1.0
14360 */
14361 template<typename T>
operator [](T * key)14362 reference operator[](T* key)
14363 {
14364 // implicitly convert null to object
14365 if (is_null())
14366 {
14367 m_type = value_t::object;
14368 m_value = value_t::object;
14369 assert_invariant();
14370 }
14371
14372 // at only works for objects
14373 if (JSON_LIKELY(is_object()))
14374 {
14375 return m_value.object->operator[](key);
14376 }
14377
14378 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14379 }
14380
14381 /*!
14382 @brief read-only access specified object element
14383
14384 Returns a const reference to the element at with specified key @a key. No
14385 bounds checking is performed.
14386
14387 @warning If the element with key @a key does not exist, the behavior is
14388 undefined.
14389
14390 @param[in] key key of the element to access
14391
14392 @return const reference to the element at key @a key
14393
14394 @pre The element with key @a key must exist. **This precondition is
14395 enforced with an assertion.**
14396
14397 @throw type_error.305 if the JSON value is not an object; in that case,
14398 using the [] operator with a key makes no sense.
14399
14400 @complexity Logarithmic in the size of the container.
14401
14402 @liveexample{The example below shows how object elements can be read using
14403 the `[]` operator.,operatorarray__key_type_const}
14404
14405 @sa @ref at(const typename object_t::key_type&) for access by reference
14406 with range checking
14407 @sa @ref value() for access by value with a default value
14408
14409 @since version 1.1.0
14410 */
14411 template<typename T>
operator [](T * key) const14412 const_reference operator[](T* key) const
14413 {
14414 // at only works for objects
14415 if (JSON_LIKELY(is_object()))
14416 {
14417 assert(m_value.object->find(key) != m_value.object->end());
14418 return m_value.object->find(key)->second;
14419 }
14420
14421 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14422 }
14423
14424 /*!
14425 @brief access specified object element with default value
14426
14427 Returns either a copy of an object's element at the specified key @a key
14428 or a given default value if no element with key @a key exists.
14429
14430 The function is basically equivalent to executing
14431 @code {.cpp}
14432 try {
14433 return at(key);
14434 } catch(out_of_range) {
14435 return default_value;
14436 }
14437 @endcode
14438
14439 @note Unlike @ref at(const typename object_t::key_type&), this function
14440 does not throw if the given key @a key was not found.
14441
14442 @note Unlike @ref operator[](const typename object_t::key_type& key), this
14443 function does not implicitly add an element to the position defined by @a
14444 key. This function is furthermore also applicable to const objects.
14445
14446 @param[in] key key of the element to access
14447 @param[in] default_value the value to return if @a key is not found
14448
14449 @tparam ValueType type compatible to JSON values, for instance `int` for
14450 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14451 JSON arrays. Note the type of the expected value at @a key and the default
14452 value @a default_value must be compatible.
14453
14454 @return copy of the element at key @a key or @a default_value if @a key
14455 is not found
14456
14457 @throw type_error.306 if the JSON value is not an object; in that case,
14458 using `value()` with a key makes no sense.
14459
14460 @complexity Logarithmic in the size of the container.
14461
14462 @liveexample{The example below shows how object elements can be queried
14463 with a default value.,basic_json__value}
14464
14465 @sa @ref at(const typename object_t::key_type&) for access by reference
14466 with range checking
14467 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14468 access by reference
14469
14470 @since version 1.0.0
14471 */
14472 template<class ValueType, typename std::enable_if<
14473 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14474 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
14475 {
14476 // at only works for objects
14477 if (JSON_LIKELY(is_object()))
14478 {
14479 // if key is found, return value and given default value otherwise
14480 const auto it = find(key);
14481 if (it != end())
14482 {
14483 return *it;
14484 }
14485
14486 return default_value;
14487 }
14488
14489 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14490 }
14491
14492 /*!
14493 @brief overload for a default value of type const char*
14494 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
14495 */
value(const typename object_t::key_type & key,const char * default_value) const14496 string_t value(const typename object_t::key_type& key, const char* default_value) const
14497 {
14498 return value(key, string_t(default_value));
14499 }
14500
14501 /*!
14502 @brief access specified object element via JSON Pointer with default value
14503
14504 Returns either a copy of an object's element at the specified key @a key
14505 or a given default value if no element with key @a key exists.
14506
14507 The function is basically equivalent to executing
14508 @code {.cpp}
14509 try {
14510 return at(ptr);
14511 } catch(out_of_range) {
14512 return default_value;
14513 }
14514 @endcode
14515
14516 @note Unlike @ref at(const json_pointer&), this function does not throw
14517 if the given key @a key was not found.
14518
14519 @param[in] ptr a JSON pointer to the element to access
14520 @param[in] default_value the value to return if @a ptr found no value
14521
14522 @tparam ValueType type compatible to JSON values, for instance `int` for
14523 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14524 JSON arrays. Note the type of the expected value at @a key and the default
14525 value @a default_value must be compatible.
14526
14527 @return copy of the element at key @a key or @a default_value if @a key
14528 is not found
14529
14530 @throw type_error.306 if the JSON value is not an object; in that case,
14531 using `value()` with a key makes no sense.
14532
14533 @complexity Logarithmic in the size of the container.
14534
14535 @liveexample{The example below shows how object elements can be queried
14536 with a default value.,basic_json__value_ptr}
14537
14538 @sa @ref operator[](const json_pointer&) for unchecked access by reference
14539
14540 @since version 2.0.2
14541 */
14542 template<class ValueType, typename std::enable_if<
14543 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14544 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
14545 {
14546 // at only works for objects
14547 if (JSON_LIKELY(is_object()))
14548 {
14549 // if pointer resolves a value, return it or use default value
14550 JSON_TRY
14551 {
14552 return ptr.get_checked(this);
14553 }
14554 JSON_INTERNAL_CATCH (out_of_range&)
14555 {
14556 return default_value;
14557 }
14558 }
14559
14560 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14561 }
14562
14563 /*!
14564 @brief overload for a default value of type const char*
14565 @copydoc basic_json::value(const json_pointer&, ValueType) const
14566 */
value(const json_pointer & ptr,const char * default_value) const14567 string_t value(const json_pointer& ptr, const char* default_value) const
14568 {
14569 return value(ptr, string_t(default_value));
14570 }
14571
14572 /*!
14573 @brief access the first element
14574
14575 Returns a reference to the first element in the container. For a JSON
14576 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
14577
14578 @return In case of a structured type (array or object), a reference to the
14579 first element is returned. In case of number, string, or boolean values, a
14580 reference to the value is returned.
14581
14582 @complexity Constant.
14583
14584 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14585 or an empty array or object (undefined behavior, **guarded by
14586 assertions**).
14587 @post The JSON value remains unchanged.
14588
14589 @throw invalid_iterator.214 when called on `null` value
14590
14591 @liveexample{The following code shows an example for `front()`.,front}
14592
14593 @sa @ref back() -- access the last element
14594
14595 @since version 1.0.0
14596 */
front()14597 reference front()
14598 {
14599 return *begin();
14600 }
14601
14602 /*!
14603 @copydoc basic_json::front()
14604 */
front() const14605 const_reference front() const
14606 {
14607 return *cbegin();
14608 }
14609
14610 /*!
14611 @brief access the last element
14612
14613 Returns a reference to the last element in the container. For a JSON
14614 container `c`, the expression `c.back()` is equivalent to
14615 @code {.cpp}
14616 auto tmp = c.end();
14617 --tmp;
14618 return *tmp;
14619 @endcode
14620
14621 @return In case of a structured type (array or object), a reference to the
14622 last element is returned. In case of number, string, or boolean values, a
14623 reference to the value is returned.
14624
14625 @complexity Constant.
14626
14627 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14628 or an empty array or object (undefined behavior, **guarded by
14629 assertions**).
14630 @post The JSON value remains unchanged.
14631
14632 @throw invalid_iterator.214 when called on a `null` value. See example
14633 below.
14634
14635 @liveexample{The following code shows an example for `back()`.,back}
14636
14637 @sa @ref front() -- access the first element
14638
14639 @since version 1.0.0
14640 */
back()14641 reference back()
14642 {
14643 auto tmp = end();
14644 --tmp;
14645 return *tmp;
14646 }
14647
14648 /*!
14649 @copydoc basic_json::back()
14650 */
back() const14651 const_reference back() const
14652 {
14653 auto tmp = cend();
14654 --tmp;
14655 return *tmp;
14656 }
14657
14658 /*!
14659 @brief remove element given an iterator
14660
14661 Removes the element specified by iterator @a pos. The iterator @a pos must
14662 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
14663 but is not dereferenceable) cannot be used as a value for @a pos.
14664
14665 If called on a primitive type other than `null`, the resulting JSON value
14666 will be `null`.
14667
14668 @param[in] pos iterator to the element to remove
14669 @return Iterator following the last removed element. If the iterator @a
14670 pos refers to the last element, the `end()` iterator is returned.
14671
14672 @tparam IteratorType an @ref iterator or @ref const_iterator
14673
14674 @post Invalidates iterators and references at or after the point of the
14675 erase, including the `end()` iterator.
14676
14677 @throw type_error.307 if called on a `null` value; example: `"cannot use
14678 erase() with null"`
14679 @throw invalid_iterator.202 if called on an iterator which does not belong
14680 to the current JSON value; example: `"iterator does not fit current
14681 value"`
14682 @throw invalid_iterator.205 if called on a primitive type with invalid
14683 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
14684 out of range"`
14685
14686 @complexity The complexity depends on the type:
14687 - objects: amortized constant
14688 - arrays: linear in distance between @a pos and the end of the container
14689 - strings: linear in the length of the string
14690 - other types: constant
14691
14692 @liveexample{The example shows the result of `erase()` for different JSON
14693 types.,erase__IteratorType}
14694
14695 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14696 the given range
14697 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14698 from an object at the given key
14699 @sa @ref erase(const size_type) -- removes the element from an array at
14700 the given index
14701
14702 @since version 1.0.0
14703 */
14704 template<class IteratorType, typename std::enable_if<
14705 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14706 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14707 = 0>
14708 IteratorType erase(IteratorType pos)
14709 {
14710 // make sure iterator fits the current value
14711 if (JSON_UNLIKELY(this != pos.m_object))
14712 {
14713 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14714 }
14715
14716 IteratorType result = end();
14717
14718 switch (m_type)
14719 {
14720 case value_t::boolean:
14721 case value_t::number_float:
14722 case value_t::number_integer:
14723 case value_t::number_unsigned:
14724 case value_t::string:
14725 {
14726 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
14727 {
14728 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
14729 }
14730
14731 if (is_string())
14732 {
14733 AllocatorType<string_t> alloc;
14734 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14735 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14736 m_value.string = nullptr;
14737 }
14738
14739 m_type = value_t::null;
14740 assert_invariant();
14741 break;
14742 }
14743
14744 case value_t::object:
14745 {
14746 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
14747 break;
14748 }
14749
14750 case value_t::array:
14751 {
14752 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
14753 break;
14754 }
14755
14756 default:
14757 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14758 }
14759
14760 return result;
14761 }
14762
14763 /*!
14764 @brief remove elements given an iterator range
14765
14766 Removes the element specified by the range `[first; last)`. The iterator
14767 @a first does not need to be dereferenceable if `first == last`: erasing
14768 an empty range is a no-op.
14769
14770 If called on a primitive type other than `null`, the resulting JSON value
14771 will be `null`.
14772
14773 @param[in] first iterator to the beginning of the range to remove
14774 @param[in] last iterator past the end of the range to remove
14775 @return Iterator following the last removed element. If the iterator @a
14776 second refers to the last element, the `end()` iterator is returned.
14777
14778 @tparam IteratorType an @ref iterator or @ref const_iterator
14779
14780 @post Invalidates iterators and references at or after the point of the
14781 erase, including the `end()` iterator.
14782
14783 @throw type_error.307 if called on a `null` value; example: `"cannot use
14784 erase() with null"`
14785 @throw invalid_iterator.203 if called on iterators which does not belong
14786 to the current JSON value; example: `"iterators do not fit current value"`
14787 @throw invalid_iterator.204 if called on a primitive type with invalid
14788 iterators (i.e., if `first != begin()` and `last != end()`); example:
14789 `"iterators out of range"`
14790
14791 @complexity The complexity depends on the type:
14792 - objects: `log(size()) + std::distance(first, last)`
14793 - arrays: linear in the distance between @a first and @a last, plus linear
14794 in the distance between @a last and end of the container
14795 - strings: linear in the length of the string
14796 - other types: constant
14797
14798 @liveexample{The example shows the result of `erase()` for different JSON
14799 types.,erase__IteratorType_IteratorType}
14800
14801 @sa @ref erase(IteratorType) -- removes the element at a given position
14802 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14803 from an object at the given key
14804 @sa @ref erase(const size_type) -- removes the element from an array at
14805 the given index
14806
14807 @since version 1.0.0
14808 */
14809 template<class IteratorType, typename std::enable_if<
14810 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14811 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14812 = 0>
14813 IteratorType erase(IteratorType first, IteratorType last)
14814 {
14815 // make sure iterator fits the current value
14816 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
14817 {
14818 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
14819 }
14820
14821 IteratorType result = end();
14822
14823 switch (m_type)
14824 {
14825 case value_t::boolean:
14826 case value_t::number_float:
14827 case value_t::number_integer:
14828 case value_t::number_unsigned:
14829 case value_t::string:
14830 {
14831 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
14832 or not last.m_it.primitive_iterator.is_end()))
14833 {
14834 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14835 }
14836
14837 if (is_string())
14838 {
14839 AllocatorType<string_t> alloc;
14840 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14841 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14842 m_value.string = nullptr;
14843 }
14844
14845 m_type = value_t::null;
14846 assert_invariant();
14847 break;
14848 }
14849
14850 case value_t::object:
14851 {
14852 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
14853 last.m_it.object_iterator);
14854 break;
14855 }
14856
14857 case value_t::array:
14858 {
14859 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
14860 last.m_it.array_iterator);
14861 break;
14862 }
14863
14864 default:
14865 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14866 }
14867
14868 return result;
14869 }
14870
14871 /*!
14872 @brief remove element from a JSON object given a key
14873
14874 Removes elements from a JSON object with the key value @a key.
14875
14876 @param[in] key value of the elements to remove
14877
14878 @return Number of elements removed. If @a ObjectType is the default
14879 `std::map` type, the return value will always be `0` (@a key was not
14880 found) or `1` (@a key was found).
14881
14882 @post References and iterators to the erased elements are invalidated.
14883 Other references and iterators are not affected.
14884
14885 @throw type_error.307 when called on a type other than JSON object;
14886 example: `"cannot use erase() with null"`
14887
14888 @complexity `log(size()) + count(key)`
14889
14890 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
14891
14892 @sa @ref erase(IteratorType) -- removes the element at a given position
14893 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14894 the given range
14895 @sa @ref erase(const size_type) -- removes the element from an array at
14896 the given index
14897
14898 @since version 1.0.0
14899 */
erase(const typename object_t::key_type & key)14900 size_type erase(const typename object_t::key_type& key)
14901 {
14902 // this erase only works for objects
14903 if (JSON_LIKELY(is_object()))
14904 {
14905 return m_value.object->erase(key);
14906 }
14907
14908 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14909 }
14910
14911 /*!
14912 @brief remove element from a JSON array given an index
14913
14914 Removes element from a JSON array at the index @a idx.
14915
14916 @param[in] idx index of the element to remove
14917
14918 @throw type_error.307 when called on a type other than JSON object;
14919 example: `"cannot use erase() with null"`
14920 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
14921 is out of range"`
14922
14923 @complexity Linear in distance between @a idx and the end of the container.
14924
14925 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
14926
14927 @sa @ref erase(IteratorType) -- removes the element at a given position
14928 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14929 the given range
14930 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14931 from an object at the given key
14932
14933 @since version 1.0.0
14934 */
erase(const size_type idx)14935 void erase(const size_type idx)
14936 {
14937 // this erase only works for arrays
14938 if (JSON_LIKELY(is_array()))
14939 {
14940 if (JSON_UNLIKELY(idx >= size()))
14941 {
14942 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14943 }
14944
14945 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
14946 }
14947 else
14948 {
14949 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14950 }
14951 }
14952
14953 /// @}
14954
14955
14956 ////////////
14957 // lookup //
14958 ////////////
14959
14960 /// @name lookup
14961 /// @{
14962
14963 /*!
14964 @brief find an element in a JSON object
14965
14966 Finds an element in a JSON object with key equivalent to @a key. If the
14967 element is not found or the JSON value is not an object, end() is
14968 returned.
14969
14970 @note This method always returns @ref end() when executed on a JSON type
14971 that is not an object.
14972
14973 @param[in] key key value of the element to search for.
14974
14975 @return Iterator to an element with key equivalent to @a key. If no such
14976 element is found or the JSON value is not an object, past-the-end (see
14977 @ref end()) iterator is returned.
14978
14979 @complexity Logarithmic in the size of the JSON object.
14980
14981 @liveexample{The example shows how `find()` is used.,find__key_type}
14982
14983 @since version 1.0.0
14984 */
14985 template<typename KeyT>
find(KeyT && key)14986 iterator find(KeyT&& key)
14987 {
14988 auto result = end();
14989
14990 if (is_object())
14991 {
14992 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
14993 }
14994
14995 return result;
14996 }
14997
14998 /*!
14999 @brief find an element in a JSON object
15000 @copydoc find(KeyT&&)
15001 */
15002 template<typename KeyT>
find(KeyT && key) const15003 const_iterator find(KeyT&& key) const
15004 {
15005 auto result = cend();
15006
15007 if (is_object())
15008 {
15009 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
15010 }
15011
15012 return result;
15013 }
15014
15015 /*!
15016 @brief returns the number of occurrences of a key in a JSON object
15017
15018 Returns the number of elements with key @a key. If ObjectType is the
15019 default `std::map` type, the return value will always be `0` (@a key was
15020 not found) or `1` (@a key was found).
15021
15022 @note This method always returns `0` when executed on a JSON type that is
15023 not an object.
15024
15025 @param[in] key key value of the element to count
15026
15027 @return Number of elements with key @a key. If the JSON value is not an
15028 object, the return value will be `0`.
15029
15030 @complexity Logarithmic in the size of the JSON object.
15031
15032 @liveexample{The example shows how `count()` is used.,count}
15033
15034 @since version 1.0.0
15035 */
15036 template<typename KeyT>
count(KeyT && key) const15037 size_type count(KeyT&& key) const
15038 {
15039 // return 0 for all nonobject types
15040 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
15041 }
15042
15043 /// @}
15044
15045
15046 ///////////////
15047 // iterators //
15048 ///////////////
15049
15050 /// @name iterators
15051 /// @{
15052
15053 /*!
15054 @brief returns an iterator to the first element
15055
15056 Returns an iterator to the first element.
15057
15058 @image html range-begin-end.svg "Illustration from cppreference.com"
15059
15060 @return iterator to the first element
15061
15062 @complexity Constant.
15063
15064 @requirement This function helps `basic_json` satisfying the
15065 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15066 requirements:
15067 - The complexity is constant.
15068
15069 @liveexample{The following code shows an example for `begin()`.,begin}
15070
15071 @sa @ref cbegin() -- returns a const iterator to the beginning
15072 @sa @ref end() -- returns an iterator to the end
15073 @sa @ref cend() -- returns a const iterator to the end
15074
15075 @since version 1.0.0
15076 */
begin()15077 iterator begin() noexcept
15078 {
15079 iterator result(this);
15080 result.set_begin();
15081 return result;
15082 }
15083
15084 /*!
15085 @copydoc basic_json::cbegin()
15086 */
begin() const15087 const_iterator begin() const noexcept
15088 {
15089 return cbegin();
15090 }
15091
15092 /*!
15093 @brief returns a const iterator to the first element
15094
15095 Returns a const iterator to the first element.
15096
15097 @image html range-begin-end.svg "Illustration from cppreference.com"
15098
15099 @return const iterator to the first element
15100
15101 @complexity Constant.
15102
15103 @requirement This function helps `basic_json` satisfying the
15104 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15105 requirements:
15106 - The complexity is constant.
15107 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
15108
15109 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
15110
15111 @sa @ref begin() -- returns an iterator to the beginning
15112 @sa @ref end() -- returns an iterator to the end
15113 @sa @ref cend() -- returns a const iterator to the end
15114
15115 @since version 1.0.0
15116 */
cbegin() const15117 const_iterator cbegin() const noexcept
15118 {
15119 const_iterator result(this);
15120 result.set_begin();
15121 return result;
15122 }
15123
15124 /*!
15125 @brief returns an iterator to one past the last element
15126
15127 Returns an iterator to one past the last element.
15128
15129 @image html range-begin-end.svg "Illustration from cppreference.com"
15130
15131 @return iterator one past the last element
15132
15133 @complexity Constant.
15134
15135 @requirement This function helps `basic_json` satisfying the
15136 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15137 requirements:
15138 - The complexity is constant.
15139
15140 @liveexample{The following code shows an example for `end()`.,end}
15141
15142 @sa @ref cend() -- returns a const iterator to the end
15143 @sa @ref begin() -- returns an iterator to the beginning
15144 @sa @ref cbegin() -- returns a const iterator to the beginning
15145
15146 @since version 1.0.0
15147 */
end()15148 iterator end() noexcept
15149 {
15150 iterator result(this);
15151 result.set_end();
15152 return result;
15153 }
15154
15155 /*!
15156 @copydoc basic_json::cend()
15157 */
end() const15158 const_iterator end() const noexcept
15159 {
15160 return cend();
15161 }
15162
15163 /*!
15164 @brief returns a const iterator to one past the last element
15165
15166 Returns a const iterator to one past the last element.
15167
15168 @image html range-begin-end.svg "Illustration from cppreference.com"
15169
15170 @return const iterator one past the last element
15171
15172 @complexity Constant.
15173
15174 @requirement This function helps `basic_json` satisfying the
15175 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15176 requirements:
15177 - The complexity is constant.
15178 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
15179
15180 @liveexample{The following code shows an example for `cend()`.,cend}
15181
15182 @sa @ref end() -- returns an iterator to the end
15183 @sa @ref begin() -- returns an iterator to the beginning
15184 @sa @ref cbegin() -- returns a const iterator to the beginning
15185
15186 @since version 1.0.0
15187 */
cend() const15188 const_iterator cend() const noexcept
15189 {
15190 const_iterator result(this);
15191 result.set_end();
15192 return result;
15193 }
15194
15195 /*!
15196 @brief returns an iterator to the reverse-beginning
15197
15198 Returns an iterator to the reverse-beginning; that is, the last element.
15199
15200 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15201
15202 @complexity Constant.
15203
15204 @requirement This function helps `basic_json` satisfying the
15205 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15206 requirements:
15207 - The complexity is constant.
15208 - Has the semantics of `reverse_iterator(end())`.
15209
15210 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
15211
15212 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15213 @sa @ref rend() -- returns a reverse iterator to the end
15214 @sa @ref crend() -- returns a const reverse iterator to the end
15215
15216 @since version 1.0.0
15217 */
rbegin()15218 reverse_iterator rbegin() noexcept
15219 {
15220 return reverse_iterator(end());
15221 }
15222
15223 /*!
15224 @copydoc basic_json::crbegin()
15225 */
rbegin() const15226 const_reverse_iterator rbegin() const noexcept
15227 {
15228 return crbegin();
15229 }
15230
15231 /*!
15232 @brief returns an iterator to the reverse-end
15233
15234 Returns an iterator to the reverse-end; that is, one before the first
15235 element.
15236
15237 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15238
15239 @complexity Constant.
15240
15241 @requirement This function helps `basic_json` satisfying the
15242 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15243 requirements:
15244 - The complexity is constant.
15245 - Has the semantics of `reverse_iterator(begin())`.
15246
15247 @liveexample{The following code shows an example for `rend()`.,rend}
15248
15249 @sa @ref crend() -- returns a const reverse iterator to the end
15250 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15251 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15252
15253 @since version 1.0.0
15254 */
rend()15255 reverse_iterator rend() noexcept
15256 {
15257 return reverse_iterator(begin());
15258 }
15259
15260 /*!
15261 @copydoc basic_json::crend()
15262 */
rend() const15263 const_reverse_iterator rend() const noexcept
15264 {
15265 return crend();
15266 }
15267
15268 /*!
15269 @brief returns a const reverse iterator to the last element
15270
15271 Returns a const iterator to the reverse-beginning; that is, the last
15272 element.
15273
15274 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15275
15276 @complexity Constant.
15277
15278 @requirement This function helps `basic_json` satisfying the
15279 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15280 requirements:
15281 - The complexity is constant.
15282 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
15283
15284 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
15285
15286 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15287 @sa @ref rend() -- returns a reverse iterator to the end
15288 @sa @ref crend() -- returns a const reverse iterator to the end
15289
15290 @since version 1.0.0
15291 */
crbegin() const15292 const_reverse_iterator crbegin() const noexcept
15293 {
15294 return const_reverse_iterator(cend());
15295 }
15296
15297 /*!
15298 @brief returns a const reverse iterator to one before the first
15299
15300 Returns a const reverse iterator to the reverse-end; that is, one before
15301 the first element.
15302
15303 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15304
15305 @complexity Constant.
15306
15307 @requirement This function helps `basic_json` satisfying the
15308 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15309 requirements:
15310 - The complexity is constant.
15311 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
15312
15313 @liveexample{The following code shows an example for `crend()`.,crend}
15314
15315 @sa @ref rend() -- returns a reverse iterator to the end
15316 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15317 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15318
15319 @since version 1.0.0
15320 */
crend() const15321 const_reverse_iterator crend() const noexcept
15322 {
15323 return const_reverse_iterator(cbegin());
15324 }
15325
15326 public:
15327 /*!
15328 @brief wrapper to access iterator member functions in range-based for
15329
15330 This function allows to access @ref iterator::key() and @ref
15331 iterator::value() during range-based for loops. In these loops, a
15332 reference to the JSON values is returned, so there is no access to the
15333 underlying iterator.
15334
15335 For loop without iterator_wrapper:
15336
15337 @code{cpp}
15338 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15339 {
15340 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15341 }
15342 @endcode
15343
15344 Range-based for loop without iterator proxy:
15345
15346 @code{cpp}
15347 for (auto it : j_object)
15348 {
15349 // "it" is of type json::reference and has no key() member
15350 std::cout << "value: " << it << '\n';
15351 }
15352 @endcode
15353
15354 Range-based for loop with iterator proxy:
15355
15356 @code{cpp}
15357 for (auto it : json::iterator_wrapper(j_object))
15358 {
15359 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15360 }
15361 @endcode
15362
15363 @note When iterating over an array, `key()` will return the index of the
15364 element as string (see example).
15365
15366 @param[in] ref reference to a JSON value
15367 @return iteration proxy object wrapping @a ref with an interface to use in
15368 range-based for loops
15369
15370 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
15371
15372 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15373 changes in the JSON value.
15374
15375 @complexity Constant.
15376
15377 @note The name of this function is not yet final and may change in the
15378 future.
15379
15380 @deprecated This stream operator is deprecated and will be removed in
15381 future 4.0.0 of the library. Please use @ref items() instead;
15382 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
15383 */
15384 JSON_DEPRECATED
iterator_wrapper(reference ref)15385 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
15386 {
15387 return ref.items();
15388 }
15389
15390 /*!
15391 @copydoc iterator_wrapper(reference)
15392 */
15393 JSON_DEPRECATED
iterator_wrapper(const_reference ref)15394 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
15395 {
15396 return ref.items();
15397 }
15398
15399 /*!
15400 @brief helper to access iterator member functions in range-based for
15401
15402 This function allows to access @ref iterator::key() and @ref
15403 iterator::value() during range-based for loops. In these loops, a
15404 reference to the JSON values is returned, so there is no access to the
15405 underlying iterator.
15406
15407 For loop without `items()` function:
15408
15409 @code{cpp}
15410 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15411 {
15412 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15413 }
15414 @endcode
15415
15416 Range-based for loop without `items()` function:
15417
15418 @code{cpp}
15419 for (auto it : j_object)
15420 {
15421 // "it" is of type json::reference and has no key() member
15422 std::cout << "value: " << it << '\n';
15423 }
15424 @endcode
15425
15426 Range-based for loop with `items()` function:
15427
15428 @code{cpp}
15429 for (auto it : j_object.items())
15430 {
15431 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15432 }
15433 @endcode
15434
15435 @note When iterating over an array, `key()` will return the index of the
15436 element as string (see example). For primitive types (e.g., numbers),
15437 `key()` returns an empty string.
15438
15439 @return iteration proxy object wrapping @a ref with an interface to use in
15440 range-based for loops
15441
15442 @liveexample{The following code shows how the function is used.,items}
15443
15444 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15445 changes in the JSON value.
15446
15447 @complexity Constant.
15448
15449 @since version 3.1.0.
15450 */
items()15451 iteration_proxy<iterator> items() noexcept
15452 {
15453 return iteration_proxy<iterator>(*this);
15454 }
15455
15456 /*!
15457 @copydoc items()
15458 */
items() const15459 iteration_proxy<const_iterator> items() const noexcept
15460 {
15461 return iteration_proxy<const_iterator>(*this);
15462 }
15463
15464 /// @}
15465
15466
15467 //////////////
15468 // capacity //
15469 //////////////
15470
15471 /// @name capacity
15472 /// @{
15473
15474 /*!
15475 @brief checks whether the container is empty.
15476
15477 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
15478
15479 @return The return value depends on the different types and is
15480 defined as follows:
15481 Value type | return value
15482 ----------- | -------------
15483 null | `true`
15484 boolean | `false`
15485 string | `false`
15486 number | `false`
15487 object | result of function `object_t::empty()`
15488 array | result of function `array_t::empty()`
15489
15490 @liveexample{The following code uses `empty()` to check if a JSON
15491 object contains any elements.,empty}
15492
15493 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15494 the Container concept; that is, their `empty()` functions have constant
15495 complexity.
15496
15497 @iterators No changes.
15498
15499 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15500
15501 @note This function does not return whether a string stored as JSON value
15502 is empty - it returns whether the JSON container itself is empty which is
15503 false in the case of a string.
15504
15505 @requirement This function helps `basic_json` satisfying the
15506 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15507 requirements:
15508 - The complexity is constant.
15509 - Has the semantics of `begin() == end()`.
15510
15511 @sa @ref size() -- returns the number of elements
15512
15513 @since version 1.0.0
15514 */
empty() const15515 bool empty() const noexcept
15516 {
15517 switch (m_type)
15518 {
15519 case value_t::null:
15520 {
15521 // null values are empty
15522 return true;
15523 }
15524
15525 case value_t::array:
15526 {
15527 // delegate call to array_t::empty()
15528 return m_value.array->empty();
15529 }
15530
15531 case value_t::object:
15532 {
15533 // delegate call to object_t::empty()
15534 return m_value.object->empty();
15535 }
15536
15537 default:
15538 {
15539 // all other types are nonempty
15540 return false;
15541 }
15542 }
15543 }
15544
15545 /*!
15546 @brief returns the number of elements
15547
15548 Returns the number of elements in a JSON value.
15549
15550 @return The return value depends on the different types and is
15551 defined as follows:
15552 Value type | return value
15553 ----------- | -------------
15554 null | `0`
15555 boolean | `1`
15556 string | `1`
15557 number | `1`
15558 object | result of function object_t::size()
15559 array | result of function array_t::size()
15560
15561 @liveexample{The following code calls `size()` on the different value
15562 types.,size}
15563
15564 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15565 the Container concept; that is, their size() functions have constant
15566 complexity.
15567
15568 @iterators No changes.
15569
15570 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15571
15572 @note This function does not return the length of a string stored as JSON
15573 value - it returns the number of elements in the JSON value which is 1 in
15574 the case of a string.
15575
15576 @requirement This function helps `basic_json` satisfying the
15577 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15578 requirements:
15579 - The complexity is constant.
15580 - Has the semantics of `std::distance(begin(), end())`.
15581
15582 @sa @ref empty() -- checks whether the container is empty
15583 @sa @ref max_size() -- returns the maximal number of elements
15584
15585 @since version 1.0.0
15586 */
size() const15587 size_type size() const noexcept
15588 {
15589 switch (m_type)
15590 {
15591 case value_t::null:
15592 {
15593 // null values are empty
15594 return 0;
15595 }
15596
15597 case value_t::array:
15598 {
15599 // delegate call to array_t::size()
15600 return m_value.array->size();
15601 }
15602
15603 case value_t::object:
15604 {
15605 // delegate call to object_t::size()
15606 return m_value.object->size();
15607 }
15608
15609 default:
15610 {
15611 // all other types have size 1
15612 return 1;
15613 }
15614 }
15615 }
15616
15617 /*!
15618 @brief returns the maximum possible number of elements
15619
15620 Returns the maximum number of elements a JSON value is able to hold due to
15621 system or library implementation limitations, i.e. `std::distance(begin(),
15622 end())` for the JSON value.
15623
15624 @return The return value depends on the different types and is
15625 defined as follows:
15626 Value type | return value
15627 ----------- | -------------
15628 null | `0` (same as `size()`)
15629 boolean | `1` (same as `size()`)
15630 string | `1` (same as `size()`)
15631 number | `1` (same as `size()`)
15632 object | result of function `object_t::max_size()`
15633 array | result of function `array_t::max_size()`
15634
15635 @liveexample{The following code calls `max_size()` on the different value
15636 types. Note the output is implementation specific.,max_size}
15637
15638 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15639 the Container concept; that is, their `max_size()` functions have constant
15640 complexity.
15641
15642 @iterators No changes.
15643
15644 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15645
15646 @requirement This function helps `basic_json` satisfying the
15647 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15648 requirements:
15649 - The complexity is constant.
15650 - Has the semantics of returning `b.size()` where `b` is the largest
15651 possible JSON value.
15652
15653 @sa @ref size() -- returns the number of elements
15654
15655 @since version 1.0.0
15656 */
max_size() const15657 size_type max_size() const noexcept
15658 {
15659 switch (m_type)
15660 {
15661 case value_t::array:
15662 {
15663 // delegate call to array_t::max_size()
15664 return m_value.array->max_size();
15665 }
15666
15667 case value_t::object:
15668 {
15669 // delegate call to object_t::max_size()
15670 return m_value.object->max_size();
15671 }
15672
15673 default:
15674 {
15675 // all other types have max_size() == size()
15676 return size();
15677 }
15678 }
15679 }
15680
15681 /// @}
15682
15683
15684 ///////////////
15685 // modifiers //
15686 ///////////////
15687
15688 /// @name modifiers
15689 /// @{
15690
15691 /*!
15692 @brief clears the contents
15693
15694 Clears the content of a JSON value and resets it to the default value as
15695 if @ref basic_json(value_t) would have been called with the current value
15696 type from @ref type():
15697
15698 Value type | initial value
15699 ----------- | -------------
15700 null | `null`
15701 boolean | `false`
15702 string | `""`
15703 number | `0`
15704 object | `{}`
15705 array | `[]`
15706
15707 @post Has the same effect as calling
15708 @code {.cpp}
15709 *this = basic_json(type());
15710 @endcode
15711
15712 @liveexample{The example below shows the effect of `clear()` to different
15713 JSON types.,clear}
15714
15715 @complexity Linear in the size of the JSON value.
15716
15717 @iterators All iterators, pointers and references related to this container
15718 are invalidated.
15719
15720 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15721
15722 @sa @ref basic_json(value_t) -- constructor that creates an object with the
15723 same value than calling `clear()`
15724
15725 @since version 1.0.0
15726 */
clear()15727 void clear() noexcept
15728 {
15729 switch (m_type)
15730 {
15731 case value_t::number_integer:
15732 {
15733 m_value.number_integer = 0;
15734 break;
15735 }
15736
15737 case value_t::number_unsigned:
15738 {
15739 m_value.number_unsigned = 0;
15740 break;
15741 }
15742
15743 case value_t::number_float:
15744 {
15745 m_value.number_float = 0.0;
15746 break;
15747 }
15748
15749 case value_t::boolean:
15750 {
15751 m_value.boolean = false;
15752 break;
15753 }
15754
15755 case value_t::string:
15756 {
15757 m_value.string->clear();
15758 break;
15759 }
15760
15761 case value_t::array:
15762 {
15763 m_value.array->clear();
15764 break;
15765 }
15766
15767 case value_t::object:
15768 {
15769 m_value.object->clear();
15770 break;
15771 }
15772
15773 default:
15774 break;
15775 }
15776 }
15777
15778 /*!
15779 @brief add an object to an array
15780
15781 Appends the given element @a val to the end of the JSON value. If the
15782 function is called on a JSON null value, an empty array is created before
15783 appending @a val.
15784
15785 @param[in] val the value to add to the JSON array
15786
15787 @throw type_error.308 when called on a type other than JSON array or
15788 null; example: `"cannot use push_back() with number"`
15789
15790 @complexity Amortized constant.
15791
15792 @liveexample{The example shows how `push_back()` and `+=` can be used to
15793 add elements to a JSON array. Note how the `null` value was silently
15794 converted to a JSON array.,push_back}
15795
15796 @since version 1.0.0
15797 */
push_back(basic_json && val)15798 void push_back(basic_json&& val)
15799 {
15800 // push_back only works for null objects or arrays
15801 if (JSON_UNLIKELY(not(is_null() or is_array())))
15802 {
15803 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15804 }
15805
15806 // transform null object into an array
15807 if (is_null())
15808 {
15809 m_type = value_t::array;
15810 m_value = value_t::array;
15811 assert_invariant();
15812 }
15813
15814 // add element to array (move semantics)
15815 m_value.array->push_back(std::move(val));
15816 // invalidate object
15817 val.m_type = value_t::null;
15818 }
15819
15820 /*!
15821 @brief add an object to an array
15822 @copydoc push_back(basic_json&&)
15823 */
operator +=(basic_json && val)15824 reference operator+=(basic_json&& val)
15825 {
15826 push_back(std::move(val));
15827 return *this;
15828 }
15829
15830 /*!
15831 @brief add an object to an array
15832 @copydoc push_back(basic_json&&)
15833 */
push_back(const basic_json & val)15834 void push_back(const basic_json& val)
15835 {
15836 // push_back only works for null objects or arrays
15837 if (JSON_UNLIKELY(not(is_null() or is_array())))
15838 {
15839 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15840 }
15841
15842 // transform null object into an array
15843 if (is_null())
15844 {
15845 m_type = value_t::array;
15846 m_value = value_t::array;
15847 assert_invariant();
15848 }
15849
15850 // add element to array
15851 m_value.array->push_back(val);
15852 }
15853
15854 /*!
15855 @brief add an object to an array
15856 @copydoc push_back(basic_json&&)
15857 */
operator +=(const basic_json & val)15858 reference operator+=(const basic_json& val)
15859 {
15860 push_back(val);
15861 return *this;
15862 }
15863
15864 /*!
15865 @brief add an object to an object
15866
15867 Inserts the given element @a val to the JSON object. If the function is
15868 called on a JSON null value, an empty object is created before inserting
15869 @a val.
15870
15871 @param[in] val the value to add to the JSON object
15872
15873 @throw type_error.308 when called on a type other than JSON object or
15874 null; example: `"cannot use push_back() with number"`
15875
15876 @complexity Logarithmic in the size of the container, O(log(`size()`)).
15877
15878 @liveexample{The example shows how `push_back()` and `+=` can be used to
15879 add elements to a JSON object. Note how the `null` value was silently
15880 converted to a JSON object.,push_back__object_t__value}
15881
15882 @since version 1.0.0
15883 */
push_back(const typename object_t::value_type & val)15884 void push_back(const typename object_t::value_type& val)
15885 {
15886 // push_back only works for null objects or objects
15887 if (JSON_UNLIKELY(not(is_null() or is_object())))
15888 {
15889 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15890 }
15891
15892 // transform null object into an object
15893 if (is_null())
15894 {
15895 m_type = value_t::object;
15896 m_value = value_t::object;
15897 assert_invariant();
15898 }
15899
15900 // add element to array
15901 m_value.object->insert(val);
15902 }
15903
15904 /*!
15905 @brief add an object to an object
15906 @copydoc push_back(const typename object_t::value_type&)
15907 */
operator +=(const typename object_t::value_type & val)15908 reference operator+=(const typename object_t::value_type& val)
15909 {
15910 push_back(val);
15911 return *this;
15912 }
15913
15914 /*!
15915 @brief add an object to an object
15916
15917 This function allows to use `push_back` with an initializer list. In case
15918
15919 1. the current value is an object,
15920 2. the initializer list @a init contains only two elements, and
15921 3. the first element of @a init is a string,
15922
15923 @a init is converted into an object element and added using
15924 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
15925 is converted to a JSON value and added using @ref push_back(basic_json&&).
15926
15927 @param[in] init an initializer list
15928
15929 @complexity Linear in the size of the initializer list @a init.
15930
15931 @note This function is required to resolve an ambiguous overload error,
15932 because pairs like `{"key", "value"}` can be both interpreted as
15933 `object_t::value_type` or `std::initializer_list<basic_json>`, see
15934 https://github.com/nlohmann/json/issues/235 for more information.
15935
15936 @liveexample{The example shows how initializer lists are treated as
15937 objects when possible.,push_back__initializer_list}
15938 */
push_back(initializer_list_t init)15939 void push_back(initializer_list_t init)
15940 {
15941 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
15942 {
15943 basic_json&& key = init.begin()->moved_or_copied();
15944 push_back(typename object_t::value_type(
15945 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
15946 }
15947 else
15948 {
15949 push_back(basic_json(init));
15950 }
15951 }
15952
15953 /*!
15954 @brief add an object to an object
15955 @copydoc push_back(initializer_list_t)
15956 */
operator +=(initializer_list_t init)15957 reference operator+=(initializer_list_t init)
15958 {
15959 push_back(init);
15960 return *this;
15961 }
15962
15963 /*!
15964 @brief add an object to an array
15965
15966 Creates a JSON value from the passed parameters @a args to the end of the
15967 JSON value. If the function is called on a JSON null value, an empty array
15968 is created before appending the value created from @a args.
15969
15970 @param[in] args arguments to forward to a constructor of @ref basic_json
15971 @tparam Args compatible types to create a @ref basic_json object
15972
15973 @throw type_error.311 when called on a type other than JSON array or
15974 null; example: `"cannot use emplace_back() with number"`
15975
15976 @complexity Amortized constant.
15977
15978 @liveexample{The example shows how `push_back()` can be used to add
15979 elements to a JSON array. Note how the `null` value was silently converted
15980 to a JSON array.,emplace_back}
15981
15982 @since version 2.0.8
15983 */
15984 template<class... Args>
emplace_back(Args &&...args)15985 void emplace_back(Args&& ... args)
15986 {
15987 // emplace_back only works for null objects or arrays
15988 if (JSON_UNLIKELY(not(is_null() or is_array())))
15989 {
15990 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
15991 }
15992
15993 // transform null object into an array
15994 if (is_null())
15995 {
15996 m_type = value_t::array;
15997 m_value = value_t::array;
15998 assert_invariant();
15999 }
16000
16001 // add element to array (perfect forwarding)
16002 m_value.array->emplace_back(std::forward<Args>(args)...);
16003 }
16004
16005 /*!
16006 @brief add an object to an object if key does not exist
16007
16008 Inserts a new element into a JSON object constructed in-place with the
16009 given @a args if there is no element with the key in the container. If the
16010 function is called on a JSON null value, an empty object is created before
16011 appending the value created from @a args.
16012
16013 @param[in] args arguments to forward to a constructor of @ref basic_json
16014 @tparam Args compatible types to create a @ref basic_json object
16015
16016 @return a pair consisting of an iterator to the inserted element, or the
16017 already-existing element if no insertion happened, and a bool
16018 denoting whether the insertion took place.
16019
16020 @throw type_error.311 when called on a type other than JSON object or
16021 null; example: `"cannot use emplace() with number"`
16022
16023 @complexity Logarithmic in the size of the container, O(log(`size()`)).
16024
16025 @liveexample{The example shows how `emplace()` can be used to add elements
16026 to a JSON object. Note how the `null` value was silently converted to a
16027 JSON object. Further note how no value is added if there was already one
16028 value stored with the same key.,emplace}
16029
16030 @since version 2.0.8
16031 */
16032 template<class... Args>
emplace(Args &&...args)16033 std::pair<iterator, bool> emplace(Args&& ... args)
16034 {
16035 // emplace only works for null objects or arrays
16036 if (JSON_UNLIKELY(not(is_null() or is_object())))
16037 {
16038 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
16039 }
16040
16041 // transform null object into an object
16042 if (is_null())
16043 {
16044 m_type = value_t::object;
16045 m_value = value_t::object;
16046 assert_invariant();
16047 }
16048
16049 // add element to array (perfect forwarding)
16050 auto res = m_value.object->emplace(std::forward<Args>(args)...);
16051 // create result iterator and set iterator to the result of emplace
16052 auto it = begin();
16053 it.m_it.object_iterator = res.first;
16054
16055 // return pair of iterator and boolean
16056 return {it, res.second};
16057 }
16058
16059 /// Helper for insertion of an iterator
16060 /// @note: This uses std::distance to support GCC 4.8,
16061 /// see https://github.com/nlohmann/json/pull/1257
16062 template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)16063 iterator insert_iterator(const_iterator pos, Args&& ... args)
16064 {
16065 iterator result(this);
16066 assert(m_value.array != nullptr);
16067
16068 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
16069 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
16070 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
16071
16072 // This could have been written as:
16073 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
16074 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
16075
16076 return result;
16077 }
16078
16079 /*!
16080 @brief inserts element
16081
16082 Inserts element @a val before iterator @a pos.
16083
16084 @param[in] pos iterator before which the content will be inserted; may be
16085 the end() iterator
16086 @param[in] val element to insert
16087 @return iterator pointing to the inserted @a val.
16088
16089 @throw type_error.309 if called on JSON values other than arrays;
16090 example: `"cannot use insert() with string"`
16091 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16092 example: `"iterator does not fit current value"`
16093
16094 @complexity Constant plus linear in the distance between @a pos and end of
16095 the container.
16096
16097 @liveexample{The example shows how `insert()` is used.,insert}
16098
16099 @since version 1.0.0
16100 */
insert(const_iterator pos,const basic_json & val)16101 iterator insert(const_iterator pos, const basic_json& val)
16102 {
16103 // insert only works for arrays
16104 if (JSON_LIKELY(is_array()))
16105 {
16106 // check if iterator pos fits to this JSON value
16107 if (JSON_UNLIKELY(pos.m_object != this))
16108 {
16109 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16110 }
16111
16112 // insert to array and return iterator
16113 return insert_iterator(pos, val);
16114 }
16115
16116 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16117 }
16118
16119 /*!
16120 @brief inserts element
16121 @copydoc insert(const_iterator, const basic_json&)
16122 */
insert(const_iterator pos,basic_json && val)16123 iterator insert(const_iterator pos, basic_json&& val)
16124 {
16125 return insert(pos, val);
16126 }
16127
16128 /*!
16129 @brief inserts elements
16130
16131 Inserts @a cnt copies of @a val before iterator @a pos.
16132
16133 @param[in] pos iterator before which the content will be inserted; may be
16134 the end() iterator
16135 @param[in] cnt number of copies of @a val to insert
16136 @param[in] val element to insert
16137 @return iterator pointing to the first element inserted, or @a pos if
16138 `cnt==0`
16139
16140 @throw type_error.309 if called on JSON values other than arrays; example:
16141 `"cannot use insert() with string"`
16142 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16143 example: `"iterator does not fit current value"`
16144
16145 @complexity Linear in @a cnt plus linear in the distance between @a pos
16146 and end of the container.
16147
16148 @liveexample{The example shows how `insert()` is used.,insert__count}
16149
16150 @since version 1.0.0
16151 */
insert(const_iterator pos,size_type cnt,const basic_json & val)16152 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
16153 {
16154 // insert only works for arrays
16155 if (JSON_LIKELY(is_array()))
16156 {
16157 // check if iterator pos fits to this JSON value
16158 if (JSON_UNLIKELY(pos.m_object != this))
16159 {
16160 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16161 }
16162
16163 // insert to array and return iterator
16164 return insert_iterator(pos, cnt, val);
16165 }
16166
16167 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16168 }
16169
16170 /*!
16171 @brief inserts elements
16172
16173 Inserts elements from range `[first, last)` before iterator @a pos.
16174
16175 @param[in] pos iterator before which the content will be inserted; may be
16176 the end() iterator
16177 @param[in] first begin of the range of elements to insert
16178 @param[in] last end of the range of elements to insert
16179
16180 @throw type_error.309 if called on JSON values other than arrays; example:
16181 `"cannot use insert() with string"`
16182 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16183 example: `"iterator does not fit current value"`
16184 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16185 same JSON value; example: `"iterators do not fit"`
16186 @throw invalid_iterator.211 if @a first or @a last are iterators into
16187 container for which insert is called; example: `"passed iterators may not
16188 belong to container"`
16189
16190 @return iterator pointing to the first element inserted, or @a pos if
16191 `first==last`
16192
16193 @complexity Linear in `std::distance(first, last)` plus linear in the
16194 distance between @a pos and end of the container.
16195
16196 @liveexample{The example shows how `insert()` is used.,insert__range}
16197
16198 @since version 1.0.0
16199 */
insert(const_iterator pos,const_iterator first,const_iterator last)16200 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
16201 {
16202 // insert only works for arrays
16203 if (JSON_UNLIKELY(not is_array()))
16204 {
16205 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16206 }
16207
16208 // check if iterator pos fits to this JSON value
16209 if (JSON_UNLIKELY(pos.m_object != this))
16210 {
16211 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16212 }
16213
16214 // check if range iterators belong to the same JSON object
16215 if (JSON_UNLIKELY(first.m_object != last.m_object))
16216 {
16217 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16218 }
16219
16220 if (JSON_UNLIKELY(first.m_object == this))
16221 {
16222 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
16223 }
16224
16225 // insert to array and return iterator
16226 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
16227 }
16228
16229 /*!
16230 @brief inserts elements
16231
16232 Inserts elements from initializer list @a ilist before iterator @a pos.
16233
16234 @param[in] pos iterator before which the content will be inserted; may be
16235 the end() iterator
16236 @param[in] ilist initializer list to insert the values from
16237
16238 @throw type_error.309 if called on JSON values other than arrays; example:
16239 `"cannot use insert() with string"`
16240 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16241 example: `"iterator does not fit current value"`
16242
16243 @return iterator pointing to the first element inserted, or @a pos if
16244 `ilist` is empty
16245
16246 @complexity Linear in `ilist.size()` plus linear in the distance between
16247 @a pos and end of the container.
16248
16249 @liveexample{The example shows how `insert()` is used.,insert__ilist}
16250
16251 @since version 1.0.0
16252 */
insert(const_iterator pos,initializer_list_t ilist)16253 iterator insert(const_iterator pos, initializer_list_t ilist)
16254 {
16255 // insert only works for arrays
16256 if (JSON_UNLIKELY(not is_array()))
16257 {
16258 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16259 }
16260
16261 // check if iterator pos fits to this JSON value
16262 if (JSON_UNLIKELY(pos.m_object != this))
16263 {
16264 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16265 }
16266
16267 // insert to array and return iterator
16268 return insert_iterator(pos, ilist.begin(), ilist.end());
16269 }
16270
16271 /*!
16272 @brief inserts elements
16273
16274 Inserts elements from range `[first, last)`.
16275
16276 @param[in] first begin of the range of elements to insert
16277 @param[in] last end of the range of elements to insert
16278
16279 @throw type_error.309 if called on JSON values other than objects; example:
16280 `"cannot use insert() with string"`
16281 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16282 point to an object; example: `"iterators first and last must point to
16283 objects"`
16284 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16285 same JSON value; example: `"iterators do not fit"`
16286
16287 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
16288 of elements to insert.
16289
16290 @liveexample{The example shows how `insert()` is used.,insert__range_object}
16291
16292 @since version 3.0.0
16293 */
insert(const_iterator first,const_iterator last)16294 void insert(const_iterator first, const_iterator last)
16295 {
16296 // insert only works for objects
16297 if (JSON_UNLIKELY(not is_object()))
16298 {
16299 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16300 }
16301
16302 // check if range iterators belong to the same JSON object
16303 if (JSON_UNLIKELY(first.m_object != last.m_object))
16304 {
16305 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16306 }
16307
16308 // passed iterators must belong to objects
16309 if (JSON_UNLIKELY(not first.m_object->is_object()))
16310 {
16311 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16312 }
16313
16314 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
16315 }
16316
16317 /*!
16318 @brief updates a JSON object from another object, overwriting existing keys
16319
16320 Inserts all values from JSON object @a j and overwrites existing keys.
16321
16322 @param[in] j JSON object to read values from
16323
16324 @throw type_error.312 if called on JSON values other than objects; example:
16325 `"cannot use update() with string"`
16326
16327 @complexity O(N*log(size() + N)), where N is the number of elements to
16328 insert.
16329
16330 @liveexample{The example shows how `update()` is used.,update}
16331
16332 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16333
16334 @since version 3.0.0
16335 */
update(const_reference j)16336 void update(const_reference j)
16337 {
16338 // implicitly convert null value to an empty object
16339 if (is_null())
16340 {
16341 m_type = value_t::object;
16342 m_value.object = create<object_t>();
16343 assert_invariant();
16344 }
16345
16346 if (JSON_UNLIKELY(not is_object()))
16347 {
16348 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16349 }
16350 if (JSON_UNLIKELY(not j.is_object()))
16351 {
16352 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
16353 }
16354
16355 for (auto it = j.cbegin(); it != j.cend(); ++it)
16356 {
16357 m_value.object->operator[](it.key()) = it.value();
16358 }
16359 }
16360
16361 /*!
16362 @brief updates a JSON object from another object, overwriting existing keys
16363
16364 Inserts all values from from range `[first, last)` and overwrites existing
16365 keys.
16366
16367 @param[in] first begin of the range of elements to insert
16368 @param[in] last end of the range of elements to insert
16369
16370 @throw type_error.312 if called on JSON values other than objects; example:
16371 `"cannot use update() with string"`
16372 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16373 point to an object; example: `"iterators first and last must point to
16374 objects"`
16375 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16376 same JSON value; example: `"iterators do not fit"`
16377
16378 @complexity O(N*log(size() + N)), where N is the number of elements to
16379 insert.
16380
16381 @liveexample{The example shows how `update()` is used__range.,update}
16382
16383 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16384
16385 @since version 3.0.0
16386 */
update(const_iterator first,const_iterator last)16387 void update(const_iterator first, const_iterator last)
16388 {
16389 // implicitly convert null value to an empty object
16390 if (is_null())
16391 {
16392 m_type = value_t::object;
16393 m_value.object = create<object_t>();
16394 assert_invariant();
16395 }
16396
16397 if (JSON_UNLIKELY(not is_object()))
16398 {
16399 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16400 }
16401
16402 // check if range iterators belong to the same JSON object
16403 if (JSON_UNLIKELY(first.m_object != last.m_object))
16404 {
16405 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16406 }
16407
16408 // passed iterators must belong to objects
16409 if (JSON_UNLIKELY(not first.m_object->is_object()
16410 or not last.m_object->is_object()))
16411 {
16412 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16413 }
16414
16415 for (auto it = first; it != last; ++it)
16416 {
16417 m_value.object->operator[](it.key()) = it.value();
16418 }
16419 }
16420
16421 /*!
16422 @brief exchanges the values
16423
16424 Exchanges the contents of the JSON value with those of @a other. Does not
16425 invoke any move, copy, or swap operations on individual elements. All
16426 iterators and references remain valid. The past-the-end iterator is
16427 invalidated.
16428
16429 @param[in,out] other JSON value to exchange the contents with
16430
16431 @complexity Constant.
16432
16433 @liveexample{The example below shows how JSON values can be swapped with
16434 `swap()`.,swap__reference}
16435
16436 @since version 1.0.0
16437 */
swap(reference other)16438 void swap(reference other) noexcept (
16439 std::is_nothrow_move_constructible<value_t>::value and
16440 std::is_nothrow_move_assignable<value_t>::value and
16441 std::is_nothrow_move_constructible<json_value>::value and
16442 std::is_nothrow_move_assignable<json_value>::value
16443 )
16444 {
16445 std::swap(m_type, other.m_type);
16446 std::swap(m_value, other.m_value);
16447 assert_invariant();
16448 }
16449
16450 /*!
16451 @brief exchanges the values
16452
16453 Exchanges the contents of a JSON array with those of @a other. Does not
16454 invoke any move, copy, or swap operations on individual elements. All
16455 iterators and references remain valid. The past-the-end iterator is
16456 invalidated.
16457
16458 @param[in,out] other array to exchange the contents with
16459
16460 @throw type_error.310 when JSON value is not an array; example: `"cannot
16461 use swap() with string"`
16462
16463 @complexity Constant.
16464
16465 @liveexample{The example below shows how arrays can be swapped with
16466 `swap()`.,swap__array_t}
16467
16468 @since version 1.0.0
16469 */
swap(array_t & other)16470 void swap(array_t& other)
16471 {
16472 // swap only works for arrays
16473 if (JSON_LIKELY(is_array()))
16474 {
16475 std::swap(*(m_value.array), other);
16476 }
16477 else
16478 {
16479 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16480 }
16481 }
16482
16483 /*!
16484 @brief exchanges the values
16485
16486 Exchanges the contents of a JSON object with those of @a other. Does not
16487 invoke any move, copy, or swap operations on individual elements. All
16488 iterators and references remain valid. The past-the-end iterator is
16489 invalidated.
16490
16491 @param[in,out] other object to exchange the contents with
16492
16493 @throw type_error.310 when JSON value is not an object; example:
16494 `"cannot use swap() with string"`
16495
16496 @complexity Constant.
16497
16498 @liveexample{The example below shows how objects can be swapped with
16499 `swap()`.,swap__object_t}
16500
16501 @since version 1.0.0
16502 */
swap(object_t & other)16503 void swap(object_t& other)
16504 {
16505 // swap only works for objects
16506 if (JSON_LIKELY(is_object()))
16507 {
16508 std::swap(*(m_value.object), other);
16509 }
16510 else
16511 {
16512 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16513 }
16514 }
16515
16516 /*!
16517 @brief exchanges the values
16518
16519 Exchanges the contents of a JSON string with those of @a other. Does not
16520 invoke any move, copy, or swap operations on individual elements. All
16521 iterators and references remain valid. The past-the-end iterator is
16522 invalidated.
16523
16524 @param[in,out] other string to exchange the contents with
16525
16526 @throw type_error.310 when JSON value is not a string; example: `"cannot
16527 use swap() with boolean"`
16528
16529 @complexity Constant.
16530
16531 @liveexample{The example below shows how strings can be swapped with
16532 `swap()`.,swap__string_t}
16533
16534 @since version 1.0.0
16535 */
swap(string_t & other)16536 void swap(string_t& other)
16537 {
16538 // swap only works for strings
16539 if (JSON_LIKELY(is_string()))
16540 {
16541 std::swap(*(m_value.string), other);
16542 }
16543 else
16544 {
16545 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16546 }
16547 }
16548
16549 /// @}
16550
16551 public:
16552 //////////////////////////////////////////
16553 // lexicographical comparison operators //
16554 //////////////////////////////////////////
16555
16556 /// @name lexicographical comparison operators
16557 /// @{
16558
16559 /*!
16560 @brief comparison: equal
16561
16562 Compares two JSON values for equality according to the following rules:
16563 - Two JSON values are equal if (1) they are from the same type and (2)
16564 their stored values are the same according to their respective
16565 `operator==`.
16566 - Integer and floating-point numbers are automatically converted before
16567 comparison. Note than two NaN values are always treated as unequal.
16568 - Two JSON null values are equal.
16569
16570 @note Floating-point inside JSON values numbers are compared with
16571 `json::number_float_t::operator==` which is `double::operator==` by
16572 default. To compare floating-point while respecting an epsilon, an alternative
16573 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
16574 could be used, for instance
16575 @code {.cpp}
16576 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
16577 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
16578 {
16579 return std::abs(a - b) <= epsilon;
16580 }
16581 @endcode
16582
16583 @note NaN values never compare equal to themselves or to other NaN values.
16584
16585 @param[in] lhs first JSON value to consider
16586 @param[in] rhs second JSON value to consider
16587 @return whether the values @a lhs and @a rhs are equal
16588
16589 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16590
16591 @complexity Linear.
16592
16593 @liveexample{The example demonstrates comparing several JSON
16594 types.,operator__equal}
16595
16596 @since version 1.0.0
16597 */
operator ==(const_reference lhs,const_reference rhs)16598 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
16599 {
16600 const auto lhs_type = lhs.type();
16601 const auto rhs_type = rhs.type();
16602
16603 if (lhs_type == rhs_type)
16604 {
16605 switch (lhs_type)
16606 {
16607 case value_t::array:
16608 return (*lhs.m_value.array == *rhs.m_value.array);
16609
16610 case value_t::object:
16611 return (*lhs.m_value.object == *rhs.m_value.object);
16612
16613 case value_t::null:
16614 return true;
16615
16616 case value_t::string:
16617 return (*lhs.m_value.string == *rhs.m_value.string);
16618
16619 case value_t::boolean:
16620 return (lhs.m_value.boolean == rhs.m_value.boolean);
16621
16622 case value_t::number_integer:
16623 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
16624
16625 case value_t::number_unsigned:
16626 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
16627
16628 case value_t::number_float:
16629 return (lhs.m_value.number_float == rhs.m_value.number_float);
16630
16631 default:
16632 return false;
16633 }
16634 }
16635 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16636 {
16637 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
16638 }
16639 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16640 {
16641 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
16642 }
16643 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16644 {
16645 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
16646 }
16647 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16648 {
16649 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
16650 }
16651 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16652 {
16653 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
16654 }
16655 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16656 {
16657 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
16658 }
16659
16660 return false;
16661 }
16662
16663 /*!
16664 @brief comparison: equal
16665 @copydoc operator==(const_reference, const_reference)
16666 */
16667 template<typename ScalarType, typename std::enable_if<
16668 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)16669 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
16670 {
16671 return (lhs == basic_json(rhs));
16672 }
16673
16674 /*!
16675 @brief comparison: equal
16676 @copydoc operator==(const_reference, const_reference)
16677 */
16678 template<typename ScalarType, typename std::enable_if<
16679 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)16680 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
16681 {
16682 return (basic_json(lhs) == rhs);
16683 }
16684
16685 /*!
16686 @brief comparison: not equal
16687
16688 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
16689
16690 @param[in] lhs first JSON value to consider
16691 @param[in] rhs second JSON value to consider
16692 @return whether the values @a lhs and @a rhs are not equal
16693
16694 @complexity Linear.
16695
16696 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16697
16698 @liveexample{The example demonstrates comparing several JSON
16699 types.,operator__notequal}
16700
16701 @since version 1.0.0
16702 */
operator !=(const_reference lhs,const_reference rhs)16703 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
16704 {
16705 return not (lhs == rhs);
16706 }
16707
16708 /*!
16709 @brief comparison: not equal
16710 @copydoc operator!=(const_reference, const_reference)
16711 */
16712 template<typename ScalarType, typename std::enable_if<
16713 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)16714 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
16715 {
16716 return (lhs != basic_json(rhs));
16717 }
16718
16719 /*!
16720 @brief comparison: not equal
16721 @copydoc operator!=(const_reference, const_reference)
16722 */
16723 template<typename ScalarType, typename std::enable_if<
16724 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)16725 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
16726 {
16727 return (basic_json(lhs) != rhs);
16728 }
16729
16730 /*!
16731 @brief comparison: less than
16732
16733 Compares whether one JSON value @a lhs is less than another JSON value @a
16734 rhs according to the following rules:
16735 - If @a lhs and @a rhs have the same type, the values are compared using
16736 the default `<` operator.
16737 - Integer and floating-point numbers are automatically converted before
16738 comparison
16739 - In case @a lhs and @a rhs have different types, the values are ignored
16740 and the order of the types is considered, see
16741 @ref operator<(const value_t, const value_t).
16742
16743 @param[in] lhs first JSON value to consider
16744 @param[in] rhs second JSON value to consider
16745 @return whether @a lhs is less than @a rhs
16746
16747 @complexity Linear.
16748
16749 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16750
16751 @liveexample{The example demonstrates comparing several JSON
16752 types.,operator__less}
16753
16754 @since version 1.0.0
16755 */
operator <(const_reference lhs,const_reference rhs)16756 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
16757 {
16758 const auto lhs_type = lhs.type();
16759 const auto rhs_type = rhs.type();
16760
16761 if (lhs_type == rhs_type)
16762 {
16763 switch (lhs_type)
16764 {
16765 case value_t::array:
16766 return (*lhs.m_value.array) < (*rhs.m_value.array);
16767
16768 case value_t::object:
16769 return *lhs.m_value.object < *rhs.m_value.object;
16770
16771 case value_t::null:
16772 return false;
16773
16774 case value_t::string:
16775 return *lhs.m_value.string < *rhs.m_value.string;
16776
16777 case value_t::boolean:
16778 return lhs.m_value.boolean < rhs.m_value.boolean;
16779
16780 case value_t::number_integer:
16781 return lhs.m_value.number_integer < rhs.m_value.number_integer;
16782
16783 case value_t::number_unsigned:
16784 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
16785
16786 case value_t::number_float:
16787 return lhs.m_value.number_float < rhs.m_value.number_float;
16788
16789 default:
16790 return false;
16791 }
16792 }
16793 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16794 {
16795 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
16796 }
16797 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16798 {
16799 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
16800 }
16801 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16802 {
16803 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
16804 }
16805 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16806 {
16807 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
16808 }
16809 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16810 {
16811 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
16812 }
16813 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16814 {
16815 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
16816 }
16817
16818 // We only reach this line if we cannot compare values. In that case,
16819 // we compare types. Note we have to call the operator explicitly,
16820 // because MSVC has problems otherwise.
16821 return operator<(lhs_type, rhs_type);
16822 }
16823
16824 /*!
16825 @brief comparison: less than
16826 @copydoc operator<(const_reference, const_reference)
16827 */
16828 template<typename ScalarType, typename std::enable_if<
16829 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)16830 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
16831 {
16832 return (lhs < basic_json(rhs));
16833 }
16834
16835 /*!
16836 @brief comparison: less than
16837 @copydoc operator<(const_reference, const_reference)
16838 */
16839 template<typename ScalarType, typename std::enable_if<
16840 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)16841 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
16842 {
16843 return (basic_json(lhs) < rhs);
16844 }
16845
16846 /*!
16847 @brief comparison: less than or equal
16848
16849 Compares whether one JSON value @a lhs is less than or equal to another
16850 JSON value by calculating `not (rhs < lhs)`.
16851
16852 @param[in] lhs first JSON value to consider
16853 @param[in] rhs second JSON value to consider
16854 @return whether @a lhs is less than or equal to @a rhs
16855
16856 @complexity Linear.
16857
16858 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16859
16860 @liveexample{The example demonstrates comparing several JSON
16861 types.,operator__greater}
16862
16863 @since version 1.0.0
16864 */
operator <=(const_reference lhs,const_reference rhs)16865 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
16866 {
16867 return not (rhs < lhs);
16868 }
16869
16870 /*!
16871 @brief comparison: less than or equal
16872 @copydoc operator<=(const_reference, const_reference)
16873 */
16874 template<typename ScalarType, typename std::enable_if<
16875 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)16876 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
16877 {
16878 return (lhs <= basic_json(rhs));
16879 }
16880
16881 /*!
16882 @brief comparison: less than or equal
16883 @copydoc operator<=(const_reference, const_reference)
16884 */
16885 template<typename ScalarType, typename std::enable_if<
16886 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)16887 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
16888 {
16889 return (basic_json(lhs) <= rhs);
16890 }
16891
16892 /*!
16893 @brief comparison: greater than
16894
16895 Compares whether one JSON value @a lhs is greater than another
16896 JSON value by calculating `not (lhs <= rhs)`.
16897
16898 @param[in] lhs first JSON value to consider
16899 @param[in] rhs second JSON value to consider
16900 @return whether @a lhs is greater than to @a rhs
16901
16902 @complexity Linear.
16903
16904 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16905
16906 @liveexample{The example demonstrates comparing several JSON
16907 types.,operator__lessequal}
16908
16909 @since version 1.0.0
16910 */
operator >(const_reference lhs,const_reference rhs)16911 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
16912 {
16913 return not (lhs <= rhs);
16914 }
16915
16916 /*!
16917 @brief comparison: greater than
16918 @copydoc operator>(const_reference, const_reference)
16919 */
16920 template<typename ScalarType, typename std::enable_if<
16921 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)16922 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
16923 {
16924 return (lhs > basic_json(rhs));
16925 }
16926
16927 /*!
16928 @brief comparison: greater than
16929 @copydoc operator>(const_reference, const_reference)
16930 */
16931 template<typename ScalarType, typename std::enable_if<
16932 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)16933 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
16934 {
16935 return (basic_json(lhs) > rhs);
16936 }
16937
16938 /*!
16939 @brief comparison: greater than or equal
16940
16941 Compares whether one JSON value @a lhs is greater than or equal to another
16942 JSON value by calculating `not (lhs < rhs)`.
16943
16944 @param[in] lhs first JSON value to consider
16945 @param[in] rhs second JSON value to consider
16946 @return whether @a lhs is greater than or equal to @a rhs
16947
16948 @complexity Linear.
16949
16950 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16951
16952 @liveexample{The example demonstrates comparing several JSON
16953 types.,operator__greaterequal}
16954
16955 @since version 1.0.0
16956 */
operator >=(const_reference lhs,const_reference rhs)16957 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
16958 {
16959 return not (lhs < rhs);
16960 }
16961
16962 /*!
16963 @brief comparison: greater than or equal
16964 @copydoc operator>=(const_reference, const_reference)
16965 */
16966 template<typename ScalarType, typename std::enable_if<
16967 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)16968 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
16969 {
16970 return (lhs >= basic_json(rhs));
16971 }
16972
16973 /*!
16974 @brief comparison: greater than or equal
16975 @copydoc operator>=(const_reference, const_reference)
16976 */
16977 template<typename ScalarType, typename std::enable_if<
16978 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)16979 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
16980 {
16981 return (basic_json(lhs) >= rhs);
16982 }
16983
16984 /// @}
16985
16986 ///////////////////
16987 // serialization //
16988 ///////////////////
16989
16990 /// @name serialization
16991 /// @{
16992
16993 /*!
16994 @brief serialize to stream
16995
16996 Serialize the given JSON value @a j to the output stream @a o. The JSON
16997 value will be serialized using the @ref dump member function.
16998
16999 - The indentation of the output can be controlled with the member variable
17000 `width` of the output stream @a o. For instance, using the manipulator
17001 `std::setw(4)` on @a o sets the indentation level to `4` and the
17002 serialization result is the same as calling `dump(4)`.
17003
17004 - The indentation character can be controlled with the member variable
17005 `fill` of the output stream @a o. For instance, the manipulator
17006 `std::setfill('\\t')` sets indentation to use a tab character rather than
17007 the default space character.
17008
17009 @param[in,out] o stream to serialize to
17010 @param[in] j JSON value to serialize
17011
17012 @return the stream @a o
17013
17014 @throw type_error.316 if a string stored inside the JSON value is not
17015 UTF-8 encoded
17016
17017 @complexity Linear.
17018
17019 @liveexample{The example below shows the serialization with different
17020 parameters to `width` to adjust the indentation level.,operator_serialize}
17021
17022 @since version 1.0.0; indentation character added in version 3.0.0
17023 */
operator <<(std::ostream & o,const basic_json & j)17024 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
17025 {
17026 // read width member and use it as indentation parameter if nonzero
17027 const bool pretty_print = (o.width() > 0);
17028 const auto indentation = (pretty_print ? o.width() : 0);
17029
17030 // reset width to 0 for subsequent calls to this stream
17031 o.width(0);
17032
17033 // do the actual serialization
17034 serializer s(detail::output_adapter<char>(o), o.fill());
17035 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
17036 return o;
17037 }
17038
17039 /*!
17040 @brief serialize to stream
17041 @deprecated This stream operator is deprecated and will be removed in
17042 future 4.0.0 of the library. Please use
17043 @ref operator<<(std::ostream&, const basic_json&)
17044 instead; that is, replace calls like `j >> o;` with `o << j;`.
17045 @since version 1.0.0; deprecated since version 3.0.0
17046 */
17047 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)17048 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
17049 {
17050 return o << j;
17051 }
17052
17053 /// @}
17054
17055
17056 /////////////////////
17057 // deserialization //
17058 /////////////////////
17059
17060 /// @name deserialization
17061 /// @{
17062
17063 /*!
17064 @brief deserialize from a compatible input
17065
17066 This function reads from a compatible input. Examples are:
17067 - an array of 1-byte values
17068 - strings with character/literal type with size of 1 byte
17069 - input streams
17070 - container with contiguous storage of 1-byte values. Compatible container
17071 types include `std::vector`, `std::string`, `std::array`,
17072 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17073 arrays can be used with `std::begin()`/`std::end()`. User-defined
17074 containers can be used as long as they implement random-access iterators
17075 and a contiguous storage.
17076
17077 @pre Each element of the container has a size of 1 byte. Violating this
17078 precondition yields undefined behavior. **This precondition is enforced
17079 with a static assertion.**
17080
17081 @pre The container storage is contiguous. Violating this precondition
17082 yields undefined behavior. **This precondition is enforced with an
17083 assertion.**
17084 @pre Each element of the container has a size of 1 byte. Violating this
17085 precondition yields undefined behavior. **This precondition is enforced
17086 with a static assertion.**
17087
17088 @warning There is no way to enforce all preconditions at compile-time. If
17089 the function is called with a noncompliant container and with
17090 assertions switched off, the behavior is undefined and will most
17091 likely yield segmentation violation.
17092
17093 @param[in] i input to read from
17094 @param[in] cb a parser callback function of type @ref parser_callback_t
17095 which is used to control the deserialization by filtering unwanted values
17096 (optional)
17097
17098 @return result of the deserialization
17099
17100 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17101 of input; expected string literal""`
17102 @throw parse_error.102 if to_unicode fails or surrogate error
17103 @throw parse_error.103 if to_unicode fails
17104
17105 @complexity Linear in the length of the input. The parser is a predictive
17106 LL(1) parser. The complexity can be higher if the parser callback function
17107 @a cb has a super-linear complexity.
17108
17109 @note A UTF-8 byte order mark is silently ignored.
17110
17111 @liveexample{The example below demonstrates the `parse()` function reading
17112 from an array.,parse__array__parser_callback_t}
17113
17114 @liveexample{The example below demonstrates the `parse()` function with
17115 and without callback function.,parse__string__parser_callback_t}
17116
17117 @liveexample{The example below demonstrates the `parse()` function with
17118 and without callback function.,parse__istream__parser_callback_t}
17119
17120 @liveexample{The example below demonstrates the `parse()` function reading
17121 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
17122
17123 @since version 2.0.3 (contiguous containers)
17124 */
parse(detail::input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)17125 static basic_json parse(detail::input_adapter&& i,
17126 const parser_callback_t cb = nullptr,
17127 const bool allow_exceptions = true)
17128 {
17129 basic_json result;
17130 parser(i, cb, allow_exceptions).parse(true, result);
17131 return result;
17132 }
17133
accept(detail::input_adapter && i)17134 static bool accept(detail::input_adapter&& i)
17135 {
17136 return parser(i).accept(true);
17137 }
17138
17139 /*!
17140 @brief generate SAX events
17141
17142 The SAX event lister must follow the interface of @ref json_sax.
17143
17144 This function reads from a compatible input. Examples are:
17145 - an array of 1-byte values
17146 - strings with character/literal type with size of 1 byte
17147 - input streams
17148 - container with contiguous storage of 1-byte values. Compatible container
17149 types include `std::vector`, `std::string`, `std::array`,
17150 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17151 arrays can be used with `std::begin()`/`std::end()`. User-defined
17152 containers can be used as long as they implement random-access iterators
17153 and a contiguous storage.
17154
17155 @pre Each element of the container has a size of 1 byte. Violating this
17156 precondition yields undefined behavior. **This precondition is enforced
17157 with a static assertion.**
17158
17159 @pre The container storage is contiguous. Violating this precondition
17160 yields undefined behavior. **This precondition is enforced with an
17161 assertion.**
17162 @pre Each element of the container has a size of 1 byte. Violating this
17163 precondition yields undefined behavior. **This precondition is enforced
17164 with a static assertion.**
17165
17166 @warning There is no way to enforce all preconditions at compile-time. If
17167 the function is called with a noncompliant container and with
17168 assertions switched off, the behavior is undefined and will most
17169 likely yield segmentation violation.
17170
17171 @param[in] i input to read from
17172 @param[in,out] sax SAX event listener
17173 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
17174 @param[in] strict whether the input has to be consumed completely
17175
17176 @return return value of the last processed SAX event
17177
17178 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17179 of input; expected string literal""`
17180 @throw parse_error.102 if to_unicode fails or surrogate error
17181 @throw parse_error.103 if to_unicode fails
17182
17183 @complexity Linear in the length of the input. The parser is a predictive
17184 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
17185 a super-linear complexity.
17186
17187 @note A UTF-8 byte order mark is silently ignored.
17188
17189 @liveexample{The example below demonstrates the `sax_parse()` function
17190 reading from string and processing the events with a user-defined SAX
17191 event consumer.,sax_parse}
17192
17193 @since version 3.2.0
17194 */
17195 template <typename SAX>
sax_parse(detail::input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true)17196 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
17197 input_format_t format = input_format_t::json,
17198 const bool strict = true)
17199 {
17200 assert(sax);
17201 switch (format)
17202 {
17203 case input_format_t::json:
17204 return parser(std::move(i)).sax_parse(sax, strict);
17205 default:
17206 return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
17207 }
17208 }
17209
17210 /*!
17211 @brief deserialize from an iterator range with contiguous storage
17212
17213 This function reads from an iterator range of a container with contiguous
17214 storage of 1-byte values. Compatible container types include
17215 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
17216 `std::initializer_list`. Furthermore, C-style arrays can be used with
17217 `std::begin()`/`std::end()`. User-defined containers can be used as long
17218 as they implement random-access iterators and a contiguous storage.
17219
17220 @pre The iterator range is contiguous. Violating this precondition yields
17221 undefined behavior. **This precondition is enforced with an assertion.**
17222 @pre Each element in the range has a size of 1 byte. Violating this
17223 precondition yields undefined behavior. **This precondition is enforced
17224 with a static assertion.**
17225
17226 @warning There is no way to enforce all preconditions at compile-time. If
17227 the function is called with noncompliant iterators and with
17228 assertions switched off, the behavior is undefined and will most
17229 likely yield segmentation violation.
17230
17231 @tparam IteratorType iterator of container with contiguous storage
17232 @param[in] first begin of the range to parse (included)
17233 @param[in] last end of the range to parse (excluded)
17234 @param[in] cb a parser callback function of type @ref parser_callback_t
17235 which is used to control the deserialization by filtering unwanted values
17236 (optional)
17237 @param[in] allow_exceptions whether to throw exceptions in case of a
17238 parse error (optional, true by default)
17239
17240 @return result of the deserialization
17241
17242 @throw parse_error.101 in case of an unexpected token
17243 @throw parse_error.102 if to_unicode fails or surrogate error
17244 @throw parse_error.103 if to_unicode fails
17245
17246 @complexity Linear in the length of the input. The parser is a predictive
17247 LL(1) parser. The complexity can be higher if the parser callback function
17248 @a cb has a super-linear complexity.
17249
17250 @note A UTF-8 byte order mark is silently ignored.
17251
17252 @liveexample{The example below demonstrates the `parse()` function reading
17253 from an iterator range.,parse__iteratortype__parser_callback_t}
17254
17255 @since version 2.0.3
17256 */
17257 template<class IteratorType, typename std::enable_if<
17258 std::is_base_of<
17259 std::random_access_iterator_tag,
17260 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)17261 static basic_json parse(IteratorType first, IteratorType last,
17262 const parser_callback_t cb = nullptr,
17263 const bool allow_exceptions = true)
17264 {
17265 basic_json result;
17266 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
17267 return result;
17268 }
17269
17270 template<class IteratorType, typename std::enable_if<
17271 std::is_base_of<
17272 std::random_access_iterator_tag,
17273 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)17274 static bool accept(IteratorType first, IteratorType last)
17275 {
17276 return parser(detail::input_adapter(first, last)).accept(true);
17277 }
17278
17279 template<class IteratorType, class SAX, typename std::enable_if<
17280 std::is_base_of<
17281 std::random_access_iterator_tag,
17282 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
sax_parse(IteratorType first,IteratorType last,SAX * sax)17283 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
17284 {
17285 return parser(detail::input_adapter(first, last)).sax_parse(sax);
17286 }
17287
17288 /*!
17289 @brief deserialize from stream
17290 @deprecated This stream operator is deprecated and will be removed in
17291 version 4.0.0 of the library. Please use
17292 @ref operator>>(std::istream&, basic_json&)
17293 instead; that is, replace calls like `j << i;` with `i >> j;`.
17294 @since version 1.0.0; deprecated since version 3.0.0
17295 */
17296 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)17297 friend std::istream& operator<<(basic_json& j, std::istream& i)
17298 {
17299 return operator>>(i, j);
17300 }
17301
17302 /*!
17303 @brief deserialize from stream
17304
17305 Deserializes an input stream to a JSON value.
17306
17307 @param[in,out] i input stream to read a serialized JSON value from
17308 @param[in,out] j JSON value to write the deserialized input to
17309
17310 @throw parse_error.101 in case of an unexpected token
17311 @throw parse_error.102 if to_unicode fails or surrogate error
17312 @throw parse_error.103 if to_unicode fails
17313
17314 @complexity Linear in the length of the input. The parser is a predictive
17315 LL(1) parser.
17316
17317 @note A UTF-8 byte order mark is silently ignored.
17318
17319 @liveexample{The example below shows how a JSON value is constructed by
17320 reading a serialization from a stream.,operator_deserialize}
17321
17322 @sa parse(std::istream&, const parser_callback_t) for a variant with a
17323 parser callback function to filter values while parsing
17324
17325 @since version 1.0.0
17326 */
operator >>(std::istream & i,basic_json & j)17327 friend std::istream& operator>>(std::istream& i, basic_json& j)
17328 {
17329 parser(detail::input_adapter(i)).parse(false, j);
17330 return i;
17331 }
17332
17333 /// @}
17334
17335 ///////////////////////////
17336 // convenience functions //
17337 ///////////////////////////
17338
17339 /*!
17340 @brief return the type as string
17341
17342 Returns the type name as string to be used in error messages - usually to
17343 indicate that a function was called on a wrong JSON type.
17344
17345 @return a string representation of a the @a m_type member:
17346 Value type | return value
17347 ----------- | -------------
17348 null | `"null"`
17349 boolean | `"boolean"`
17350 string | `"string"`
17351 number | `"number"` (for all number types)
17352 object | `"object"`
17353 array | `"array"`
17354 discarded | `"discarded"`
17355
17356 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17357
17358 @complexity Constant.
17359
17360 @liveexample{The following code exemplifies `type_name()` for all JSON
17361 types.,type_name}
17362
17363 @sa @ref type() -- return the type of the JSON value
17364 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
17365
17366 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
17367 since 3.0.0
17368 */
type_name() const17369 const char* type_name() const noexcept
17370 {
17371 {
17372 switch (m_type)
17373 {
17374 case value_t::null:
17375 return "null";
17376 case value_t::object:
17377 return "object";
17378 case value_t::array:
17379 return "array";
17380 case value_t::string:
17381 return "string";
17382 case value_t::boolean:
17383 return "boolean";
17384 case value_t::discarded:
17385 return "discarded";
17386 default:
17387 return "number";
17388 }
17389 }
17390 }
17391
17392
17393 private:
17394 //////////////////////
17395 // member variables //
17396 //////////////////////
17397
17398 /// the type of the current element
17399 value_t m_type = value_t::null;
17400
17401 /// the value of the current element
17402 json_value m_value = {};
17403
17404 //////////////////////////////////////////
17405 // binary serialization/deserialization //
17406 //////////////////////////////////////////
17407
17408 /// @name binary serialization/deserialization support
17409 /// @{
17410
17411 public:
17412 /*!
17413 @brief create a CBOR serialization of a given JSON value
17414
17415 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
17416 Binary Object Representation) serialization format. CBOR is a binary
17417 serialization format which aims to be more compact than JSON itself, yet
17418 more efficient to parse.
17419
17420 The library uses the following mapping from JSON values types to
17421 CBOR types according to the CBOR specification (RFC 7049):
17422
17423 JSON value type | value/range | CBOR type | first byte
17424 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
17425 null | `null` | Null | 0xF6
17426 boolean | `true` | True | 0xF5
17427 boolean | `false` | False | 0xF4
17428 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
17429 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
17430 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
17431 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
17432 number_integer | -24..-1 | Negative integer | 0x20..0x37
17433 number_integer | 0..23 | Integer | 0x00..0x17
17434 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
17435 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17436 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17437 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17438 number_unsigned | 0..23 | Integer | 0x00..0x17
17439 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
17440 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17441 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17442 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17443 number_float | *any value* | Double-Precision Float | 0xFB
17444 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
17445 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
17446 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
17447 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
17448 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
17449 array | *size*: 0..23 | array | 0x80..0x97
17450 array | *size*: 23..255 | array (1 byte follow) | 0x98
17451 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
17452 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
17453 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
17454 object | *size*: 0..23 | map | 0xA0..0xB7
17455 object | *size*: 23..255 | map (1 byte follow) | 0xB8
17456 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
17457 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
17458 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
17459
17460 @note The mapping is **complete** in the sense that any JSON value type
17461 can be converted to a CBOR value.
17462
17463 @note If NaN or Infinity are stored inside a JSON number, they are
17464 serialized properly. This behavior differs from the @ref dump()
17465 function which serializes NaN or Infinity to `null`.
17466
17467 @note The following CBOR types are not used in the conversion:
17468 - byte strings (0x40..0x5F)
17469 - UTF-8 strings terminated by "break" (0x7F)
17470 - arrays terminated by "break" (0x9F)
17471 - maps terminated by "break" (0xBF)
17472 - date/time (0xC0..0xC1)
17473 - bignum (0xC2..0xC3)
17474 - decimal fraction (0xC4)
17475 - bigfloat (0xC5)
17476 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17477 - expected conversions (0xD5..0xD7)
17478 - simple values (0xE0..0xF3, 0xF8)
17479 - undefined (0xF7)
17480 - half and single-precision floats (0xF9-0xFA)
17481 - break (0xFF)
17482
17483 @param[in] j JSON value to serialize
17484 @return MessagePack serialization as byte vector
17485
17486 @complexity Linear in the size of the JSON value @a j.
17487
17488 @liveexample{The example shows the serialization of a JSON value to a byte
17489 vector in CBOR format.,to_cbor}
17490
17491 @sa http://cbor.io
17492 @sa @ref from_cbor(detail::input_adapter, const bool strict) for the
17493 analogous deserialization
17494 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17495 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17496 related UBJSON format
17497
17498 @since version 2.0.9
17499 */
to_cbor(const basic_json & j)17500 static std::vector<uint8_t> to_cbor(const basic_json& j)
17501 {
17502 std::vector<uint8_t> result;
17503 to_cbor(j, result);
17504 return result;
17505 }
17506
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)17507 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
17508 {
17509 binary_writer<uint8_t>(o).write_cbor(j);
17510 }
17511
to_cbor(const basic_json & j,detail::output_adapter<char> o)17512 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
17513 {
17514 binary_writer<char>(o).write_cbor(j);
17515 }
17516
17517 /*!
17518 @brief create a MessagePack serialization of a given JSON value
17519
17520 Serializes a given JSON value @a j to a byte vector using the MessagePack
17521 serialization format. MessagePack is a binary serialization format which
17522 aims to be more compact than JSON itself, yet more efficient to parse.
17523
17524 The library uses the following mapping from JSON values types to
17525 MessagePack types according to the MessagePack specification:
17526
17527 JSON value type | value/range | MessagePack type | first byte
17528 --------------- | --------------------------------- | ---------------- | ----------
17529 null | `null` | nil | 0xC0
17530 boolean | `true` | true | 0xC3
17531 boolean | `false` | false | 0xC2
17532 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
17533 number_integer | -2147483648..-32769 | int32 | 0xD2
17534 number_integer | -32768..-129 | int16 | 0xD1
17535 number_integer | -128..-33 | int8 | 0xD0
17536 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
17537 number_integer | 0..127 | positive fixint | 0x00..0x7F
17538 number_integer | 128..255 | uint 8 | 0xCC
17539 number_integer | 256..65535 | uint 16 | 0xCD
17540 number_integer | 65536..4294967295 | uint 32 | 0xCE
17541 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
17542 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
17543 number_unsigned | 128..255 | uint 8 | 0xCC
17544 number_unsigned | 256..65535 | uint 16 | 0xCD
17545 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
17546 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
17547 number_float | *any value* | float 64 | 0xCB
17548 string | *length*: 0..31 | fixstr | 0xA0..0xBF
17549 string | *length*: 32..255 | str 8 | 0xD9
17550 string | *length*: 256..65535 | str 16 | 0xDA
17551 string | *length*: 65536..4294967295 | str 32 | 0xDB
17552 array | *size*: 0..15 | fixarray | 0x90..0x9F
17553 array | *size*: 16..65535 | array 16 | 0xDC
17554 array | *size*: 65536..4294967295 | array 32 | 0xDD
17555 object | *size*: 0..15 | fix map | 0x80..0x8F
17556 object | *size*: 16..65535 | map 16 | 0xDE
17557 object | *size*: 65536..4294967295 | map 32 | 0xDF
17558
17559 @note The mapping is **complete** in the sense that any JSON value type
17560 can be converted to a MessagePack value.
17561
17562 @note The following values can **not** be converted to a MessagePack value:
17563 - strings with more than 4294967295 bytes
17564 - arrays with more than 4294967295 elements
17565 - objects with more than 4294967295 elements
17566
17567 @note The following MessagePack types are not used in the conversion:
17568 - bin 8 - bin 32 (0xC4..0xC6)
17569 - ext 8 - ext 32 (0xC7..0xC9)
17570 - float 32 (0xCA)
17571 - fixext 1 - fixext 16 (0xD4..0xD8)
17572
17573 @note Any MessagePack output created @ref to_msgpack can be successfully
17574 parsed by @ref from_msgpack.
17575
17576 @note If NaN or Infinity are stored inside a JSON number, they are
17577 serialized properly. This behavior differs from the @ref dump()
17578 function which serializes NaN or Infinity to `null`.
17579
17580 @param[in] j JSON value to serialize
17581 @return MessagePack serialization as byte vector
17582
17583 @complexity Linear in the size of the JSON value @a j.
17584
17585 @liveexample{The example shows the serialization of a JSON value to a byte
17586 vector in MessagePack format.,to_msgpack}
17587
17588 @sa http://msgpack.org
17589 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
17590 analogous deserialization
17591 @sa @ref to_cbor(const basic_json& for the related CBOR format
17592 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17593 related UBJSON format
17594
17595 @since version 2.0.9
17596 */
to_msgpack(const basic_json & j)17597 static std::vector<uint8_t> to_msgpack(const basic_json& j)
17598 {
17599 std::vector<uint8_t> result;
17600 to_msgpack(j, result);
17601 return result;
17602 }
17603
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)17604 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
17605 {
17606 binary_writer<uint8_t>(o).write_msgpack(j);
17607 }
17608
to_msgpack(const basic_json & j,detail::output_adapter<char> o)17609 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
17610 {
17611 binary_writer<char>(o).write_msgpack(j);
17612 }
17613
17614 /*!
17615 @brief create a UBJSON serialization of a given JSON value
17616
17617 Serializes a given JSON value @a j to a byte vector using the UBJSON
17618 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
17619 than JSON itself, yet more efficient to parse.
17620
17621 The library uses the following mapping from JSON values types to
17622 UBJSON types according to the UBJSON specification:
17623
17624 JSON value type | value/range | UBJSON type | marker
17625 --------------- | --------------------------------- | ----------- | ------
17626 null | `null` | null | `Z`
17627 boolean | `true` | true | `T`
17628 boolean | `false` | false | `F`
17629 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
17630 number_integer | -2147483648..-32769 | int32 | `l`
17631 number_integer | -32768..-129 | int16 | `I`
17632 number_integer | -128..127 | int8 | `i`
17633 number_integer | 128..255 | uint8 | `U`
17634 number_integer | 256..32767 | int16 | `I`
17635 number_integer | 32768..2147483647 | int32 | `l`
17636 number_integer | 2147483648..9223372036854775807 | int64 | `L`
17637 number_unsigned | 0..127 | int8 | `i`
17638 number_unsigned | 128..255 | uint8 | `U`
17639 number_unsigned | 256..32767 | int16 | `I`
17640 number_unsigned | 32768..2147483647 | int32 | `l`
17641 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
17642 number_float | *any value* | float64 | `D`
17643 string | *with shortest length indicator* | string | `S`
17644 array | *see notes on optimized format* | array | `[`
17645 object | *see notes on optimized format* | map | `{`
17646
17647 @note The mapping is **complete** in the sense that any JSON value type
17648 can be converted to a UBJSON value.
17649
17650 @note The following values can **not** be converted to a UBJSON value:
17651 - strings with more than 9223372036854775807 bytes (theoretical)
17652 - unsigned integer numbers above 9223372036854775807
17653
17654 @note The following markers are not used in the conversion:
17655 - `Z`: no-op values are not created.
17656 - `C`: single-byte strings are serialized with `S` markers.
17657
17658 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
17659 by @ref from_ubjson.
17660
17661 @note If NaN or Infinity are stored inside a JSON number, they are
17662 serialized properly. This behavior differs from the @ref dump()
17663 function which serializes NaN or Infinity to `null`.
17664
17665 @note The optimized formats for containers are supported: Parameter
17666 @a use_size adds size information to the beginning of a container and
17667 removes the closing marker. Parameter @a use_type further checks
17668 whether all elements of a container have the same type and adds the
17669 type marker to the beginning of the container. The @a use_type
17670 parameter must only be used together with @a use_size = true. Note
17671 that @a use_size = true alone may result in larger representations -
17672 the benefit of this parameter is that the receiving side is
17673 immediately informed on the number of elements of the container.
17674
17675 @param[in] j JSON value to serialize
17676 @param[in] use_size whether to add size annotations to container types
17677 @param[in] use_type whether to add type annotations to container types
17678 (must be combined with @a use_size = true)
17679 @return UBJSON serialization as byte vector
17680
17681 @complexity Linear in the size of the JSON value @a j.
17682
17683 @liveexample{The example shows the serialization of a JSON value to a byte
17684 vector in UBJSON format.,to_ubjson}
17685
17686 @sa http://ubjson.org
17687 @sa @ref from_ubjson(detail::input_adapter, const bool strict) for the
17688 analogous deserialization
17689 @sa @ref to_cbor(const basic_json& for the related CBOR format
17690 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17691
17692 @since version 3.1.0
17693 */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)17694 static std::vector<uint8_t> to_ubjson(const basic_json& j,
17695 const bool use_size = false,
17696 const bool use_type = false)
17697 {
17698 std::vector<uint8_t> result;
17699 to_ubjson(j, result, use_size, use_type);
17700 return result;
17701 }
17702
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)17703 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
17704 const bool use_size = false, const bool use_type = false)
17705 {
17706 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
17707 }
17708
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)17709 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
17710 const bool use_size = false, const bool use_type = false)
17711 {
17712 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
17713 }
17714
17715 /*!
17716 @brief create a JSON value from an input in CBOR format
17717
17718 Deserializes a given input @a i to a JSON value using the CBOR (Concise
17719 Binary Object Representation) serialization format.
17720
17721 The library maps CBOR types to JSON value types as follows:
17722
17723 CBOR type | JSON value type | first byte
17724 ---------------------- | --------------- | ----------
17725 Integer | number_unsigned | 0x00..0x17
17726 Unsigned integer | number_unsigned | 0x18
17727 Unsigned integer | number_unsigned | 0x19
17728 Unsigned integer | number_unsigned | 0x1A
17729 Unsigned integer | number_unsigned | 0x1B
17730 Negative integer | number_integer | 0x20..0x37
17731 Negative integer | number_integer | 0x38
17732 Negative integer | number_integer | 0x39
17733 Negative integer | number_integer | 0x3A
17734 Negative integer | number_integer | 0x3B
17735 Negative integer | number_integer | 0x40..0x57
17736 UTF-8 string | string | 0x60..0x77
17737 UTF-8 string | string | 0x78
17738 UTF-8 string | string | 0x79
17739 UTF-8 string | string | 0x7A
17740 UTF-8 string | string | 0x7B
17741 UTF-8 string | string | 0x7F
17742 array | array | 0x80..0x97
17743 array | array | 0x98
17744 array | array | 0x99
17745 array | array | 0x9A
17746 array | array | 0x9B
17747 array | array | 0x9F
17748 map | object | 0xA0..0xB7
17749 map | object | 0xB8
17750 map | object | 0xB9
17751 map | object | 0xBA
17752 map | object | 0xBB
17753 map | object | 0xBF
17754 False | `false` | 0xF4
17755 True | `true` | 0xF5
17756 Nill | `null` | 0xF6
17757 Half-Precision Float | number_float | 0xF9
17758 Single-Precision Float | number_float | 0xFA
17759 Double-Precision Float | number_float | 0xFB
17760
17761 @warning The mapping is **incomplete** in the sense that not all CBOR
17762 types can be converted to a JSON value. The following CBOR types
17763 are not supported and will yield parse errors (parse_error.112):
17764 - byte strings (0x40..0x5F)
17765 - date/time (0xC0..0xC1)
17766 - bignum (0xC2..0xC3)
17767 - decimal fraction (0xC4)
17768 - bigfloat (0xC5)
17769 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17770 - expected conversions (0xD5..0xD7)
17771 - simple values (0xE0..0xF3, 0xF8)
17772 - undefined (0xF7)
17773
17774 @warning CBOR allows map keys of any type, whereas JSON only allows
17775 strings as keys in object values. Therefore, CBOR maps with keys
17776 other than UTF-8 strings are rejected (parse_error.113).
17777
17778 @note Any CBOR output created @ref to_cbor can be successfully parsed by
17779 @ref from_cbor.
17780
17781 @param[in] i an input in CBOR format convertible to an input adapter
17782 @param[in] strict whether to expect the input to be consumed until EOF
17783 (true by default)
17784 @param[in] allow_exceptions whether to throw exceptions in case of a
17785 parse error (optional, true by default)
17786
17787 @return deserialized JSON value
17788
17789 @throw parse_error.110 if the given input ends prematurely or the end of
17790 file was not reached when @a strict was set to true
17791 @throw parse_error.112 if unsupported features from CBOR were
17792 used in the given input @a v or if the input is not valid CBOR
17793 @throw parse_error.113 if a string was expected as map key, but not found
17794
17795 @complexity Linear in the size of the input @a i.
17796
17797 @liveexample{The example shows the deserialization of a byte vector in CBOR
17798 format to a JSON value.,from_cbor}
17799
17800 @sa http://cbor.io
17801 @sa @ref to_cbor(const basic_json&) for the analogous serialization
17802 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for the
17803 related MessagePack format
17804 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for the
17805 related UBJSON format
17806
17807 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17808 consume input adapters, removed start_index parameter, and added
17809 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17810 since 3.2.0
17811 */
from_cbor(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17812 static basic_json from_cbor(detail::input_adapter&& i,
17813 const bool strict = true,
17814 const bool allow_exceptions = true)
17815 {
17816 basic_json result;
17817 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17818 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
17819 return res ? result : basic_json(value_t::discarded);
17820 }
17821
17822 /*!
17823 @copydoc from_cbor(detail::input_adapter, const bool, const bool)
17824 */
17825 template<typename A1, typename A2,
17826 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)17827 static basic_json from_cbor(A1 && a1, A2 && a2,
17828 const bool strict = true,
17829 const bool allow_exceptions = true)
17830 {
17831 basic_json result;
17832 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17833 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
17834 return res ? result : basic_json(value_t::discarded);
17835 }
17836
17837 /*!
17838 @brief create a JSON value from an input in MessagePack format
17839
17840 Deserializes a given input @a i to a JSON value using the MessagePack
17841 serialization format.
17842
17843 The library maps MessagePack types to JSON value types as follows:
17844
17845 MessagePack type | JSON value type | first byte
17846 ---------------- | --------------- | ----------
17847 positive fixint | number_unsigned | 0x00..0x7F
17848 fixmap | object | 0x80..0x8F
17849 fixarray | array | 0x90..0x9F
17850 fixstr | string | 0xA0..0xBF
17851 nil | `null` | 0xC0
17852 false | `false` | 0xC2
17853 true | `true` | 0xC3
17854 float 32 | number_float | 0xCA
17855 float 64 | number_float | 0xCB
17856 uint 8 | number_unsigned | 0xCC
17857 uint 16 | number_unsigned | 0xCD
17858 uint 32 | number_unsigned | 0xCE
17859 uint 64 | number_unsigned | 0xCF
17860 int 8 | number_integer | 0xD0
17861 int 16 | number_integer | 0xD1
17862 int 32 | number_integer | 0xD2
17863 int 64 | number_integer | 0xD3
17864 str 8 | string | 0xD9
17865 str 16 | string | 0xDA
17866 str 32 | string | 0xDB
17867 array 16 | array | 0xDC
17868 array 32 | array | 0xDD
17869 map 16 | object | 0xDE
17870 map 32 | object | 0xDF
17871 negative fixint | number_integer | 0xE0-0xFF
17872
17873 @warning The mapping is **incomplete** in the sense that not all
17874 MessagePack types can be converted to a JSON value. The following
17875 MessagePack types are not supported and will yield parse errors:
17876 - bin 8 - bin 32 (0xC4..0xC6)
17877 - ext 8 - ext 32 (0xC7..0xC9)
17878 - fixext 1 - fixext 16 (0xD4..0xD8)
17879
17880 @note Any MessagePack output created @ref to_msgpack can be successfully
17881 parsed by @ref from_msgpack.
17882
17883 @param[in] i an input in MessagePack format convertible to an input
17884 adapter
17885 @param[in] strict whether to expect the input to be consumed until EOF
17886 (true by default)
17887 @param[in] allow_exceptions whether to throw exceptions in case of a
17888 parse error (optional, true by default)
17889
17890 @return deserialized JSON value
17891
17892 @throw parse_error.110 if the given input ends prematurely or the end of
17893 file was not reached when @a strict was set to true
17894 @throw parse_error.112 if unsupported features from MessagePack were
17895 used in the given input @a i or if the input is not valid MessagePack
17896 @throw parse_error.113 if a string was expected as map key, but not found
17897
17898 @complexity Linear in the size of the input @a i.
17899
17900 @liveexample{The example shows the deserialization of a byte vector in
17901 MessagePack format to a JSON value.,from_msgpack}
17902
17903 @sa http://msgpack.org
17904 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
17905 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17906 related CBOR format
17907 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for
17908 the related UBJSON format
17909
17910 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17911 consume input adapters, removed start_index parameter, and added
17912 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17913 since 3.2.0
17914 */
from_msgpack(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17915 static basic_json from_msgpack(detail::input_adapter&& i,
17916 const bool strict = true,
17917 const bool allow_exceptions = true)
17918 {
17919 basic_json result;
17920 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17921 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
17922 return res ? result : basic_json(value_t::discarded);
17923 }
17924
17925 /*!
17926 @copydoc from_msgpack(detail::input_adapter, const bool, const bool)
17927 */
17928 template<typename A1, typename A2,
17929 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)17930 static basic_json from_msgpack(A1 && a1, A2 && a2,
17931 const bool strict = true,
17932 const bool allow_exceptions = true)
17933 {
17934 basic_json result;
17935 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17936 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
17937 return res ? result : basic_json(value_t::discarded);
17938 }
17939
17940 /*!
17941 @brief create a JSON value from an input in UBJSON format
17942
17943 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
17944 Binary JSON) serialization format.
17945
17946 The library maps UBJSON types to JSON value types as follows:
17947
17948 UBJSON type | JSON value type | marker
17949 ----------- | --------------------------------------- | ------
17950 no-op | *no value, next value is read* | `N`
17951 null | `null` | `Z`
17952 false | `false` | `F`
17953 true | `true` | `T`
17954 float32 | number_float | `d`
17955 float64 | number_float | `D`
17956 uint8 | number_unsigned | `U`
17957 int8 | number_integer | `i`
17958 int16 | number_integer | `I`
17959 int32 | number_integer | `l`
17960 int64 | number_integer | `L`
17961 string | string | `S`
17962 char | string | `C`
17963 array | array (optimized values are supported) | `[`
17964 object | object (optimized values are supported) | `{`
17965
17966 @note The mapping is **complete** in the sense that any UBJSON value can
17967 be converted to a JSON value.
17968
17969 @param[in] i an input in UBJSON format convertible to an input adapter
17970 @param[in] strict whether to expect the input to be consumed until EOF
17971 (true by default)
17972 @param[in] allow_exceptions whether to throw exceptions in case of a
17973 parse error (optional, true by default)
17974
17975 @return deserialized JSON value
17976
17977 @throw parse_error.110 if the given input ends prematurely or the end of
17978 file was not reached when @a strict was set to true
17979 @throw parse_error.112 if a parse error occurs
17980 @throw parse_error.113 if a string could not be parsed successfully
17981
17982 @complexity Linear in the size of the input @a i.
17983
17984 @liveexample{The example shows the deserialization of a byte vector in
17985 UBJSON format to a JSON value.,from_ubjson}
17986
17987 @sa http://ubjson.org
17988 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17989 analogous serialization
17990 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17991 related CBOR format
17992 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for
17993 the related MessagePack format
17994
17995 @since version 3.1.0; added @allow_exceptions parameter since 3.2.0
17996 */
from_ubjson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)17997 static basic_json from_ubjson(detail::input_adapter&& i,
17998 const bool strict = true,
17999 const bool allow_exceptions = true)
18000 {
18001 basic_json result;
18002 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
18003 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
18004 return res ? result : basic_json(value_t::discarded);
18005 }
18006
18007 /*!
18008 @copydoc from_ubjson(detail::input_adapter, const bool, const bool)
18009 */
18010 template<typename A1, typename A2,
18011 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)18012 static basic_json from_ubjson(A1 && a1, A2 && a2,
18013 const bool strict = true,
18014 const bool allow_exceptions = true)
18015 {
18016 basic_json result;
18017 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
18018 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
18019 return res ? result : basic_json(value_t::discarded);
18020 }
18021
18022 /// @}
18023
18024 //////////////////////////
18025 // JSON Pointer support //
18026 //////////////////////////
18027
18028 /// @name JSON Pointer functions
18029 /// @{
18030
18031 /*!
18032 @brief access specified element via JSON Pointer
18033
18034 Uses a JSON pointer to retrieve a reference to the respective JSON value.
18035 No bound checking is performed. Similar to @ref operator[](const typename
18036 object_t::key_type&), `null` values are created in arrays and objects if
18037 necessary.
18038
18039 In particular:
18040 - If the JSON pointer points to an object key that does not exist, it
18041 is created an filled with a `null` value before a reference to it
18042 is returned.
18043 - If the JSON pointer points to an array index that does not exist, it
18044 is created an filled with a `null` value before a reference to it
18045 is returned. All indices between the current maximum and the given
18046 index are also filled with `null`.
18047 - The special value `-` is treated as a synonym for the index past the
18048 end.
18049
18050 @param[in] ptr a JSON pointer
18051
18052 @return reference to the element pointed to by @a ptr
18053
18054 @complexity Constant.
18055
18056 @throw parse_error.106 if an array index begins with '0'
18057 @throw parse_error.109 if an array index was not a number
18058 @throw out_of_range.404 if the JSON pointer can not be resolved
18059
18060 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
18061
18062 @since version 2.0.0
18063 */
operator [](const json_pointer & ptr)18064 reference operator[](const json_pointer& ptr)
18065 {
18066 return ptr.get_unchecked(this);
18067 }
18068
18069 /*!
18070 @brief access specified element via JSON Pointer
18071
18072 Uses a JSON pointer to retrieve a reference to the respective JSON value.
18073 No bound checking is performed. The function does not change the JSON
18074 value; no `null` values are created. In particular, the the special value
18075 `-` yields an exception.
18076
18077 @param[in] ptr JSON pointer to the desired element
18078
18079 @return const reference to the element pointed to by @a ptr
18080
18081 @complexity Constant.
18082
18083 @throw parse_error.106 if an array index begins with '0'
18084 @throw parse_error.109 if an array index was not a number
18085 @throw out_of_range.402 if the array index '-' is used
18086 @throw out_of_range.404 if the JSON pointer can not be resolved
18087
18088 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
18089
18090 @since version 2.0.0
18091 */
operator [](const json_pointer & ptr) const18092 const_reference operator[](const json_pointer& ptr) const
18093 {
18094 return ptr.get_unchecked(this);
18095 }
18096
18097 /*!
18098 @brief access specified element via JSON Pointer
18099
18100 Returns a reference to the element at with specified JSON pointer @a ptr,
18101 with bounds checking.
18102
18103 @param[in] ptr JSON pointer to the desired element
18104
18105 @return reference to the element pointed to by @a ptr
18106
18107 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18108 begins with '0'. See example below.
18109
18110 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18111 is not a number. See example below.
18112
18113 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18114 is out of range. See example below.
18115
18116 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18117 pointer @a ptr. As `at` provides checked access (and no elements are
18118 implicitly inserted), the index '-' is always invalid. See example below.
18119
18120 @throw out_of_range.403 if the JSON pointer describes a key of an object
18121 which cannot be found. See example below.
18122
18123 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18124 See example below.
18125
18126 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18127 changes in the JSON value.
18128
18129 @complexity Constant.
18130
18131 @since version 2.0.0
18132
18133 @liveexample{The behavior is shown in the example.,at_json_pointer}
18134 */
at(const json_pointer & ptr)18135 reference at(const json_pointer& ptr)
18136 {
18137 return ptr.get_checked(this);
18138 }
18139
18140 /*!
18141 @brief access specified element via JSON Pointer
18142
18143 Returns a const reference to the element at with specified JSON pointer @a
18144 ptr, with bounds checking.
18145
18146 @param[in] ptr JSON pointer to the desired element
18147
18148 @return reference to the element pointed to by @a ptr
18149
18150 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18151 begins with '0'. See example below.
18152
18153 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18154 is not a number. See example below.
18155
18156 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18157 is out of range. See example below.
18158
18159 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18160 pointer @a ptr. As `at` provides checked access (and no elements are
18161 implicitly inserted), the index '-' is always invalid. See example below.
18162
18163 @throw out_of_range.403 if the JSON pointer describes a key of an object
18164 which cannot be found. See example below.
18165
18166 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18167 See example below.
18168
18169 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18170 changes in the JSON value.
18171
18172 @complexity Constant.
18173
18174 @since version 2.0.0
18175
18176 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
18177 */
at(const json_pointer & ptr) const18178 const_reference at(const json_pointer& ptr) const
18179 {
18180 return ptr.get_checked(this);
18181 }
18182
18183 /*!
18184 @brief return flattened JSON value
18185
18186 The function creates a JSON object whose keys are JSON pointers (see [RFC
18187 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
18188 primitive. The original JSON value can be restored using the @ref
18189 unflatten() function.
18190
18191 @return an object that maps JSON pointers to primitive values
18192
18193 @note Empty objects and arrays are flattened to `null` and will not be
18194 reconstructed correctly by the @ref unflatten() function.
18195
18196 @complexity Linear in the size the JSON value.
18197
18198 @liveexample{The following code shows how a JSON object is flattened to an
18199 object whose keys consist of JSON pointers.,flatten}
18200
18201 @sa @ref unflatten() for the reverse function
18202
18203 @since version 2.0.0
18204 */
flatten() const18205 basic_json flatten() const
18206 {
18207 basic_json result(value_t::object);
18208 json_pointer::flatten("", *this, result);
18209 return result;
18210 }
18211
18212 /*!
18213 @brief unflatten a previously flattened JSON value
18214
18215 The function restores the arbitrary nesting of a JSON value that has been
18216 flattened before using the @ref flatten() function. The JSON value must
18217 meet certain constraints:
18218 1. The value must be an object.
18219 2. The keys must be JSON pointers (see
18220 [RFC 6901](https://tools.ietf.org/html/rfc6901))
18221 3. The mapped values must be primitive JSON types.
18222
18223 @return the original JSON from a flattened version
18224
18225 @note Empty objects and arrays are flattened by @ref flatten() to `null`
18226 values and can not unflattened to their original type. Apart from
18227 this example, for a JSON value `j`, the following is always true:
18228 `j == j.flatten().unflatten()`.
18229
18230 @complexity Linear in the size the JSON value.
18231
18232 @throw type_error.314 if value is not an object
18233 @throw type_error.315 if object values are not primitive
18234
18235 @liveexample{The following code shows how a flattened JSON object is
18236 unflattened into the original nested JSON object.,unflatten}
18237
18238 @sa @ref flatten() for the reverse function
18239
18240 @since version 2.0.0
18241 */
unflatten() const18242 basic_json unflatten() const
18243 {
18244 return json_pointer::unflatten(*this);
18245 }
18246
18247 /// @}
18248
18249 //////////////////////////
18250 // JSON Patch functions //
18251 //////////////////////////
18252
18253 /// @name JSON Patch functions
18254 /// @{
18255
18256 /*!
18257 @brief applies a JSON patch
18258
18259 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
18260 expressing a sequence of operations to apply to a JSON) document. With
18261 this function, a JSON Patch is applied to the current JSON value by
18262 executing all operations from the patch.
18263
18264 @param[in] json_patch JSON patch document
18265 @return patched document
18266
18267 @note The application of a patch is atomic: Either all operations succeed
18268 and the patched document is returned or an exception is thrown. In
18269 any case, the original value is not changed: the patch is applied
18270 to a copy of the value.
18271
18272 @throw parse_error.104 if the JSON patch does not consist of an array of
18273 objects
18274
18275 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
18276 attributes are missing); example: `"operation add must have member path"`
18277
18278 @throw out_of_range.401 if an array index is out of range.
18279
18280 @throw out_of_range.403 if a JSON pointer inside the patch could not be
18281 resolved successfully in the current JSON value; example: `"key baz not
18282 found"`
18283
18284 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
18285 "move")
18286
18287 @throw other_error.501 if "test" operation was unsuccessful
18288
18289 @complexity Linear in the size of the JSON value and the length of the
18290 JSON patch. As usually only a fraction of the JSON value is affected by
18291 the patch, the complexity can usually be neglected.
18292
18293 @liveexample{The following code shows how a JSON patch is applied to a
18294 value.,patch}
18295
18296 @sa @ref diff -- create a JSON patch by comparing two JSON values
18297
18298 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18299 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
18300
18301 @since version 2.0.0
18302 */
patch(const basic_json & json_patch) const18303 basic_json patch(const basic_json& json_patch) const
18304 {
18305 // make a working copy to apply the patch to
18306 basic_json result = *this;
18307
18308 // the valid JSON Patch operations
18309 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
18310
18311 const auto get_op = [](const std::string & op)
18312 {
18313 if (op == "add")
18314 {
18315 return patch_operations::add;
18316 }
18317 if (op == "remove")
18318 {
18319 return patch_operations::remove;
18320 }
18321 if (op == "replace")
18322 {
18323 return patch_operations::replace;
18324 }
18325 if (op == "move")
18326 {
18327 return patch_operations::move;
18328 }
18329 if (op == "copy")
18330 {
18331 return patch_operations::copy;
18332 }
18333 if (op == "test")
18334 {
18335 return patch_operations::test;
18336 }
18337
18338 return patch_operations::invalid;
18339 };
18340
18341 // wrapper for "add" operation; add value at ptr
18342 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
18343 {
18344 // adding to the root of the target document means replacing it
18345 if (ptr.is_root())
18346 {
18347 result = val;
18348 }
18349 else
18350 {
18351 // make sure the top element of the pointer exists
18352 json_pointer top_pointer = ptr.top();
18353 if (top_pointer != ptr)
18354 {
18355 result.at(top_pointer);
18356 }
18357
18358 // get reference to parent of JSON pointer ptr
18359 const auto last_path = ptr.pop_back();
18360 basic_json& parent = result[ptr];
18361
18362 switch (parent.m_type)
18363 {
18364 case value_t::null:
18365 case value_t::object:
18366 {
18367 // use operator[] to add value
18368 parent[last_path] = val;
18369 break;
18370 }
18371
18372 case value_t::array:
18373 {
18374 if (last_path == "-")
18375 {
18376 // special case: append to back
18377 parent.push_back(val);
18378 }
18379 else
18380 {
18381 const auto idx = json_pointer::array_index(last_path);
18382 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
18383 {
18384 // avoid undefined behavior
18385 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
18386 }
18387 else
18388 {
18389 // default case: insert add offset
18390 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
18391 }
18392 }
18393 break;
18394 }
18395
18396 // LCOV_EXCL_START
18397 default:
18398 {
18399 // if there exists a parent it cannot be primitive
18400 assert(false);
18401 }
18402 // LCOV_EXCL_STOP
18403 }
18404 }
18405 };
18406
18407 // wrapper for "remove" operation; remove value at ptr
18408 const auto operation_remove = [&result](json_pointer & ptr)
18409 {
18410 // get reference to parent of JSON pointer ptr
18411 const auto last_path = ptr.pop_back();
18412 basic_json& parent = result.at(ptr);
18413
18414 // remove child
18415 if (parent.is_object())
18416 {
18417 // perform range check
18418 auto it = parent.find(last_path);
18419 if (JSON_LIKELY(it != parent.end()))
18420 {
18421 parent.erase(it);
18422 }
18423 else
18424 {
18425 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
18426 }
18427 }
18428 else if (parent.is_array())
18429 {
18430 // note erase performs range check
18431 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
18432 }
18433 };
18434
18435 // type check: top level value must be an array
18436 if (JSON_UNLIKELY(not json_patch.is_array()))
18437 {
18438 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18439 }
18440
18441 // iterate and apply the operations
18442 for (const auto& val : json_patch)
18443 {
18444 // wrapper to get a value for an operation
18445 const auto get_value = [&val](const std::string & op,
18446 const std::string & member,
18447 bool string_type) -> basic_json &
18448 {
18449 // find value
18450 auto it = val.m_value.object->find(member);
18451
18452 // context-sensitive error message
18453 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
18454
18455 // check if desired value is present
18456 if (JSON_UNLIKELY(it == val.m_value.object->end()))
18457 {
18458 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
18459 }
18460
18461 // check if result is of type string
18462 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
18463 {
18464 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
18465 }
18466
18467 // no error: return value
18468 return it->second;
18469 };
18470
18471 // type check: every element of the array must be an object
18472 if (JSON_UNLIKELY(not val.is_object()))
18473 {
18474 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18475 }
18476
18477 // collect mandatory members
18478 const std::string op = get_value("op", "op", true);
18479 const std::string path = get_value(op, "path", true);
18480 json_pointer ptr(path);
18481
18482 switch (get_op(op))
18483 {
18484 case patch_operations::add:
18485 {
18486 operation_add(ptr, get_value("add", "value", false));
18487 break;
18488 }
18489
18490 case patch_operations::remove:
18491 {
18492 operation_remove(ptr);
18493 break;
18494 }
18495
18496 case patch_operations::replace:
18497 {
18498 // the "path" location must exist - use at()
18499 result.at(ptr) = get_value("replace", "value", false);
18500 break;
18501 }
18502
18503 case patch_operations::move:
18504 {
18505 const std::string from_path = get_value("move", "from", true);
18506 json_pointer from_ptr(from_path);
18507
18508 // the "from" location must exist - use at()
18509 basic_json v = result.at(from_ptr);
18510
18511 // The move operation is functionally identical to a
18512 // "remove" operation on the "from" location, followed
18513 // immediately by an "add" operation at the target
18514 // location with the value that was just removed.
18515 operation_remove(from_ptr);
18516 operation_add(ptr, v);
18517 break;
18518 }
18519
18520 case patch_operations::copy:
18521 {
18522 const std::string from_path = get_value("copy", "from", true);
18523 const json_pointer from_ptr(from_path);
18524
18525 // the "from" location must exist - use at()
18526 basic_json v = result.at(from_ptr);
18527
18528 // The copy is functionally identical to an "add"
18529 // operation at the target location using the value
18530 // specified in the "from" member.
18531 operation_add(ptr, v);
18532 break;
18533 }
18534
18535 case patch_operations::test:
18536 {
18537 bool success = false;
18538 JSON_TRY
18539 {
18540 // check if "value" matches the one at "path"
18541 // the "path" location must exist - use at()
18542 success = (result.at(ptr) == get_value("test", "value", false));
18543 }
18544 JSON_INTERNAL_CATCH (out_of_range&)
18545 {
18546 // ignore out of range errors: success remains false
18547 }
18548
18549 // throw an exception if test fails
18550 if (JSON_UNLIKELY(not success))
18551 {
18552 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
18553 }
18554
18555 break;
18556 }
18557
18558 case patch_operations::invalid:
18559 {
18560 // op must be "add", "remove", "replace", "move", "copy", or
18561 // "test"
18562 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
18563 }
18564 }
18565 }
18566
18567 return result;
18568 }
18569
18570 /*!
18571 @brief creates a diff as a JSON patch
18572
18573 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
18574 be changed into the value @a target by calling @ref patch function.
18575
18576 @invariant For two JSON values @a source and @a target, the following code
18577 yields always `true`:
18578 @code {.cpp}
18579 source.patch(diff(source, target)) == target;
18580 @endcode
18581
18582 @note Currently, only `remove`, `add`, and `replace` operations are
18583 generated.
18584
18585 @param[in] source JSON value to compare from
18586 @param[in] target JSON value to compare against
18587 @param[in] path helper value to create JSON pointers
18588
18589 @return a JSON patch to convert the @a source to @a target
18590
18591 @complexity Linear in the lengths of @a source and @a target.
18592
18593 @liveexample{The following code shows how a JSON patch is created as a
18594 diff for two JSON values.,diff}
18595
18596 @sa @ref patch -- apply a JSON patch
18597 @sa @ref merge_patch -- apply a JSON Merge Patch
18598
18599 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18600
18601 @since version 2.0.0
18602 */
diff(const basic_json & source,const basic_json & target,const std::string & path="")18603 static basic_json diff(const basic_json& source, const basic_json& target,
18604 const std::string& path = "")
18605 {
18606 // the patch
18607 basic_json result(value_t::array);
18608
18609 // if the values are the same, return empty patch
18610 if (source == target)
18611 {
18612 return result;
18613 }
18614
18615 if (source.type() != target.type())
18616 {
18617 // different types: replace value
18618 result.push_back(
18619 {
18620 {"op", "replace"}, {"path", path}, {"value", target}
18621 });
18622 }
18623 else
18624 {
18625 switch (source.type())
18626 {
18627 case value_t::array:
18628 {
18629 // first pass: traverse common elements
18630 std::size_t i = 0;
18631 while (i < source.size() and i < target.size())
18632 {
18633 // recursive call to compare array values at index i
18634 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
18635 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18636 ++i;
18637 }
18638
18639 // i now reached the end of at least one array
18640 // in a second pass, traverse the remaining elements
18641
18642 // remove my remaining elements
18643 const auto end_index = static_cast<difference_type>(result.size());
18644 while (i < source.size())
18645 {
18646 // add operations in reverse order to avoid invalid
18647 // indices
18648 result.insert(result.begin() + end_index, object(
18649 {
18650 {"op", "remove"},
18651 {"path", path + "/" + std::to_string(i)}
18652 }));
18653 ++i;
18654 }
18655
18656 // add other remaining elements
18657 while (i < target.size())
18658 {
18659 result.push_back(
18660 {
18661 {"op", "add"},
18662 {"path", path + "/" + std::to_string(i)},
18663 {"value", target[i]}
18664 });
18665 ++i;
18666 }
18667
18668 break;
18669 }
18670
18671 case value_t::object:
18672 {
18673 // first pass: traverse this object's elements
18674 for (auto it = source.cbegin(); it != source.cend(); ++it)
18675 {
18676 // escape the key name to be used in a JSON patch
18677 const auto key = json_pointer::escape(it.key());
18678
18679 if (target.find(it.key()) != target.end())
18680 {
18681 // recursive call to compare object values at key it
18682 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
18683 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18684 }
18685 else
18686 {
18687 // found a key that is not in o -> remove it
18688 result.push_back(object(
18689 {
18690 {"op", "remove"}, {"path", path + "/" + key}
18691 }));
18692 }
18693 }
18694
18695 // second pass: traverse other object's elements
18696 for (auto it = target.cbegin(); it != target.cend(); ++it)
18697 {
18698 if (source.find(it.key()) == source.end())
18699 {
18700 // found a key that is not in this -> add it
18701 const auto key = json_pointer::escape(it.key());
18702 result.push_back(
18703 {
18704 {"op", "add"}, {"path", path + "/" + key},
18705 {"value", it.value()}
18706 });
18707 }
18708 }
18709
18710 break;
18711 }
18712
18713 default:
18714 {
18715 // both primitive type: replace value
18716 result.push_back(
18717 {
18718 {"op", "replace"}, {"path", path}, {"value", target}
18719 });
18720 break;
18721 }
18722 }
18723 }
18724
18725 return result;
18726 }
18727
18728 /// @}
18729
18730 ////////////////////////////////
18731 // JSON Merge Patch functions //
18732 ////////////////////////////////
18733
18734 /// @name JSON Merge Patch functions
18735 /// @{
18736
18737 /*!
18738 @brief applies a JSON Merge Patch
18739
18740 The merge patch format is primarily intended for use with the HTTP PATCH
18741 method as a means of describing a set of modifications to a target
18742 resource's content. This function applies a merge patch to the current
18743 JSON value.
18744
18745 The function implements the following algorithm from Section 2 of
18746 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
18747
18748 ```
18749 define MergePatch(Target, Patch):
18750 if Patch is an Object:
18751 if Target is not an Object:
18752 Target = {} // Ignore the contents and set it to an empty Object
18753 for each Name/Value pair in Patch:
18754 if Value is null:
18755 if Name exists in Target:
18756 remove the Name/Value pair from Target
18757 else:
18758 Target[Name] = MergePatch(Target[Name], Value)
18759 return Target
18760 else:
18761 return Patch
18762 ```
18763
18764 Thereby, `Target` is the current object; that is, the patch is applied to
18765 the current value.
18766
18767 @param[in] patch the patch to apply
18768
18769 @complexity Linear in the lengths of @a patch.
18770
18771 @liveexample{The following code shows how a JSON Merge Patch is applied to
18772 a JSON document.,merge_patch}
18773
18774 @sa @ref patch -- apply a JSON patch
18775 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
18776
18777 @since version 3.0.0
18778 */
merge_patch(const basic_json & patch)18779 void merge_patch(const basic_json& patch)
18780 {
18781 if (patch.is_object())
18782 {
18783 if (not is_object())
18784 {
18785 *this = object();
18786 }
18787 for (auto it = patch.begin(); it != patch.end(); ++it)
18788 {
18789 if (it.value().is_null())
18790 {
18791 erase(it.key());
18792 }
18793 else
18794 {
18795 operator[](it.key()).merge_patch(it.value());
18796 }
18797 }
18798 }
18799 else
18800 {
18801 *this = patch;
18802 }
18803 }
18804
18805 /// @}
18806 };
18807 } // namespace nlohmann
18808
18809 ///////////////////////
18810 // nonmember support //
18811 ///////////////////////
18812
18813 // specialization of std::swap, and std::hash
18814 namespace std
18815 {
18816
18817 /// hash value for JSON objects
18818 template<>
18819 struct hash<nlohmann::json>
18820 {
18821 /*!
18822 @brief return a hash value for a JSON object
18823
18824 @since version 1.0.0
18825 */
operator ()std::hash18826 std::size_t operator()(const nlohmann::json& j) const
18827 {
18828 // a naive hashing via the string representation
18829 const auto& h = hash<nlohmann::json::string_t>();
18830 return h(j.dump());
18831 }
18832 };
18833
18834 /// specialization for std::less<value_t>
18835 /// @note: do not remove the space after '<',
18836 /// see https://github.com/nlohmann/json/pull/679
18837 template<>
18838 struct less< ::nlohmann::detail::value_t>
18839 {
18840 /*!
18841 @brief compare two value_t enum values
18842 @since version 3.0.0
18843 */
operator ()std::less18844 bool operator()(nlohmann::detail::value_t lhs,
18845 nlohmann::detail::value_t rhs) const noexcept
18846 {
18847 return nlohmann::detail::operator<(lhs, rhs);
18848 }
18849 };
18850
18851 /*!
18852 @brief exchanges the values of two JSON objects
18853
18854 @since version 1.0.0
18855 */
18856 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)18857 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
18858 is_nothrow_move_constructible<nlohmann::json>::value and
18859 is_nothrow_move_assignable<nlohmann::json>::value
18860 )
18861 {
18862 j1.swap(j2);
18863 }
18864
18865 } // namespace std
18866
18867 /*!
18868 @brief user-defined string literal for JSON values
18869
18870 This operator implements a user-defined string literal for JSON objects. It
18871 can be used by adding `"_json"` to a string literal and returns a JSON object
18872 if no parse error occurred.
18873
18874 @param[in] s a string representation of a JSON object
18875 @param[in] n the length of string @a s
18876 @return a JSON object
18877
18878 @since version 1.0.0
18879 */
operator ""_json(const char * s,std::size_t n)18880 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
18881 {
18882 return nlohmann::json::parse(s, s + n);
18883 }
18884
18885 /*!
18886 @brief user-defined string literal for JSON pointer
18887
18888 This operator implements a user-defined string literal for JSON Pointers. It
18889 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
18890 object if no parse error occurred.
18891
18892 @param[in] s a string representation of a JSON Pointer
18893 @param[in] n the length of string @a s
18894 @return a JSON pointer object
18895
18896 @since version 2.0.0
18897 */
operator ""_json_pointer(const char * s,std::size_t n)18898 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
18899 {
18900 return nlohmann::json::json_pointer(std::string(s, n));
18901 }
18902
18903 // #include <nlohmann/detail/macro_unscope.hpp>
18904
18905
18906 // restore GCC/clang diagnostic settings
18907 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
18908 #pragma GCC diagnostic pop
18909 #endif
18910 #if defined(__clang__)
18911 #pragma GCC diagnostic pop
18912 #endif
18913
18914 // clean up
18915 #undef JSON_INTERNAL_CATCH
18916 #undef JSON_CATCH
18917 #undef JSON_THROW
18918 #undef JSON_TRY
18919 #undef JSON_LIKELY
18920 #undef JSON_UNLIKELY
18921 #undef JSON_DEPRECATED
18922 #undef JSON_HAS_CPP_14
18923 #undef JSON_HAS_CPP_17
18924 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
18925 #undef NLOHMANN_BASIC_JSON_TPL
18926
18927
18928 #endif
18929