1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.2.0
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef NLOHMANN_JSON_HPP
31#define NLOHMANN_JSON_HPP
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 2
35#define NLOHMANN_JSON_VERSION_PATCH 0
36
37#include <algorithm> // all_of, find, for_each
38#include <cassert> // assert
39#include <ciso646> // and, not, or
40#include <cstddef> // nullptr_t, ptrdiff_t, size_t
41#include <functional> // hash, less
42#include <initializer_list> // initializer_list
43#include <iosfwd> // istream, ostream
44#include <iterator> // iterator_traits, random_access_iterator_tag
45#include <numeric> // accumulate
46#include <string> // string, stoi, to_string
47#include <utility> // declval, forward, move, pair, swap
48
49// #include <nlohmann/json_fwd.hpp>
50#ifndef NLOHMANN_JSON_FWD_HPP
51#define NLOHMANN_JSON_FWD_HPP
52
53#include <cstdint> // int64_t, uint64_t
54#include <map> // map
55#include <memory> // allocator
56#include <string> // string
57#include <vector> // vector
58
59/*!
60@brief namespace for Niels Lohmann
61@see https://github.com/nlohmann
62@since version 1.0.0
63*/
64namespace nlohmann
65{
66/*!
67@brief default JSONSerializer template argument
68
69This serializer ignores the template arguments and uses ADL
70([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
71for serialization.
72*/
73template<typename T = void, typename SFINAE = void>
74struct adl_serializer;
75
76template<template<typename U, typename V, typename... Args> class ObjectType =
77std::map,
78template<typename U, typename... Args> class ArrayType = std::vector,
79class StringType = std::string, class BooleanType = bool,
80class NumberIntegerType = std::int64_t,
81class NumberUnsignedType = std::uint64_t,
82class NumberFloatType = double,
83template<typename U> class AllocatorType = std::allocator,
84template<typename T, typename SFINAE = void> class JSONSerializer =
85adl_serializer>
86class basic_json;
87
88/*!
89@brief JSON Pointer
90
91A JSON pointer defines a string syntax for identifying a specific value
92within 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*/
99template<typename BasicJsonType>
100class json_pointer;
101
102/*!
103@brief default JSON class
104
105This type is the default specialization of the @ref basic_json class which
106uses the standard template types.
107
108@since version 1.0.0
109*/
110using json = basic_json<>;
111}
112
113#endif
114
115// #include <nlohmann/detail/macro_scope.hpp>
116
117
118// This file contains all internal macro definitions
119// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
120
121// exclude unsupported compilers
122#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
123#if defined(__clang__)
124#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
125#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
126#endif
127#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
128#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
129#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
130#endif
131#endif
132#endif
133
134// disable float-equal warnings on GCC/clang
135#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
136#pragma GCC diagnostic push
137#pragma GCC diagnostic ignored "-Wfloat-equal"
138#endif
139
140// disable documentation warnings on clang
141#if defined(__clang__)
142#pragma GCC diagnostic push
143#pragma GCC diagnostic ignored "-Wdocumentation"
144#endif
145
146// allow for portable deprecation warnings
147#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
148#define JSON_DEPRECATED __attribute__((deprecated))
149#elif defined(_MSC_VER)
150#define JSON_DEPRECATED __declspec(deprecated)
151#else
152#define JSON_DEPRECATED
153#endif
154
155// allow to disable exceptions
156#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
157#define JSON_THROW(exception) throw exception
158#define JSON_TRY try
159#define JSON_CATCH(exception) catch(exception)
160#define JSON_INTERNAL_CATCH(exception) catch(exception)
161#else
162#define JSON_THROW(exception) std::abort()
163#define JSON_TRY if(true)
164#define JSON_CATCH(exception) if(false)
165#define JSON_INTERNAL_CATCH(exception) if(false)
166#endif
167
168// override exception macros
169#if defined(JSON_THROW_USER)
170#undef JSON_THROW
171#define JSON_THROW JSON_THROW_USER
172#endif
173#if defined(JSON_TRY_USER)
174#undef JSON_TRY
175#define JSON_TRY JSON_TRY_USER
176#endif
177#if defined(JSON_CATCH_USER)
178#undef JSON_CATCH
179#define JSON_CATCH JSON_CATCH_USER
180#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
228namespace nlohmann
229{
230namespace detail
231{
232// alias templates to reduce boilerplate
233template<bool B, typename T = void>
234using enable_if_t = typename std::enable_if<B, T>::type;
235
236template<typename T>
237using 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
241template<std::size_t... Ints>
242struct index_sequence
243{
244using type = index_sequence;
245using value_type = std::size_t;
246static constexpr std::size_t size() noexcept
247{
248return sizeof...(Ints);
249}
250};
251
252template<class Sequence1, class Sequence2>
253struct merge_and_renumber;
254
255template<std::size_t... I1, std::size_t... I2>
256struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
257: index_sequence < I1..., (sizeof...(I1) + I2)... > {};
258
259template<std::size_t N>
260struct make_index_sequence
261: merge_and_renumber < typename make_index_sequence < N / 2 >::type,
262typename make_index_sequence < N - N / 2 >::type > {};
263
264template<> struct make_index_sequence<0> : index_sequence<> {};
265template<> struct make_index_sequence<1> : index_sequence<0> {};
266
267template<typename... Ts>
268using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
269
270// dispatch utility (taken from ranges-v3)
271template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
272template<> struct priority_tag<0> {};
273
274// taken from ranges-v3
275template<typename T>
276struct static_const
277{
278static constexpr T value{};
279};
280
281template<typename T>
282constexpr 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
306namespace nlohmann
307{
308namespace detail
309{
310template <typename ...Ts> struct make_void
311{
312using type = void;
313};
314template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
315}
316}
317
318
319// http://en.cppreference.com/w/cpp/experimental/is_detected
320namespace nlohmann
321{
322namespace detail
323{
324struct nonesuch
325{
326nonesuch() = delete;
327~nonesuch() = delete;
328nonesuch(nonesuch const&) = delete;
329void operator=(nonesuch const&) = delete;
330};
331
332template <class Default,
333class AlwaysVoid,
334template <class...> class Op,
335class... Args>
336struct detector
337{
338using value_t = std::false_type;
339using type = Default;
340};
341
342template <class Default, template <class...> class Op, class... Args>
343struct detector<Default, void_t<Op<Args...>>, Op, Args...>
344{
345using value_t = std::true_type;
346using type = Op<Args...>;
347};
348
349template <template <class...> class Op, class... Args>
350using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
351
352template <template <class...> class Op, class... Args>
353using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
354
355template <class Default, template <class...> class Op, class... Args>
356using detected_or = detector<Default, void, Op, Args...>;
357
358template <class Default, template <class...> class Op, class... Args>
359using detected_or_t = typename detected_or<Default, Op, Args...>::type;
360
361template <class Expected, template <class...> class Op, class... Args>
362using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
363
364template <class To, template <class...> class Op, class... Args>
365using is_detected_convertible =
366std::is_convertible<detected_t<Op, Args...>, To>;
367}
368}
369
370// #include <nlohmann/detail/macro_scope.hpp>
371
372
373namespace nlohmann
374{
375/*!
376@brief detail namespace with internal helper functions
377
378This namespace collects functions that should not be exposed,
379implementations of some @ref basic_json methods, and meta-programming helpers.
380
381@since version 2.1.0
382*/
383namespace detail
384{
385/////////////
386// helpers //
387/////////////
388
389template<typename> struct is_basic_json : std::false_type {};
390
391NLOHMANN_BASIC_JSON_TPL_DECLARATION
392struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
393
394//////////////////////////
395// aliases for detected //
396//////////////////////////
397
398template <typename T>
399using mapped_type_t = typename T::mapped_type;
400
401template <typename T>
402using key_type_t = typename T::key_type;
403
404template <typename T>
405using value_type_t = typename T::value_type;
406
407template <typename T>
408using difference_type_t = typename T::difference_type;
409
410template <typename T>
411using pointer_t = typename T::pointer;
412
413template <typename T>
414using reference_t = typename T::reference;
415
416template <typename T>
417using iterator_category_t = typename T::iterator_category;
418
419template <typename T>
420using iterator_t = typename T::iterator;
421
422template <typename T, typename... Args>
423using to_json_function = decltype(T::to_json(std::declval<Args>()...));
424
425template <typename T, typename... Args>
426using from_json_function = decltype(T::from_json(std::declval<Args>()...));
427
428///////////////////
429// is_ functions //
430///////////////////
431
432template <typename T, typename = void>
433struct is_iterator_traits : std::false_type {};
434
435template <typename T>
436struct is_iterator_traits<std::iterator_traits<T>>
437{
438private:
439using traits = std::iterator_traits<T>;
440
441public:
442static constexpr auto value =
443is_detected<value_type_t, traits>::value &&
444is_detected<difference_type_t, traits>::value &&
445is_detected<pointer_t, traits>::value &&
446is_detected<iterator_category_t, traits>::value &&
447is_detected<reference_t, traits>::value;
448};
449
450// source: https://stackoverflow.com/a/37193089/4116453
451
452template <typename T, typename = void>
453struct is_complete_type : std::false_type {};
454
455template <typename T>
456struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
457
458template <typename BasicJsonType, typename CompatibleObjectType,
459typename = void>
460struct is_compatible_object_type_impl : std::false_type {};
461
462template <typename BasicJsonType, typename CompatibleObjectType>
463struct is_compatible_object_type_impl <
464BasicJsonType, CompatibleObjectType,
465enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
466is_detected<key_type_t, CompatibleObjectType>::value >>
467{
468
469using object_t = typename BasicJsonType::object_t;
470
471// macOS's is_constructible does not play well with nonesuch...
472static constexpr bool value =
473std::is_constructible<typename object_t::key_type,
474typename CompatibleObjectType::key_type>::value and
475std::is_constructible<typename object_t::mapped_type,
476typename CompatibleObjectType::mapped_type>::value;
477};
478
479template <typename BasicJsonType, typename CompatibleObjectType>
480struct is_compatible_object_type
481: is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
482
483template <typename BasicJsonType, typename CompatibleStringType,
484typename = void>
485struct is_compatible_string_type_impl : std::false_type {};
486
487template <typename BasicJsonType, typename CompatibleStringType>
488struct is_compatible_string_type_impl <
489BasicJsonType, CompatibleStringType,
490enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
491value_type_t, CompatibleStringType>::value >>
492{
493static constexpr auto value =
494std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
495};
496
497template <typename BasicJsonType, typename CompatibleStringType>
498struct is_compatible_string_type
499: is_compatible_string_type_impl<BasicJsonType, CompatibleStringType> {};
500
501template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
502struct is_compatible_array_type_impl : std::false_type {};
503
504template <typename BasicJsonType, typename CompatibleArrayType>
505struct is_compatible_array_type_impl <
506BasicJsonType, CompatibleArrayType,
507enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
508is_detected<iterator_t, CompatibleArrayType>::value >>
509{
510// This is needed because json_reverse_iterator has a ::iterator type...
511// Therefore it is detected as a CompatibleArrayType.
512// The real fix would be to have an Iterable concept.
513static constexpr bool value = not is_iterator_traits<std::iterator_traits<CompatibleArrayType>>::value;
514};
515
516template <typename BasicJsonType, typename CompatibleArrayType>
517struct is_compatible_array_type
518: is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
519
520template <typename RealIntegerType, typename CompatibleNumberIntegerType,
521typename = void>
522struct is_compatible_integer_type_impl : std::false_type {};
523
524template <typename RealIntegerType, typename CompatibleNumberIntegerType>
525struct is_compatible_integer_type_impl <
526RealIntegerType, CompatibleNumberIntegerType,
527enable_if_t<std::is_integral<RealIntegerType>::value and
528std::is_integral<CompatibleNumberIntegerType>::value and
529not std::is_same<bool, CompatibleNumberIntegerType>::value >>
530{
531// is there an assert somewhere on overflows?
532using RealLimits = std::numeric_limits<RealIntegerType>;
533using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
534
535static constexpr auto value =
536std::is_constructible<RealIntegerType,
537CompatibleNumberIntegerType>::value and
538CompatibleLimits::is_integer and
539RealLimits::is_signed == CompatibleLimits::is_signed;
540};
541
542template <typename RealIntegerType, typename CompatibleNumberIntegerType>
543struct is_compatible_integer_type
544: is_compatible_integer_type_impl<RealIntegerType,
545CompatibleNumberIntegerType> {};
546
547// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
548template<typename BasicJsonType, typename T>
549struct has_from_json
550{
551using serializer = typename BasicJsonType::template json_serializer<T, void>;
552
553static constexpr bool value =
554is_detected_exact<void, from_json_function, serializer,
555const BasicJsonType&, T&>::value;
556};
557
558// This trait checks if JSONSerializer<T>::from_json(json const&) exists
559// this overload is used for non-default-constructible user-defined-types
560template<typename BasicJsonType, typename T>
561struct has_non_default_from_json
562{
563using serializer = typename BasicJsonType::template json_serializer<T, void>;
564
565static constexpr bool value =
566is_detected_exact<T, from_json_function, serializer,
567const BasicJsonType&>::value;
568};
569
570// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
571template<typename BasicJsonType, typename T>
572struct has_to_json
573{
574using serializer = typename BasicJsonType::template json_serializer<T, void>;
575
576static constexpr bool value =
577is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
578T>::value;
579};
580
581template <typename BasicJsonType, typename CompatibleType, typename = void>
582struct is_compatible_type_impl: std::false_type {};
583
584template <typename BasicJsonType, typename CompatibleType>
585struct is_compatible_type_impl <
586BasicJsonType, CompatibleType,
587enable_if_t<is_complete_type<CompatibleType>::value >>
588{
589static constexpr bool value =
590has_to_json<BasicJsonType, CompatibleType>::value;
591};
592
593template <typename BasicJsonType, typename CompatibleType>
594struct is_compatible_type
595: is_compatible_type_impl<BasicJsonType, CompatibleType> {};
596}
597}
598
599// #include <nlohmann/detail/exceptions.hpp>
600
601
602#include <exception> // exception
603#include <stdexcept> // runtime_error
604#include <string> // to_string
605
606namespace nlohmann
607{
608namespace detail
609{
610////////////////
611// exceptions //
612////////////////
613
614/*!
615@brief general exception of the @ref basic_json class
616
617This class is an extension of `std::exception` objects with a member @a id for
618exception ids. It is used as the base class for all exceptions thrown by the
619@ref basic_json class. This class can hence be used as "wildcard" to catch
620exceptions.
621
622Subclasses:
623- @ref parse_error for exceptions indicating a parse error
624- @ref invalid_iterator for exceptions indicating errors with iterators
625- @ref type_error for exceptions indicating executing a member function with
626 a wrong type
627- @ref out_of_range for exceptions indicating access out of the defined range
628- @ref other_error for exceptions indicating other library errors
629
630@internal
631@note To have nothrow-copy-constructible exceptions, we internally use
632 `std::runtime_error` which can cope with arbitrary-length error messages.
633 Intermediate strings are built with static functions and then passed to
634 the actual constructor.
635@endinternal
636
637@liveexample{The following code shows how arbitrary library exceptions can be
638caught.,exception}
639
640@since version 3.0.0
641*/
642class exception : public std::exception
643{
644public:
645/// returns the explanatory string
646const char* what() const noexcept override
647{
648return m.what();
649}
650
651/// the id of the exception
652const int id;
653
654protected:
655exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
656
657static std::string name(const std::string& ename, int id_)
658{
659return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
660}
661
662private:
663/// an exception object as storage for error messages
664std::runtime_error m;
665};
666
667/*!
668@brief exception indicating a parse error
669
670This exception is thrown by the library when a parse error occurs. Parse errors
671can occur during the deserialization of JSON text, CBOR, MessagePack, as well
672as when using JSON Patch.
673
674Member @a byte holds the byte index of the last read character in the input
675file.
676
677Exceptions have ids 1xx.
678
679name / id | example message | description
680------------------------------ | --------------- | -------------------------
681json.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.
682json.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.
683json.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.
684json.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.
685json.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.
686json.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`.
687json.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.
688json.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.
689json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
690json.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.
691json.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.
692json.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.
693
694@note For an input with n bytes, 1 is the index of the first character and n+1
695 is the index of the terminating null byte or the end of file. This also
696 holds true when reading a byte vector (CBOR or MessagePack).
697
698@liveexample{The following code shows how a `parse_error` exception can be
699caught.,parse_error}
700
701@sa @ref exception for the base class of the library exceptions
702@sa @ref invalid_iterator for exceptions indicating errors with iterators
703@sa @ref type_error for exceptions indicating executing a member function with
704 a wrong type
705@sa @ref out_of_range for exceptions indicating access out of the defined range
706@sa @ref other_error for exceptions indicating other library errors
707
708@since version 3.0.0
709*/
710class parse_error : public exception
711{
712public:
713/*!
714 @brief create a parse error exception
715 @param[in] id_ the id of the exception
716 @param[in] byte_ the byte index where the error occurred (or 0 if the
717 position cannot be determined)
718 @param[in] what_arg the explanatory string
719 @return parse_error object
720 */
721static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
722{
723std::string w = exception::name("parse_error", id_) + "parse error" +
724(byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
725": " + what_arg;
726return parse_error(id_, byte_, w.c_str());
727}
728
729/*!
730 @brief byte index of the parse error
731
732 The byte index of the last read character in the input file.
733
734 @note For an input with n bytes, 1 is the index of the first character and
735 n+1 is the index of the terminating null byte or the end of file.
736 This also holds true when reading a byte vector (CBOR or MessagePack).
737 */
738const std::size_t byte;
739
740private:
741parse_error(int id_, std::size_t byte_, const char* what_arg)
742: exception(id_, what_arg), byte(byte_) {}
743};
744
745/*!
746@brief exception indicating errors with iterators
747
748This exception is thrown if iterators passed to a library function do not match
749the expected semantics.
750
751Exceptions have ids 2xx.
752
753name / id | example message | description
754----------------------------------- | --------------- | -------------------------
755json.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.
756json.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.
757json.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.
758json.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.
759json.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.
760json.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.
761json.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.
762json.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.
763json.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.
764json.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.
765json.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.
766json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
767json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
768json.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().
769
770@liveexample{The following code shows how an `invalid_iterator` exception can be
771caught.,invalid_iterator}
772
773@sa @ref exception for the base class of the library exceptions
774@sa @ref parse_error for exceptions indicating a parse error
775@sa @ref type_error for exceptions indicating executing a member function with
776 a wrong type
777@sa @ref out_of_range for exceptions indicating access out of the defined range
778@sa @ref other_error for exceptions indicating other library errors
779
780@since version 3.0.0
781*/
782class invalid_iterator : public exception
783{
784public:
785static invalid_iterator create(int id_, const std::string& what_arg)
786{
787std::string w = exception::name("invalid_iterator", id_) + what_arg;
788return invalid_iterator(id_, w.c_str());
789}
790
791private:
792invalid_iterator(int id_, const char* what_arg)
793: exception(id_, what_arg) {}
794};
795
796/*!
797@brief exception indicating executing a member function with a wrong type
798
799This exception is thrown in case of a type error; that is, a library function is
800executed on a JSON value whose type does not match the expected semantics.
801
802Exceptions have ids 3xx.
803
804name / id | example message | description
805----------------------------- | --------------- | -------------------------
806json.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.
807json.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.
808json.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&.
809json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
810json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
811json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
812json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
813json.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.
814json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
815json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
816json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
817json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
818json.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.
819json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
820json.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.
821json.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. |
822
823@liveexample{The following code shows how a `type_error` exception can be
824caught.,type_error}
825
826@sa @ref exception for the base class of the library exceptions
827@sa @ref parse_error for exceptions indicating a parse error
828@sa @ref invalid_iterator for exceptions indicating errors with iterators
829@sa @ref out_of_range for exceptions indicating access out of the defined range
830@sa @ref other_error for exceptions indicating other library errors
831
832@since version 3.0.0
833*/
834class type_error : public exception
835{
836public:
837static type_error create(int id_, const std::string& what_arg)
838{
839std::string w = exception::name("type_error", id_) + what_arg;
840return type_error(id_, w.c_str());
841}
842
843private:
844type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
845};
846
847/*!
848@brief exception indicating access out of the defined range
849
850This exception is thrown in case a library function is called on an input
851parameter that exceeds the expected range, for instance in case of array
852indices or nonexisting object keys.
853
854Exceptions have ids 4xx.
855
856name / id | example message | description
857------------------------------- | --------------- | -------------------------
858json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
859json.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.
860json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
861json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
862json.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.
863json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
864json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON only supports integers numbers up to 9223372036854775807. |
865json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
866
867@liveexample{The following code shows how an `out_of_range` exception can be
868caught.,out_of_range}
869
870@sa @ref exception for the base class of the library exceptions
871@sa @ref parse_error for exceptions indicating a parse error
872@sa @ref invalid_iterator for exceptions indicating errors with iterators
873@sa @ref type_error for exceptions indicating executing a member function with
874 a wrong type
875@sa @ref other_error for exceptions indicating other library errors
876
877@since version 3.0.0
878*/
879class out_of_range : public exception
880{
881public:
882static out_of_range create(int id_, const std::string& what_arg)
883{
884std::string w = exception::name("out_of_range", id_) + what_arg;
885return out_of_range(id_, w.c_str());
886}
887
888private:
889out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
890};
891
892/*!
893@brief exception indicating other library errors
894
895This exception is thrown in case of errors that cannot be classified with the
896other exception types.
897
898Exceptions have ids 5xx.
899
900name / id | example message | description
901------------------------------ | --------------- | -------------------------
902json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
903
904@sa @ref exception for the base class of the library exceptions
905@sa @ref parse_error for exceptions indicating a parse error
906@sa @ref invalid_iterator for exceptions indicating errors with iterators
907@sa @ref type_error for exceptions indicating executing a member function with
908 a wrong type
909@sa @ref out_of_range for exceptions indicating access out of the defined range
910
911@liveexample{The following code shows how an `other_error` exception can be
912caught.,other_error}
913
914@since version 3.0.0
915*/
916class other_error : public exception
917{
918public:
919static other_error create(int id_, const std::string& what_arg)
920{
921std::string w = exception::name("other_error", id_) + what_arg;
922return other_error(id_, w.c_str());
923}
924
925private:
926other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
927};
928}
929}
930
931// #include <nlohmann/detail/value_t.hpp>
932
933
934#include <array> // array
935#include <ciso646> // and
936#include <cstddef> // size_t
937#include <cstdint> // uint8_t
938
939namespace nlohmann
940{
941namespace detail
942{
943///////////////////////////
944// JSON type enumeration //
945///////////////////////////
946
947/*!
948@brief the JSON type enumeration
949
950This enumeration collects the different JSON types. It is internally used to
951distinguish the stored values, and the functions @ref basic_json::is_null(),
952@ref basic_json::is_object(), @ref basic_json::is_array(),
953@ref basic_json::is_string(), @ref basic_json::is_boolean(),
954@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
955@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
956@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
957@ref basic_json::is_structured() rely on it.
958
959@note There are three enumeration entries (number_integer, number_unsigned, and
960number_float), because the library distinguishes these three types for numbers:
961@ref basic_json::number_unsigned_t is used for unsigned integers,
962@ref basic_json::number_integer_t is used for signed integers, and
963@ref basic_json::number_float_t is used for floating-point numbers or to
964approximate integers which do not fit in the limits of their respective type.
965
966@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
967value with the default value for a given type
968
969@since version 1.0.0
970*/
971enum class value_t : std::uint8_t
972{
973null, ///< null value
974object, ///< object (unordered set of name/value pairs)
975array, ///< array (ordered collection of values)
976string, ///< string value
977boolean, ///< boolean value
978number_integer, ///< number value (signed integer)
979number_unsigned, ///< number value (unsigned integer)
980number_float, ///< number value (floating-point)
981discarded ///< discarded by the the parser callback function
982};
983
984/*!
985@brief comparison operator for JSON types
986
987Returns an ordering that is similar to Python:
988- order: null < boolean < number < object < array < string
989- furthermore, each type is not smaller than itself
990- discarded values are not comparable
991
992@since version 1.0.0
993*/
994inline bool operator<(const value_t lhs, const value_t rhs) noexcept
995{
996static constexpr std::array<std::uint8_t, 8> order = {{
9970 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
9981 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
999}
1000};
1001
1002const auto l_index = static_cast<std::size_t>(lhs);
1003const auto r_index = static_cast<std::size_t>(rhs);
1004return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1005}
1006}
1007}
1008
1009// #include <nlohmann/detail/conversions/from_json.hpp>
1010
1011
1012#include <algorithm> // transform
1013#include <array> // array
1014#include <ciso646> // and, not
1015#include <forward_list> // forward_list
1016#include <iterator> // inserter, front_inserter, end
1017#include <map> // map
1018#include <string> // string
1019#include <tuple> // tuple, make_tuple
1020#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
1021#include <unordered_map> // unordered_map
1022#include <utility> // pair, declval
1023#include <valarray> // valarray
1024
1025// #include <nlohmann/detail/exceptions.hpp>
1026
1027// #include <nlohmann/detail/macro_scope.hpp>
1028
1029// #include <nlohmann/detail/meta/cpp_future.hpp>
1030
1031// #include <nlohmann/detail/meta/type_traits.hpp>
1032
1033// #include <nlohmann/detail/value_t.hpp>
1034
1035
1036namespace nlohmann
1037{
1038namespace detail
1039{
1040template<typename BasicJsonType>
1041void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1042{
1043if (JSON_UNLIKELY(not j.is_null()))
1044{
1045JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1046}
1047n = nullptr;
1048}
1049
1050// overloads for basic_json template parameters
1051template<typename BasicJsonType, typename ArithmeticType,
1052enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1053not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1054int> = 0>
1055void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1056{
1057switch (static_cast<value_t>(j))
1058{
1059case value_t::number_unsigned:
1060{
1061val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1062break;
1063}
1064case value_t::number_integer:
1065{
1066val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1067break;
1068}
1069case value_t::number_float:
1070{
1071val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1072break;
1073}
1074
1075default:
1076JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1077}
1078}
1079
1080template<typename BasicJsonType>
1081void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1082{
1083if (JSON_UNLIKELY(not j.is_boolean()))
1084{
1085JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1086}
1087b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1088}
1089
1090template<typename BasicJsonType>
1091void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1092{
1093if (JSON_UNLIKELY(not j.is_string()))
1094{
1095JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1096}
1097s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1098}
1099
1100template <
1101typename BasicJsonType, typename CompatibleStringType,
1102enable_if_t <
1103is_compatible_string_type<BasicJsonType, CompatibleStringType>::value and
1104not std::is_same<typename BasicJsonType::string_t,
1105CompatibleStringType>::value,
1106int > = 0 >
1107void from_json(const BasicJsonType& j, CompatibleStringType& s)
1108{
1109if (JSON_UNLIKELY(not j.is_string()))
1110{
1111JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1112}
1113
1114s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1115}
1116
1117template<typename BasicJsonType>
1118void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1119{
1120get_arithmetic_value(j, val);
1121}
1122
1123template<typename BasicJsonType>
1124void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1125{
1126get_arithmetic_value(j, val);
1127}
1128
1129template<typename BasicJsonType>
1130void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1131{
1132get_arithmetic_value(j, val);
1133}
1134
1135template<typename BasicJsonType, typename EnumType,
1136enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1137void from_json(const BasicJsonType& j, EnumType& e)
1138{
1139typename std::underlying_type<EnumType>::type val;
1140get_arithmetic_value(j, val);
1141e = static_cast<EnumType>(val);
1142}
1143
1144// forward_list doesn't have an insert method
1145template<typename BasicJsonType, typename T, typename Allocator,
1146enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1147void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1148{
1149if (JSON_UNLIKELY(not j.is_array()))
1150{
1151JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1152}
1153std::transform(j.rbegin(), j.rend(),
1154std::front_inserter(l), [](const BasicJsonType & i)
1155{
1156return i.template get<T>();
1157});
1158}
1159
1160// valarray doesn't have an insert method
1161template<typename BasicJsonType, typename T,
1162enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1163void from_json(const BasicJsonType& j, std::valarray<T>& l)
1164{
1165if (JSON_UNLIKELY(not j.is_array()))
1166{
1167JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1168}
1169l.resize(j.size());
1170std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1171}
1172
1173template<typename BasicJsonType>
1174void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1175{
1176arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1177}
1178
1179template <typename BasicJsonType, typename T, std::size_t N>
1180auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1181priority_tag<2> /*unused*/)
1182-> decltype(j.template get<T>(), void())
1183{
1184for (std::size_t i = 0; i < N; ++i)
1185{
1186arr[i] = j.at(i).template get<T>();
1187}
1188}
1189
1190template<typename BasicJsonType, typename CompatibleArrayType>
1191auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1192-> decltype(
1193arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1194j.template get<typename CompatibleArrayType::value_type>(),
1195void())
1196{
1197using std::end;
1198
1199arr.reserve(j.size());
1200std::transform(j.begin(), j.end(),
1201std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1202{
1203// get<BasicJsonType>() returns *this, this won't call a from_json
1204// method when value_type is BasicJsonType
1205return i.template get<typename CompatibleArrayType::value_type>();
1206});
1207}
1208
1209template <typename BasicJsonType, typename CompatibleArrayType>
1210void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr,
1211priority_tag<0> /*unused*/)
1212{
1213using std::end;
1214
1215std::transform(
1216j.begin(), j.end(), std::inserter(arr, end(arr)),
1217[](const BasicJsonType & i)
1218{
1219// get<BasicJsonType>() returns *this, this won't call a from_json
1220// method when value_type is BasicJsonType
1221return i.template get<typename CompatibleArrayType::value_type>();
1222});
1223}
1224
1225template <typename BasicJsonType, typename CompatibleArrayType,
1226enable_if_t <
1227is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1228not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
1229not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
1230not is_basic_json<CompatibleArrayType>::value,
1231int > = 0 >
1232
1233auto from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1234-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1235j.template get<typename CompatibleArrayType::value_type>(),
1236void())
1237{
1238if (JSON_UNLIKELY(not j.is_array()))
1239{
1240JSON_THROW(type_error::create(302, "type must be array, but is " +
1241std::string(j.type_name())));
1242}
1243
1244from_json_array_impl(j, arr, priority_tag<3> {});
1245}
1246
1247template<typename BasicJsonType, typename CompatibleObjectType,
1248enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1249void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1250{
1251if (JSON_UNLIKELY(not j.is_object()))
1252{
1253JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1254}
1255
1256auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1257using value_type = typename CompatibleObjectType::value_type;
1258std::transform(
1259inner_object->begin(), inner_object->end(),
1260std::inserter(obj, obj.begin()),
1261[](typename BasicJsonType::object_t::value_type const & p)
1262{
1263return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1264});
1265}
1266
1267// overload for arithmetic types, not chosen for basic_json template arguments
1268// (BooleanType, etc..); note: Is it really necessary to provide explicit
1269// overloads for boolean_t etc. in case of a custom BooleanType which is not
1270// an arithmetic type?
1271template<typename BasicJsonType, typename ArithmeticType,
1272enable_if_t <
1273std::is_arithmetic<ArithmeticType>::value and
1274not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1275not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1276not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1277not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1278int> = 0>
1279void from_json(const BasicJsonType& j, ArithmeticType& val)
1280{
1281switch (static_cast<value_t>(j))
1282{
1283case value_t::number_unsigned:
1284{
1285val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1286break;
1287}
1288case value_t::number_integer:
1289{
1290val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1291break;
1292}
1293case value_t::number_float:
1294{
1295val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1296break;
1297}
1298case value_t::boolean:
1299{
1300val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1301break;
1302}
1303
1304default:
1305JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1306}
1307}
1308
1309template<typename BasicJsonType, typename A1, typename A2>
1310void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1311{
1312p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1313}
1314
1315template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1316void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1317{
1318t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1319}
1320
1321template<typename BasicJsonType, typename... Args>
1322void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1323{
1324from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1325}
1326
1327template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1328typename = enable_if_t<not std::is_constructible<
1329typename BasicJsonType::string_t, Key>::value>>
1330void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1331{
1332if (JSON_UNLIKELY(not j.is_array()))
1333{
1334JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1335}
1336for (const auto& p : j)
1337{
1338if (JSON_UNLIKELY(not p.is_array()))
1339{
1340JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1341}
1342m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1343}
1344}
1345
1346template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1347typename = enable_if_t<not std::is_constructible<
1348typename BasicJsonType::string_t, Key>::value>>
1349void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1350{
1351if (JSON_UNLIKELY(not j.is_array()))
1352{
1353JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1354}
1355for (const auto& p : j)
1356{
1357if (JSON_UNLIKELY(not p.is_array()))
1358{
1359JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1360}
1361m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1362}
1363}
1364
1365struct from_json_fn
1366{
1367template<typename BasicJsonType, typename T>
1368auto operator()(const BasicJsonType& j, T& val) const
1369noexcept(noexcept(from_json(j, val)))
1370-> decltype(from_json(j, val), void())
1371{
1372return from_json(j, val);
1373}
1374};
1375}
1376
1377/// namespace to hold default `from_json` function
1378/// to see why this is required:
1379/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1380namespace
1381{
1382constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1383}
1384}
1385
1386// #include <nlohmann/detail/conversions/to_json.hpp>
1387
1388
1389#include <ciso646> // or, and, not
1390#include <iterator> // begin, end
1391#include <tuple> // tuple, get
1392#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1393#include <utility> // move, forward, declval, pair
1394#include <valarray> // valarray
1395#include <vector> // vector
1396
1397// #include <nlohmann/detail/meta/cpp_future.hpp>
1398
1399// #include <nlohmann/detail/meta/type_traits.hpp>
1400
1401// #include <nlohmann/detail/value_t.hpp>
1402
1403// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1404
1405
1406#include <cstddef> // size_t
1407#include <string> // string, to_string
1408#include <iterator> // input_iterator_tag
1409
1410// #include <nlohmann/detail/value_t.hpp>
1411
1412
1413namespace nlohmann
1414{
1415namespace detail
1416{
1417/// proxy class for the items() function
1418template<typename IteratorType> class iteration_proxy
1419{
1420private:
1421/// helper class for iteration
1422class iteration_proxy_internal
1423{
1424public:
1425using difference_type = std::ptrdiff_t;
1426using value_type = iteration_proxy_internal;
1427using pointer = iteration_proxy_internal*;
1428using reference = iteration_proxy_internal&;
1429using iterator_category = std::input_iterator_tag;
1430
1431private:
1432/// the iterator
1433IteratorType anchor;
1434/// an index for arrays (used to create key names)
1435std::size_t array_index = 0;
1436/// last stringified array index
1437mutable std::size_t array_index_last = 0;
1438/// a string representation of the array index
1439mutable std::string array_index_str = "0";
1440/// an empty string (to return a reference for primitive values)
1441const std::string empty_str = "";
1442
1443public:
1444explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
1445
1446iteration_proxy_internal(const iteration_proxy_internal&) = default;
1447iteration_proxy_internal& operator=(const iteration_proxy_internal&) = default;
1448
1449/// dereference operator (needed for range-based for)
1450iteration_proxy_internal& operator*()
1451{
1452return *this;
1453}
1454
1455/// increment operator (needed for range-based for)
1456iteration_proxy_internal& operator++()
1457{
1458++anchor;
1459++array_index;
1460
1461return *this;
1462}
1463
1464/// equality operator (needed for InputIterator)
1465bool operator==(const iteration_proxy_internal& o) const noexcept
1466{
1467return anchor == o.anchor;
1468}
1469
1470/// inequality operator (needed for range-based for)
1471bool operator!=(const iteration_proxy_internal& o) const noexcept
1472{
1473return anchor != o.anchor;
1474}
1475
1476/// return key of the iterator
1477const std::string& key() const
1478{
1479assert(anchor.m_object != nullptr);
1480
1481switch (anchor.m_object->type())
1482{
1483// use integer array index as key
1484case value_t::array:
1485{
1486if (array_index != array_index_last)
1487{
1488array_index_str = std::to_string(array_index);
1489array_index_last = array_index;
1490}
1491return array_index_str;
1492}
1493
1494// use key from the object
1495case value_t::object:
1496return anchor.key();
1497
1498// use an empty key for all primitive types
1499default:
1500return empty_str;
1501}
1502}
1503
1504/// return value of the iterator
1505typename IteratorType::reference value() const
1506{
1507return anchor.value();
1508}
1509};
1510
1511/// the container to iterate
1512typename IteratorType::reference container;
1513
1514public:
1515/// construct iteration proxy from a container
1516explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1517: container(cont) {}
1518
1519/// return iterator begin (needed for range-based for)
1520iteration_proxy_internal begin() noexcept
1521{
1522return iteration_proxy_internal(container.begin());
1523}
1524
1525/// return iterator end (needed for range-based for)
1526iteration_proxy_internal end() noexcept
1527{
1528return iteration_proxy_internal(container.end());
1529}
1530};
1531}
1532}
1533
1534
1535namespace nlohmann
1536{
1537namespace detail
1538{
1539//////////////////
1540// constructors //
1541//////////////////
1542
1543template<value_t> struct external_constructor;
1544
1545template<>
1546struct external_constructor<value_t::boolean>
1547{
1548template<typename BasicJsonType>
1549static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1550{
1551j.m_type = value_t::boolean;
1552j.m_value = b;
1553j.assert_invariant();
1554}
1555};
1556
1557template<>
1558struct external_constructor<value_t::string>
1559{
1560template<typename BasicJsonType>
1561static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1562{
1563j.m_type = value_t::string;
1564j.m_value = s;
1565j.assert_invariant();
1566}
1567
1568template<typename BasicJsonType>
1569static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1570{
1571j.m_type = value_t::string;
1572j.m_value = std::move(s);
1573j.assert_invariant();
1574}
1575
1576template<typename BasicJsonType, typename CompatibleStringType,
1577enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1578int> = 0>
1579static void construct(BasicJsonType& j, const CompatibleStringType& str)
1580{
1581j.m_type = value_t::string;
1582j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1583j.assert_invariant();
1584}
1585};
1586
1587template<>
1588struct external_constructor<value_t::number_float>
1589{
1590template<typename BasicJsonType>
1591static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1592{
1593j.m_type = value_t::number_float;
1594j.m_value = val;
1595j.assert_invariant();
1596}
1597};
1598
1599template<>
1600struct external_constructor<value_t::number_unsigned>
1601{
1602template<typename BasicJsonType>
1603static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1604{
1605j.m_type = value_t::number_unsigned;
1606j.m_value = val;
1607j.assert_invariant();
1608}
1609};
1610
1611template<>
1612struct external_constructor<value_t::number_integer>
1613{
1614template<typename BasicJsonType>
1615static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1616{
1617j.m_type = value_t::number_integer;
1618j.m_value = val;
1619j.assert_invariant();
1620}
1621};
1622
1623template<>
1624struct external_constructor<value_t::array>
1625{
1626template<typename BasicJsonType>
1627static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1628{
1629j.m_type = value_t::array;
1630j.m_value = arr;
1631j.assert_invariant();
1632}
1633
1634template<typename BasicJsonType>
1635static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1636{
1637j.m_type = value_t::array;
1638j.m_value = std::move(arr);
1639j.assert_invariant();
1640}
1641
1642template<typename BasicJsonType, typename CompatibleArrayType,
1643enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1644int> = 0>
1645static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1646{
1647using std::begin;
1648using std::end;
1649j.m_type = value_t::array;
1650j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1651j.assert_invariant();
1652}
1653
1654template<typename BasicJsonType>
1655static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1656{
1657j.m_type = value_t::array;
1658j.m_value = value_t::array;
1659j.m_value.array->reserve(arr.size());
1660for (const bool x : arr)
1661{
1662j.m_value.array->push_back(x);
1663}
1664j.assert_invariant();
1665}
1666
1667template<typename BasicJsonType, typename T,
1668enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1669static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1670{
1671j.m_type = value_t::array;
1672j.m_value = value_t::array;
1673j.m_value.array->resize(arr.size());
1674std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1675j.assert_invariant();
1676}
1677};
1678
1679template<>
1680struct external_constructor<value_t::object>
1681{
1682template<typename BasicJsonType>
1683static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1684{
1685j.m_type = value_t::object;
1686j.m_value = obj;
1687j.assert_invariant();
1688}
1689
1690template<typename BasicJsonType>
1691static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1692{
1693j.m_type = value_t::object;
1694j.m_value = std::move(obj);
1695j.assert_invariant();
1696}
1697
1698template<typename BasicJsonType, typename CompatibleObjectType,
1699enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
1700static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1701{
1702using std::begin;
1703using std::end;
1704
1705j.m_type = value_t::object;
1706j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1707j.assert_invariant();
1708}
1709};
1710
1711/////////////
1712// to_json //
1713/////////////
1714
1715template<typename BasicJsonType, typename T,
1716enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
1717void to_json(BasicJsonType& j, T b) noexcept
1718{
1719external_constructor<value_t::boolean>::construct(j, b);
1720}
1721
1722template<typename BasicJsonType, typename CompatibleString,
1723enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
1724void to_json(BasicJsonType& j, const CompatibleString& s)
1725{
1726external_constructor<value_t::string>::construct(j, s);
1727}
1728
1729template<typename BasicJsonType>
1730void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1731{
1732external_constructor<value_t::string>::construct(j, std::move(s));
1733}
1734
1735template<typename BasicJsonType, typename FloatType,
1736enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
1737void to_json(BasicJsonType& j, FloatType val) noexcept
1738{
1739external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1740}
1741
1742template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1743enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
1744void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1745{
1746external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1747}
1748
1749template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1750enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
1751void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1752{
1753external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1754}
1755
1756template<typename BasicJsonType, typename EnumType,
1757enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1758void to_json(BasicJsonType& j, EnumType e) noexcept
1759{
1760using underlying_type = typename std::underlying_type<EnumType>::type;
1761external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1762}
1763
1764template<typename BasicJsonType>
1765void to_json(BasicJsonType& j, const std::vector<bool>& e)
1766{
1767external_constructor<value_t::array>::construct(j, e);
1768}
1769
1770template <typename BasicJsonType, typename CompatibleArrayType,
1771enable_if_t<is_compatible_array_type<BasicJsonType,
1772CompatibleArrayType>::value and
1773not is_compatible_object_type<
1774BasicJsonType, CompatibleArrayType>::value and
1775not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
1776not is_basic_json<CompatibleArrayType>::value,
1777int> = 0>
1778void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1779{
1780external_constructor<value_t::array>::construct(j, arr);
1781}
1782
1783template<typename BasicJsonType, typename T,
1784enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1785void to_json(BasicJsonType& j, const std::valarray<T>& arr)
1786{
1787external_constructor<value_t::array>::construct(j, std::move(arr));
1788}
1789
1790template<typename BasicJsonType>
1791void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1792{
1793external_constructor<value_t::array>::construct(j, std::move(arr));
1794}
1795
1796template<typename BasicJsonType, typename CompatibleObjectType,
1797enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
1798void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1799{
1800external_constructor<value_t::object>::construct(j, obj);
1801}
1802
1803template<typename BasicJsonType>
1804void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1805{
1806external_constructor<value_t::object>::construct(j, std::move(obj));
1807}
1808
1809template <
1810typename BasicJsonType, typename T, std::size_t N,
1811enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
1812const T (&)[N]>::value,
1813int> = 0 >
1814void to_json(BasicJsonType& j, const T (&arr)[N])
1815{
1816external_constructor<value_t::array>::construct(j, arr);
1817}
1818
1819template<typename BasicJsonType, typename... Args>
1820void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1821{
1822j = {p.first, p.second};
1823}
1824
1825// for https://github.com/nlohmann/json/pull/1134
1826template<typename BasicJsonType, typename T,
1827enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
1828void to_json(BasicJsonType& j, T b) noexcept
1829{
1830j = {{b.key(), b.value()}};
1831}
1832
1833template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1834void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1835{
1836j = {std::get<Idx>(t)...};
1837}
1838
1839template<typename BasicJsonType, typename... Args>
1840void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1841{
1842to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1843}
1844
1845struct to_json_fn
1846{
1847template<typename BasicJsonType, typename T>
1848auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1849-> decltype(to_json(j, std::forward<T>(val)), void())
1850{
1851return to_json(j, std::forward<T>(val));
1852}
1853};
1854}
1855
1856/// namespace to hold default `to_json` function
1857namespace
1858{
1859constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1860}
1861}
1862
1863// #include <nlohmann/detail/input/input_adapters.hpp>
1864
1865
1866#include <cassert> // assert
1867#include <cstddef> // size_t
1868#include <cstring> // strlen
1869#include <istream> // istream
1870#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1871#include <memory> // shared_ptr, make_shared, addressof
1872#include <numeric> // accumulate
1873#include <string> // string, char_traits
1874#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1875#include <utility> // pair, declval
1876
1877// #include <nlohmann/detail/macro_scope.hpp>
1878
1879
1880namespace nlohmann
1881{
1882namespace detail
1883{
1884/// the supported input formats
1885enum class input_format_t { json, cbor, msgpack, ubjson };
1886
1887////////////////////
1888// input adapters //
1889////////////////////
1890
1891/*!
1892@brief abstract input adapter interface
1893
1894Produces a stream of std::char_traits<char>::int_type characters from a
1895std::istream, a buffer, or some other input type. Accepts the return of
1896exactly one non-EOF character for future input. The int_type characters
1897returned consist of all valid char values as positive values (typically
1898unsigned char), plus an EOF value outside that range, specified by the value
1899of the function std::char_traits<char>::eof(). This value is typically -1, but
1900could be any arbitrary value which is not a valid char value.
1901*/
1902struct input_adapter_protocol
1903{
1904/// get a character [0,255] or std::char_traits<char>::eof().
1905virtual std::char_traits<char>::int_type get_character() = 0;
1906virtual ~input_adapter_protocol() = default;
1907};
1908
1909/// a type to simplify interfaces
1910using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1911
1912/*!
1913Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1914beginning of input. Does not support changing the underlying std::streambuf
1915in mid-input. Maintains underlying std::istream and std::streambuf to support
1916subsequent use of standard std::istream operations to process any input
1917characters following those used in parsing the JSON input. Clears the
1918std::istream flags; any input errors (e.g., EOF) will be detected by the first
1919subsequent call for input from the std::istream.
1920*/
1921class input_stream_adapter : public input_adapter_protocol
1922{
1923public:
1924~input_stream_adapter() override
1925{
1926// clear stream flags; we use underlying streambuf I/O, do not
1927// maintain ifstream flags
1928is.clear();
1929}
1930
1931explicit input_stream_adapter(std::istream& i)
1932: is(i), sb(*i.rdbuf())
1933{}
1934
1935// delete because of pointer members
1936input_stream_adapter(const input_stream_adapter&) = delete;
1937input_stream_adapter& operator=(input_stream_adapter&) = delete;
1938
1939// std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1940// ensure that std::char_traits<char>::eof() and the character 0xFF do not
1941// end up as the same value, eg. 0xFFFFFFFF.
1942std::char_traits<char>::int_type get_character() override
1943{
1944return sb.sbumpc();
1945}
1946
1947private:
1948/// the associated input stream
1949std::istream& is;
1950std::streambuf& sb;
1951};
1952
1953/// input adapter for buffer input
1954class input_buffer_adapter : public input_adapter_protocol
1955{
1956public:
1957input_buffer_adapter(const char* b, const std::size_t l)
1958: cursor(b), limit(b + l)
1959{}
1960
1961// delete because of pointer members
1962input_buffer_adapter(const input_buffer_adapter&) = delete;
1963input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1964
1965std::char_traits<char>::int_type get_character() noexcept override
1966{
1967if (JSON_LIKELY(cursor < limit))
1968{
1969return std::char_traits<char>::to_int_type(*(cursor++));
1970}
1971
1972return std::char_traits<char>::eof();
1973}
1974
1975private:
1976/// pointer to the current character
1977const char* cursor;
1978/// pointer past the last character
1979const char* const limit;
1980};
1981
1982template<typename WideStringType>
1983class wide_string_input_adapter : public input_adapter_protocol
1984{
1985public:
1986explicit wide_string_input_adapter(const WideStringType& w) : str(w) {}
1987
1988std::char_traits<char>::int_type get_character() noexcept override
1989{
1990// check if buffer needs to be filled
1991if (utf8_bytes_index == utf8_bytes_filled)
1992{
1993if (sizeof(typename WideStringType::value_type) == 2)
1994{
1995fill_buffer_utf16();
1996}
1997else
1998{
1999fill_buffer_utf32();
2000}
2001
2002assert(utf8_bytes_filled > 0);
2003assert(utf8_bytes_index == 0);
2004}
2005
2006// use buffer
2007assert(utf8_bytes_filled > 0);
2008assert(utf8_bytes_index < utf8_bytes_filled);
2009return utf8_bytes[utf8_bytes_index++];
2010}
2011
2012private:
2013void fill_buffer_utf16()
2014{
2015utf8_bytes_index = 0;
2016
2017if (current_wchar == str.size())
2018{
2019utf8_bytes[0] = std::char_traits<char>::eof();
2020utf8_bytes_filled = 1;
2021}
2022else
2023{
2024// get the current character
2025const int wc = static_cast<int>(str[current_wchar++]);
2026
2027// UTF-16 to UTF-8 encoding
2028if (wc < 0x80)
2029{
2030utf8_bytes[0] = wc;
2031utf8_bytes_filled = 1;
2032}
2033else if (wc <= 0x7FF)
2034{
2035utf8_bytes[0] = 0xC0 | ((wc >> 6));
2036utf8_bytes[1] = 0x80 | (wc & 0x3F);
2037utf8_bytes_filled = 2;
2038}
2039else if (0xD800 > wc or wc >= 0xE000)
2040{
2041utf8_bytes[0] = 0xE0 | ((wc >> 12));
2042utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2043utf8_bytes[2] = 0x80 | (wc & 0x3F);
2044utf8_bytes_filled = 3;
2045}
2046else
2047{
2048if (current_wchar < str.size())
2049{
2050const int wc2 = static_cast<int>(str[current_wchar++]);
2051const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2052utf8_bytes[0] = 0xf0 | (charcode >> 18);
2053utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2054utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2055utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2056utf8_bytes_filled = 4;
2057}
2058else
2059{
2060// unknown character
2061++current_wchar;
2062utf8_bytes[0] = wc;
2063utf8_bytes_filled = 1;
2064}
2065}
2066}
2067}
2068
2069void fill_buffer_utf32()
2070{
2071utf8_bytes_index = 0;
2072
2073if (current_wchar == str.size())
2074{
2075utf8_bytes[0] = std::char_traits<char>::eof();
2076utf8_bytes_filled = 1;
2077}
2078else
2079{
2080// get the current character
2081const int wc = static_cast<int>(str[current_wchar++]);
2082
2083// UTF-32 to UTF-8 encoding
2084if (wc < 0x80)
2085{
2086utf8_bytes[0] = wc;
2087utf8_bytes_filled = 1;
2088}
2089else if (wc <= 0x7FF)
2090{
2091utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2092utf8_bytes[1] = 0x80 | (wc & 0x3F);
2093utf8_bytes_filled = 2;
2094}
2095else if (wc <= 0xFFFF)
2096{
2097utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2098utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2099utf8_bytes[2] = 0x80 | (wc & 0x3F);
2100utf8_bytes_filled = 3;
2101}
2102else if (wc <= 0x10FFFF)
2103{
2104utf8_bytes[0] = 0xF0 | ((wc >> 18 ) & 0x07);
2105utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2106utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2107utf8_bytes[3] = 0x80 | (wc & 0x3F);
2108utf8_bytes_filled = 4;
2109}
2110else
2111{
2112// unknown character
2113utf8_bytes[0] = wc;
2114utf8_bytes_filled = 1;
2115}
2116}
2117}
2118
2119private:
2120/// the wstring to process
2121const WideStringType& str;
2122
2123/// index of the current wchar in str
2124std::size_t current_wchar = 0;
2125
2126/// a buffer for UTF-8 bytes
2127std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2128
2129/// index to the utf8_codes array for the next valid byte
2130std::size_t utf8_bytes_index = 0;
2131/// number of valid bytes in the utf8_codes array
2132std::size_t utf8_bytes_filled = 0;
2133};
2134
2135class input_adapter
2136{
2137public:
2138// native support
2139
2140/// input adapter for input stream
2141input_adapter(std::istream& i)
2142: ia(std::make_shared<input_stream_adapter>(i)) {}
2143
2144/// input adapter for input stream
2145input_adapter(std::istream&& i)
2146: ia(std::make_shared<input_stream_adapter>(i)) {}
2147
2148input_adapter(const std::wstring& ws)
2149: ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2150
2151input_adapter(const std::u16string& ws)
2152: ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2153
2154input_adapter(const std::u32string& ws)
2155: ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2156
2157/// input adapter for buffer
2158template<typename CharT,
2159typename std::enable_if<
2160std::is_pointer<CharT>::value and
2161std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2162sizeof(typename std::remove_pointer<CharT>::type) == 1,
2163int>::type = 0>
2164input_adapter(CharT b, std::size_t l)
2165: ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2166
2167// derived support
2168
2169/// input adapter for string literal
2170template<typename CharT,
2171typename std::enable_if<
2172std::is_pointer<CharT>::value and
2173std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2174sizeof(typename std::remove_pointer<CharT>::type) == 1,
2175int>::type = 0>
2176input_adapter(CharT b)
2177: input_adapter(reinterpret_cast<const char*>(b),
2178std::strlen(reinterpret_cast<const char*>(b))) {}
2179
2180/// input adapter for iterator range with contiguous storage
2181template<class IteratorType,
2182typename std::enable_if<
2183std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2184int>::type = 0>
2185input_adapter(IteratorType first, IteratorType last)
2186{
2187#ifndef NDEBUG
2188// assertion to check that the iterator range is indeed contiguous,
2189// see http://stackoverflow.com/a/35008842/266378 for more discussion
2190const auto is_contiguous = std::accumulate(
2191first, last, std::pair<bool, int>(true, 0),
2192[&first](std::pair<bool, int> res, decltype(*first) val)
2193{
2194res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2195return res;
2196}).first;
2197assert(is_contiguous);
2198#endif
2199
2200// assertion to check that each element is 1 byte long
2201static_assert(
2202sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
2203"each element in the iterator range must have the size of 1 byte");
2204
2205const auto len = static_cast<size_t>(std::distance(first, last));
2206if (JSON_LIKELY(len > 0))
2207{
2208// there is at least one element: use the address of first
2209ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2210}
2211else
2212{
2213// the address of first cannot be used: use nullptr
2214ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2215}
2216}
2217
2218/// input adapter for array
2219template<class T, std::size_t N>
2220input_adapter(T (&array)[N])
2221: input_adapter(std::begin(array), std::end(array)) {}
2222
2223/// input adapter for contiguous container
2224template<class ContiguousContainer, typename
2225std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2226std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2227int>::type = 0>
2228input_adapter(const ContiguousContainer& c)
2229: input_adapter(std::begin(c), std::end(c)) {}
2230
2231operator input_adapter_t()
2232{
2233return ia;
2234}
2235
2236private:
2237/// the actual adapter
2238input_adapter_t ia = nullptr;
2239};
2240}
2241}
2242
2243// #include <nlohmann/detail/input/lexer.hpp>
2244
2245
2246#include <clocale> // localeconv
2247#include <cstddef> // size_t
2248#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
2249#include <cstdio> // snprintf
2250#include <initializer_list> // initializer_list
2251#include <string> // char_traits, string
2252#include <vector> // vector
2253
2254// #include <nlohmann/detail/macro_scope.hpp>
2255
2256// #include <nlohmann/detail/input/input_adapters.hpp>
2257
2258
2259namespace nlohmann
2260{
2261namespace detail
2262{
2263///////////
2264// lexer //
2265///////////
2266
2267/*!
2268@brief lexical analysis
2269
2270This class organizes the lexical analysis during JSON deserialization.
2271*/
2272template<typename BasicJsonType>
2273class lexer
2274{
2275using number_integer_t = typename BasicJsonType::number_integer_t;
2276using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2277using number_float_t = typename BasicJsonType::number_float_t;
2278using string_t = typename BasicJsonType::string_t;
2279
2280public:
2281/// token types for the parser
2282enum class token_type
2283{
2284uninitialized, ///< indicating the scanner is uninitialized
2285literal_true, ///< the `true` literal
2286literal_false, ///< the `false` literal
2287literal_null, ///< the `null` literal
2288value_string, ///< a string -- use get_string() for actual value
2289value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
2290value_integer, ///< a signed integer -- use get_number_integer() for actual value
2291value_float, ///< an floating point number -- use get_number_float() for actual value
2292begin_array, ///< the character for array begin `[`
2293begin_object, ///< the character for object begin `{`
2294end_array, ///< the character for array end `]`
2295end_object, ///< the character for object end `}`
2296name_separator, ///< the name separator `:`
2297value_separator, ///< the value separator `,`
2298parse_error, ///< indicating a parse error
2299end_of_input, ///< indicating the end of the input buffer
2300literal_or_value ///< a literal or the begin of a value (only for diagnostics)
2301};
2302
2303/// return name of values of type token_type (only used for errors)
2304static const char* token_type_name(const token_type t) noexcept
2305{
2306switch (t)
2307{
2308case token_type::uninitialized:
2309return "<uninitialized>";
2310case token_type::literal_true:
2311return "true literal";
2312case token_type::literal_false:
2313return "false literal";
2314case token_type::literal_null:
2315return "null literal";
2316case token_type::value_string:
2317return "string literal";
2318case lexer::token_type::value_unsigned:
2319case lexer::token_type::value_integer:
2320case lexer::token_type::value_float:
2321return "number literal";
2322case token_type::begin_array:
2323return "'['";
2324case token_type::begin_object:
2325return "'{'";
2326case token_type::end_array:
2327return "']'";
2328case token_type::end_object:
2329return "'}'";
2330case token_type::name_separator:
2331return "':'";
2332case token_type::value_separator:
2333return "','";
2334case token_type::parse_error:
2335return "<parse error>";
2336case token_type::end_of_input:
2337return "end of input";
2338case token_type::literal_or_value:
2339return "'[', '{', or a literal";
2340// LCOV_EXCL_START
2341default: // catch non-enum values
2342return "unknown token";
2343// LCOV_EXCL_STOP
2344}
2345}
2346
2347explicit lexer(detail::input_adapter_t&& adapter)
2348: ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2349
2350// delete because of pointer members
2351lexer(const lexer&) = delete;
2352lexer& operator=(lexer&) = delete;
2353
2354private:
2355/////////////////////
2356// locales
2357/////////////////////
2358
2359/// return the locale-dependent decimal point
2360static char get_decimal_point() noexcept
2361{
2362const auto loc = localeconv();
2363assert(loc != nullptr);
2364return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2365}
2366
2367/////////////////////
2368// scan functions
2369/////////////////////
2370
2371/*!
2372 @brief get codepoint from 4 hex characters following `\u`
2373
2374 For input "\u c1 c2 c3 c4" the codepoint is:
2375 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
2376 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
2377
2378 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
2379 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
2380 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
2381 between the ASCII value of the character and the desired integer value.
2382
2383 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
2384 non-hex character)
2385 */
2386int get_codepoint()
2387{
2388// this function only makes sense after reading `\u`
2389assert(current == 'u');
2390int codepoint = 0;
2391
2392const auto factors = { 12, 8, 4, 0 };
2393for (const auto factor : factors)
2394{
2395get();
2396
2397if (current >= '0' and current <= '9')
2398{
2399codepoint += ((current - 0x30) << factor);
2400}
2401else if (current >= 'A' and current <= 'F')
2402{
2403codepoint += ((current - 0x37) << factor);
2404}
2405else if (current >= 'a' and current <= 'f')
2406{
2407codepoint += ((current - 0x57) << factor);
2408}
2409else
2410{
2411return -1;
2412}
2413}
2414
2415assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2416return codepoint;
2417}
2418
2419/*!
2420 @brief check if the next byte(s) are inside a given range
2421
2422 Adds the current byte and, for each passed range, reads a new byte and
2423 checks if it is inside the range. If a violation was detected, set up an
2424 error message and return false. Otherwise, return true.
2425
2426 @param[in] ranges list of integers; interpreted as list of pairs of
2427 inclusive lower and upper bound, respectively
2428
2429 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
2430 1, 2, or 3 pairs. This precondition is enforced by an assertion.
2431
2432 @return true if and only if no range violation was detected
2433 */
2434bool next_byte_in_range(std::initializer_list<int> ranges)
2435{
2436assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2437add(current);
2438
2439for (auto range = ranges.begin(); range != ranges.end(); ++range)
2440{
2441get();
2442if (JSON_LIKELY(*range <= current and current <= *(++range)))
2443{
2444add(current);
2445}
2446else
2447{
2448error_message = "invalid string: ill-formed UTF-8 byte";
2449return false;
2450}
2451}
2452
2453return true;
2454}
2455
2456/*!
2457 @brief scan a string literal
2458
2459 This function scans a string according to Sect. 7 of RFC 7159. While
2460 scanning, bytes are escaped and copied into buffer token_buffer. Then the
2461 function returns successfully, token_buffer is *not* null-terminated (as it
2462 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
2463 string.
2464
2465 @return token_type::value_string if string could be successfully scanned,
2466 token_type::parse_error otherwise
2467
2468 @note In case of errors, variable error_message contains a textual
2469 description.
2470 */
2471token_type scan_string()
2472{
2473// reset token_buffer (ignore opening quote)
2474reset();
2475
2476// we entered the function by reading an open quote
2477assert(current == '\"');
2478
2479while (true)
2480{
2481// get next character
2482switch (get())
2483{
2484// end of file while parsing string
2485case std::char_traits<char>::eof():
2486{
2487error_message = "invalid string: missing closing quote";
2488return token_type::parse_error;
2489}
2490
2491// closing quote
2492case '\"':
2493{
2494return token_type::value_string;
2495}
2496
2497// escapes
2498case '\\':
2499{
2500switch (get())
2501{
2502// quotation mark
2503case '\"':
2504add('\"');
2505break;
2506// reverse solidus
2507case '\\':
2508add('\\');
2509break;
2510// solidus
2511case '/':
2512add('/');
2513break;
2514// backspace
2515case 'b':
2516add('\b');
2517break;
2518// form feed
2519case 'f':
2520add('\f');
2521break;
2522// line feed
2523case 'n':
2524add('\n');
2525break;
2526// carriage return
2527case 'r':
2528add('\r');
2529break;
2530// tab
2531case 't':
2532add('\t');
2533break;
2534
2535// unicode escapes
2536case 'u':
2537{
2538const int codepoint1 = get_codepoint();
2539int codepoint = codepoint1; // start with codepoint1
2540
2541if (JSON_UNLIKELY(codepoint1 == -1))
2542{
2543error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2544return token_type::parse_error;
2545}
2546
2547// check if code point is a high surrogate
2548if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2549{
2550// expect next \uxxxx entry
2551if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2552{
2553const int codepoint2 = get_codepoint();
2554
2555if (JSON_UNLIKELY(codepoint2 == -1))
2556{
2557error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2558return token_type::parse_error;
2559}
2560
2561// check if codepoint2 is a low surrogate
2562if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2563{
2564// overwrite codepoint
2565codepoint =
2566// high surrogate occupies the most significant 22 bits
2567(codepoint1 << 10)
2568// low surrogate occupies the least significant 15 bits
2569+ codepoint2
2570// there is still the 0xD800, 0xDC00 and 0x10000 noise
2571// in the result so we have to subtract with:
2572// (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2573- 0x35FDC00;
2574}
2575else
2576{
2577error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2578return token_type::parse_error;
2579}
2580}
2581else
2582{
2583error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2584return token_type::parse_error;
2585}
2586}
2587else
2588{
2589if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2590{
2591error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2592return token_type::parse_error;
2593}
2594}
2595
2596// result of the above calculation yields a proper codepoint
2597assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2598
2599// translate codepoint into bytes
2600if (codepoint < 0x80)
2601{
2602// 1-byte characters: 0xxxxxxx (ASCII)
2603add(codepoint);
2604}
2605else if (codepoint <= 0x7FF)
2606{
2607// 2-byte characters: 110xxxxx 10xxxxxx
2608add(0xC0 | (codepoint >> 6));
2609add(0x80 | (codepoint & 0x3F));
2610}
2611else if (codepoint <= 0xFFFF)
2612{
2613// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2614add(0xE0 | (codepoint >> 12));
2615add(0x80 | ((codepoint >> 6) & 0x3F));
2616add(0x80 | (codepoint & 0x3F));
2617}
2618else
2619{
2620// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2621add(0xF0 | (codepoint >> 18));
2622add(0x80 | ((codepoint >> 12) & 0x3F));
2623add(0x80 | ((codepoint >> 6) & 0x3F));
2624add(0x80 | (codepoint & 0x3F));
2625}
2626
2627break;
2628}
2629
2630// other characters after escape
2631default:
2632error_message = "invalid string: forbidden character after backslash";
2633return token_type::parse_error;
2634}
2635
2636break;
2637}
2638
2639// invalid control characters
2640case 0x00:
2641case 0x01:
2642case 0x02:
2643case 0x03:
2644case 0x04:
2645case 0x05:
2646case 0x06:
2647case 0x07:
2648case 0x08:
2649case 0x09:
2650case 0x0A:
2651case 0x0B:
2652case 0x0C:
2653case 0x0D:
2654case 0x0E:
2655case 0x0F:
2656case 0x10:
2657case 0x11:
2658case 0x12:
2659case 0x13:
2660case 0x14:
2661case 0x15:
2662case 0x16:
2663case 0x17:
2664case 0x18:
2665case 0x19:
2666case 0x1A:
2667case 0x1B:
2668case 0x1C:
2669case 0x1D:
2670case 0x1E:
2671case 0x1F:
2672{
2673error_message = "invalid string: control character must be escaped";
2674return token_type::parse_error;
2675}
2676
2677// U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2678case 0x20:
2679case 0x21:
2680case 0x23:
2681case 0x24:
2682case 0x25:
2683case 0x26:
2684case 0x27:
2685case 0x28:
2686case 0x29:
2687case 0x2A:
2688case 0x2B:
2689case 0x2C:
2690case 0x2D:
2691case 0x2E:
2692case 0x2F:
2693case 0x30:
2694case 0x31:
2695case 0x32:
2696case 0x33:
2697case 0x34:
2698case 0x35:
2699case 0x36:
2700case 0x37:
2701case 0x38:
2702case 0x39:
2703case 0x3A:
2704case 0x3B:
2705case 0x3C:
2706case 0x3D:
2707case 0x3E:
2708case 0x3F:
2709case 0x40:
2710case 0x41:
2711case 0x42:
2712case 0x43:
2713case 0x44:
2714case 0x45:
2715case 0x46:
2716case 0x47:
2717case 0x48:
2718case 0x49:
2719case 0x4A:
2720case 0x4B:
2721case 0x4C:
2722case 0x4D:
2723case 0x4E:
2724case 0x4F:
2725case 0x50:
2726case 0x51:
2727case 0x52:
2728case 0x53:
2729case 0x54:
2730case 0x55:
2731case 0x56:
2732case 0x57:
2733case 0x58:
2734case 0x59:
2735case 0x5A:
2736case 0x5B:
2737case 0x5D:
2738case 0x5E:
2739case 0x5F:
2740case 0x60:
2741case 0x61:
2742case 0x62:
2743case 0x63:
2744case 0x64:
2745case 0x65:
2746case 0x66:
2747case 0x67:
2748case 0x68:
2749case 0x69:
2750case 0x6A:
2751case 0x6B:
2752case 0x6C:
2753case 0x6D:
2754case 0x6E:
2755case 0x6F:
2756case 0x70:
2757case 0x71:
2758case 0x72:
2759case 0x73:
2760case 0x74:
2761case 0x75:
2762case 0x76:
2763case 0x77:
2764case 0x78:
2765case 0x79:
2766case 0x7A:
2767case 0x7B:
2768case 0x7C:
2769case 0x7D:
2770case 0x7E:
2771case 0x7F:
2772{
2773add(current);
2774break;
2775}
2776
2777// U+0080..U+07FF: bytes C2..DF 80..BF
2778case 0xC2:
2779case 0xC3:
2780case 0xC4:
2781case 0xC5:
2782case 0xC6:
2783case 0xC7:
2784case 0xC8:
2785case 0xC9:
2786case 0xCA:
2787case 0xCB:
2788case 0xCC:
2789case 0xCD:
2790case 0xCE:
2791case 0xCF:
2792case 0xD0:
2793case 0xD1:
2794case 0xD2:
2795case 0xD3:
2796case 0xD4:
2797case 0xD5:
2798case 0xD6:
2799case 0xD7:
2800case 0xD8:
2801case 0xD9:
2802case 0xDA:
2803case 0xDB:
2804case 0xDC:
2805case 0xDD:
2806case 0xDE:
2807case 0xDF:
2808{
2809if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2810{
2811return token_type::parse_error;
2812}
2813break;
2814}
2815
2816// U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2817case 0xE0:
2818{
2819if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2820{
2821return token_type::parse_error;
2822}
2823break;
2824}
2825
2826// U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2827// U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2828case 0xE1:
2829case 0xE2:
2830case 0xE3:
2831case 0xE4:
2832case 0xE5:
2833case 0xE6:
2834case 0xE7:
2835case 0xE8:
2836case 0xE9:
2837case 0xEA:
2838case 0xEB:
2839case 0xEC:
2840case 0xEE:
2841case 0xEF:
2842{
2843if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2844{
2845return token_type::parse_error;
2846}
2847break;
2848}
2849
2850// U+D000..U+D7FF: bytes ED 80..9F 80..BF
2851case 0xED:
2852{
2853if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2854{
2855return token_type::parse_error;
2856}
2857break;
2858}
2859
2860// U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2861case 0xF0:
2862{
2863if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2864{
2865return token_type::parse_error;
2866}
2867break;
2868}
2869
2870// U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2871case 0xF1:
2872case 0xF2:
2873case 0xF3:
2874{
2875if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2876{
2877return token_type::parse_error;
2878}
2879break;
2880}
2881
2882// U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2883case 0xF4:
2884{
2885if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2886{
2887return token_type::parse_error;
2888}
2889break;
2890}
2891
2892// remaining bytes (80..C1 and F5..FF) are ill-formed
2893default:
2894{
2895error_message = "invalid string: ill-formed UTF-8 byte";
2896return token_type::parse_error;
2897}
2898}
2899}
2900}
2901
2902static void strtof(float& f, const char* str, char** endptr) noexcept
2903{
2904f = std::strtof(str, endptr);
2905}
2906
2907static void strtof(double& f, const char* str, char** endptr) noexcept
2908{
2909f = std::strtod(str, endptr);
2910}
2911
2912static void strtof(long double& f, const char* str, char** endptr) noexcept
2913{
2914f = std::strtold(str, endptr);
2915}
2916
2917/*!
2918 @brief scan a number literal
2919
2920 This function scans a string according to Sect. 6 of RFC 7159.
2921
2922 The function is realized with a deterministic finite state machine derived
2923 from the grammar described in RFC 7159. Starting in state "init", the
2924 input is read and used to determined the next state. Only state "done"
2925 accepts the number. State "error" is a trap state to model errors. In the
2926 table below, "anything" means any character but the ones listed before.
2927
2928 state | 0 | 1-9 | e E | + | - | . | anything
2929 ---------|----------|----------|----------|---------|---------|----------|-----------
2930 init | zero | any1 | [error] | [error] | minus | [error] | [error]
2931 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
2932 zero | done | done | exponent | done | done | decimal1 | done
2933 any1 | any1 | any1 | exponent | done | done | decimal1 | done
2934 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
2935 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
2936 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
2937 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
2938 any2 | any2 | any2 | done | done | done | done | done
2939
2940 The state machine is realized with one label per state (prefixed with
2941 "scan_number_") and `goto` statements between them. The state machine
2942 contains cycles, but any cycle can be left when EOF is read. Therefore,
2943 the function is guaranteed to terminate.
2944
2945 During scanning, the read bytes are stored in token_buffer. This string is
2946 then converted to a signed integer, an unsigned integer, or a
2947 floating-point number.
2948
2949 @return token_type::value_unsigned, token_type::value_integer, or
2950 token_type::value_float if number could be successfully scanned,
2951 token_type::parse_error otherwise
2952
2953 @note The scanner is independent of the current locale. Internally, the
2954 locale's decimal point is used instead of `.` to work with the
2955 locale-dependent converters.
2956 */
2957token_type scan_number()
2958{
2959// reset token_buffer to store the number's bytes
2960reset();
2961
2962// the type of the parsed number; initially set to unsigned; will be
2963// changed if minus sign, decimal point or exponent is read
2964token_type number_type = token_type::value_unsigned;
2965
2966// state (init): we just found out we need to scan a number
2967switch (current)
2968{
2969case '-':
2970{
2971add(current);
2972goto scan_number_minus;
2973}
2974
2975case '0':
2976{
2977add(current);
2978goto scan_number_zero;
2979}
2980
2981case '1':
2982case '2':
2983case '3':
2984case '4':
2985case '5':
2986case '6':
2987case '7':
2988case '8':
2989case '9':
2990{
2991add(current);
2992goto scan_number_any1;
2993}
2994
2995// LCOV_EXCL_START
2996default:
2997{
2998// all other characters are rejected outside scan_number()
2999assert(false);
3000}
3001// LCOV_EXCL_STOP
3002}
3003
3004scan_number_minus:
3005// state: we just parsed a leading minus sign
3006number_type = token_type::value_integer;
3007switch (get())
3008{
3009case '0':
3010{
3011add(current);
3012goto scan_number_zero;
3013}
3014
3015case '1':
3016case '2':
3017case '3':
3018case '4':
3019case '5':
3020case '6':
3021case '7':
3022case '8':
3023case '9':
3024{
3025add(current);
3026goto scan_number_any1;
3027}
3028
3029default:
3030{
3031error_message = "invalid number; expected digit after '-'";
3032return token_type::parse_error;
3033}
3034}
3035
3036scan_number_zero:
3037// state: we just parse a zero (maybe with a leading minus sign)
3038switch (get())
3039{
3040case '.':
3041{
3042add(decimal_point_char);
3043goto scan_number_decimal1;
3044}
3045
3046case 'e':
3047case 'E':
3048{
3049add(current);
3050goto scan_number_exponent;
3051}
3052
3053default:
3054goto scan_number_done;
3055}
3056
3057scan_number_any1:
3058// state: we just parsed a number 0-9 (maybe with a leading minus sign)
3059switch (get())
3060{
3061case '0':
3062case '1':
3063case '2':
3064case '3':
3065case '4':
3066case '5':
3067case '6':
3068case '7':
3069case '8':
3070case '9':
3071{
3072add(current);
3073goto scan_number_any1;
3074}
3075
3076case '.':
3077{
3078add(decimal_point_char);
3079goto scan_number_decimal1;
3080}
3081
3082case 'e':
3083case 'E':
3084{
3085add(current);
3086goto scan_number_exponent;
3087}
3088
3089default:
3090goto scan_number_done;
3091}
3092
3093scan_number_decimal1:
3094// state: we just parsed a decimal point
3095number_type = token_type::value_float;
3096switch (get())
3097{
3098case '0':
3099case '1':
3100case '2':
3101case '3':
3102case '4':
3103case '5':
3104case '6':
3105case '7':
3106case '8':
3107case '9':
3108{
3109add(current);
3110goto scan_number_decimal2;
3111}
3112
3113default:
3114{
3115error_message = "invalid number; expected digit after '.'";
3116return token_type::parse_error;
3117}
3118}
3119
3120scan_number_decimal2:
3121// we just parsed at least one number after a decimal point
3122switch (get())
3123{
3124case '0':
3125case '1':
3126case '2':
3127case '3':
3128case '4':
3129case '5':
3130case '6':
3131case '7':
3132case '8':
3133case '9':
3134{
3135add(current);
3136goto scan_number_decimal2;
3137}
3138
3139case 'e':
3140case 'E':
3141{
3142add(current);
3143goto scan_number_exponent;
3144}
3145
3146default:
3147goto scan_number_done;
3148}
3149
3150scan_number_exponent:
3151// we just parsed an exponent
3152number_type = token_type::value_float;
3153switch (get())
3154{
3155case '+':
3156case '-':
3157{
3158add(current);
3159goto scan_number_sign;
3160}
3161
3162case '0':
3163case '1':
3164case '2':
3165case '3':
3166case '4':
3167case '5':
3168case '6':
3169case '7':
3170case '8':
3171case '9':
3172{
3173add(current);
3174goto scan_number_any2;
3175}
3176
3177default:
3178{
3179error_message =
3180"invalid number; expected '+', '-', or digit after exponent";
3181return token_type::parse_error;
3182}
3183}
3184
3185scan_number_sign:
3186// we just parsed an exponent sign
3187switch (get())
3188{
3189case '0':
3190case '1':
3191case '2':
3192case '3':
3193case '4':
3194case '5':
3195case '6':
3196case '7':
3197case '8':
3198case '9':
3199{
3200add(current);
3201goto scan_number_any2;
3202}
3203
3204default:
3205{
3206error_message = "invalid number; expected digit after exponent sign";
3207return token_type::parse_error;
3208}
3209}
3210
3211scan_number_any2:
3212// we just parsed a number after the exponent or exponent sign
3213switch (get())
3214{
3215case '0':
3216case '1':
3217case '2':
3218case '3':
3219case '4':
3220case '5':
3221case '6':
3222case '7':
3223case '8':
3224case '9':
3225{
3226add(current);
3227goto scan_number_any2;
3228}
3229
3230default:
3231goto scan_number_done;
3232}
3233
3234scan_number_done:
3235// unget the character after the number (we only read it to know that
3236// we are done scanning a number)
3237unget();
3238
3239char* endptr = nullptr;
3240errno = 0;
3241
3242// try to parse integers first and fall back to floats
3243if (number_type == token_type::value_unsigned)
3244{
3245const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3246
3247// we checked the number format before
3248assert(endptr == token_buffer.data() + token_buffer.size());
3249
3250if (errno == 0)
3251{
3252value_unsigned = static_cast<number_unsigned_t>(x);
3253if (value_unsigned == x)
3254{
3255return token_type::value_unsigned;
3256}
3257}
3258}
3259else if (number_type == token_type::value_integer)
3260{
3261const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3262
3263// we checked the number format before
3264assert(endptr == token_buffer.data() + token_buffer.size());
3265
3266if (errno == 0)
3267{
3268value_integer = static_cast<number_integer_t>(x);
3269if (value_integer == x)
3270{
3271return token_type::value_integer;
3272}
3273}
3274}
3275
3276// this code is reached if we parse a floating-point number or if an
3277// integer conversion above failed
3278strtof(value_float, token_buffer.data(), &endptr);
3279
3280// we checked the number format before
3281assert(endptr == token_buffer.data() + token_buffer.size());
3282
3283return token_type::value_float;
3284}
3285
3286/*!
3287 @param[in] literal_text the literal text to expect
3288 @param[in] length the length of the passed literal text
3289 @param[in] return_type the token type to return on success
3290 */
3291token_type scan_literal(const char* literal_text, const std::size_t length,
3292token_type return_type)
3293{
3294assert(current == literal_text[0]);
3295for (std::size_t i = 1; i < length; ++i)
3296{
3297if (JSON_UNLIKELY(get() != literal_text[i]))
3298{
3299error_message = "invalid literal";
3300return token_type::parse_error;
3301}
3302}
3303return return_type;
3304}
3305
3306/////////////////////
3307// input management
3308/////////////////////
3309
3310/// reset token_buffer; current character is beginning of token
3311void reset() noexcept
3312{
3313token_buffer.clear();
3314token_string.clear();
3315token_string.push_back(std::char_traits<char>::to_char_type(current));
3316}
3317
3318/*
3319 @brief get next character from the input
3320
3321 This function provides the interface to the used input adapter. It does
3322 not throw in case the input reached EOF, but returns a
3323 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
3324 for use in error messages.
3325
3326 @return character read from the input
3327 */
3328std::char_traits<char>::int_type get()
3329{
3330++chars_read;
3331if (next_unget)
3332{
3333// just reset the next_unget variable and work with current
3334next_unget = false;
3335}
3336else
3337{
3338current = ia->get_character();
3339}
3340
3341if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3342{
3343token_string.push_back(std::char_traits<char>::to_char_type(current));
3344}
3345return current;
3346}
3347
3348/*!
3349 @brief unget current character (read it again on next get)
3350
3351 We implement unget by setting variable next_unget to true. The input is not
3352 changed - we just simulate ungetting by modifying chars_read and
3353 token_string. The next call to get() will behave as if the unget character
3354 is read again.
3355 */
3356void unget()
3357{
3358next_unget = true;
3359--chars_read;
3360if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3361{
3362assert(token_string.size() != 0);
3363token_string.pop_back();
3364}
3365}
3366
3367/// add a character to token_buffer
3368void add(int c)
3369{
3370token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3371}
3372
3373public:
3374/////////////////////
3375// value getters
3376/////////////////////
3377
3378/// return integer value
3379constexpr number_integer_t get_number_integer() const noexcept
3380{
3381return value_integer;
3382}
3383
3384/// return unsigned integer value
3385constexpr number_unsigned_t get_number_unsigned() const noexcept
3386{
3387return value_unsigned;
3388}
3389
3390/// return floating-point value
3391constexpr number_float_t get_number_float() const noexcept
3392{
3393return value_float;
3394}
3395
3396/// return current string value (implicitly resets the token; useful only once)
3397string_t& get_string()
3398{
3399return token_buffer;
3400}
3401
3402/////////////////////
3403// diagnostics
3404/////////////////////
3405
3406/// return position of last read token
3407constexpr std::size_t get_position() const noexcept
3408{
3409return chars_read;
3410}
3411
3412/// return the last read token (for errors only). Will never contain EOF
3413/// (an arbitrary value that is not a valid char value, often -1), because
3414/// 255 may legitimately occur. May contain NUL, which should be escaped.
3415std::string get_token_string() const
3416{
3417// escape control characters
3418std::string result;
3419for (const auto c : token_string)
3420{
3421if ('\x00' <= c and c <= '\x1F')
3422{
3423// escape control characters
3424char cs[9];
3425snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
3426result += cs;
3427}
3428else
3429{
3430// add character as is
3431result.push_back(c);
3432}
3433}
3434
3435return result;
3436}
3437
3438/// return syntax error message
3439constexpr const char* get_error_message() const noexcept
3440{
3441return error_message;
3442}
3443
3444/////////////////////
3445// actual scanner
3446/////////////////////
3447
3448/*!
3449 @brief skip the UTF-8 byte order mark
3450 @return true iff there is no BOM or the correct BOM has been skipped
3451 */
3452bool skip_bom()
3453{
3454if (get() == 0xEF)
3455{
3456if (get() == 0xBB and get() == 0xBF)
3457{
3458// we completely parsed the BOM
3459return true;
3460}
3461else
3462{
3463// after reading 0xEF, an unexpected character followed
3464return false;
3465}
3466}
3467else
3468{
3469// the first character is not the beginning of the BOM; unget it to
3470// process is later
3471unget();
3472return true;
3473}
3474}
3475
3476token_type scan()
3477{
3478// initially, skip the BOM
3479if (chars_read == 0 and not skip_bom())
3480{
3481error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
3482return token_type::parse_error;
3483}
3484
3485// read next character and ignore whitespace
3486do
3487{
3488get();
3489}
3490while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3491
3492switch (current)
3493{
3494// structural characters
3495case '[':
3496return token_type::begin_array;
3497case ']':
3498return token_type::end_array;
3499case '{':
3500return token_type::begin_object;
3501case '}':
3502return token_type::end_object;
3503case ':':
3504return token_type::name_separator;
3505case ',':
3506return token_type::value_separator;
3507
3508// literals
3509case 't':
3510return scan_literal("true", 4, token_type::literal_true);
3511case 'f':
3512return scan_literal("false", 5, token_type::literal_false);
3513case 'n':
3514return scan_literal("null", 4, token_type::literal_null);
3515
3516// string
3517case '\"':
3518return scan_string();
3519
3520// number
3521case '-':
3522case '0':
3523case '1':
3524case '2':
3525case '3':
3526case '4':
3527case '5':
3528case '6':
3529case '7':
3530case '8':
3531case '9':
3532return scan_number();
3533
3534// end of input (the null byte is needed when parsing from
3535// string literals)
3536case '\0':
3537case std::char_traits<char>::eof():
3538return token_type::end_of_input;
3539
3540// error
3541default:
3542error_message = "invalid literal";
3543return token_type::parse_error;
3544}
3545}
3546
3547private:
3548/// input adapter
3549detail::input_adapter_t ia = nullptr;
3550
3551/// the current character
3552std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3553
3554/// whether the next get() call should just return current
3555bool next_unget = false;
3556
3557/// the number of characters read
3558std::size_t chars_read = 0;
3559
3560/// raw input token string (for error messages)
3561std::vector<char> token_string {};
3562
3563/// buffer for variable-length tokens (numbers, strings)
3564string_t token_buffer {};
3565
3566/// a description of occurred lexer errors
3567const char* error_message = "";
3568
3569// number values
3570number_integer_t value_integer = 0;
3571number_unsigned_t value_unsigned = 0;
3572number_float_t value_float = 0;
3573
3574/// the decimal point
3575const char decimal_point_char = '.';
3576};
3577}
3578}
3579
3580// #include <nlohmann/detail/input/parser.hpp>
3581
3582
3583#include <cassert> // assert
3584#include <cmath> // isfinite
3585#include <cstdint> // uint8_t
3586#include <functional> // function
3587#include <string> // string
3588#include <utility> // move
3589
3590// #include <nlohmann/detail/exceptions.hpp>
3591
3592// #include <nlohmann/detail/macro_scope.hpp>
3593
3594// #include <nlohmann/detail/meta/is_sax.hpp>
3595
3596
3597#include <cstdint> // size_t
3598#include <utility> // declval
3599
3600// #include <nlohmann/detail/meta/detected.hpp>
3601
3602// #include <nlohmann/detail/meta/type_traits.hpp>
3603
3604
3605namespace nlohmann
3606{
3607namespace detail
3608{
3609template <typename T>
3610using null_function_t = decltype(std::declval<T&>().null());
3611
3612template <typename T>
3613using boolean_function_t =
3614decltype(std::declval<T&>().boolean(std::declval<bool>()));
3615
3616template <typename T, typename Integer>
3617using number_integer_function_t =
3618decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3619
3620template <typename T, typename Unsigned>
3621using number_unsigned_function_t =
3622decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3623
3624template <typename T, typename Float, typename String>
3625using number_float_function_t = decltype(std::declval<T&>().number_float(
3626std::declval<Float>(), std::declval<const String&>()));
3627
3628template <typename T, typename String>
3629using string_function_t =
3630decltype(std::declval<T&>().string(std::declval<String&>()));
3631
3632template <typename T>
3633using start_object_function_t =
3634decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3635
3636template <typename T, typename String>
3637using key_function_t =
3638decltype(std::declval<T&>().key(std::declval<String&>()));
3639
3640template <typename T>
3641using end_object_function_t = decltype(std::declval<T&>().end_object());
3642
3643template <typename T>
3644using start_array_function_t =
3645decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3646
3647template <typename T>
3648using end_array_function_t = decltype(std::declval<T&>().end_array());
3649
3650template <typename T, typename Exception>
3651using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3652std::declval<std::size_t>(), std::declval<const std::string&>(),
3653std::declval<const Exception&>()));
3654
3655template <typename SAX, typename BasicJsonType>
3656struct is_sax
3657{
3658private:
3659static_assert(is_basic_json<BasicJsonType>::value,
3660"BasicJsonType must be of type basic_json<...>");
3661
3662using number_integer_t = typename BasicJsonType::number_integer_t;
3663using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3664using number_float_t = typename BasicJsonType::number_float_t;
3665using string_t = typename BasicJsonType::string_t;
3666using exception_t = typename BasicJsonType::exception;
3667
3668public:
3669static constexpr bool value =
3670is_detected_exact<bool, null_function_t, SAX>::value &&
3671is_detected_exact<bool, boolean_function_t, SAX>::value &&
3672is_detected_exact<bool, number_integer_function_t, SAX,
3673number_integer_t>::value &&
3674is_detected_exact<bool, number_unsigned_function_t, SAX,
3675number_unsigned_t>::value &&
3676is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3677string_t>::value &&
3678is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3679is_detected_exact<bool, start_object_function_t, SAX>::value &&
3680is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3681is_detected_exact<bool, end_object_function_t, SAX>::value &&
3682is_detected_exact<bool, start_array_function_t, SAX>::value &&
3683is_detected_exact<bool, end_array_function_t, SAX>::value &&
3684is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3685};
3686
3687template <typename SAX, typename BasicJsonType>
3688struct is_sax_static_asserts
3689{
3690private:
3691static_assert(is_basic_json<BasicJsonType>::value,
3692"BasicJsonType must be of type basic_json<...>");
3693
3694using number_integer_t = typename BasicJsonType::number_integer_t;
3695using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3696using number_float_t = typename BasicJsonType::number_float_t;
3697using string_t = typename BasicJsonType::string_t;
3698using exception_t = typename BasicJsonType::exception;
3699
3700public:
3701static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3702"Missing/invalid function: bool null()");
3703static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3704"Missing/invalid function: bool boolean(bool)");
3705static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3706"Missing/invalid function: bool boolean(bool)");
3707static_assert(
3708is_detected_exact<bool, number_integer_function_t, SAX,
3709number_integer_t>::value,
3710"Missing/invalid function: bool number_integer(number_integer_t)");
3711static_assert(
3712is_detected_exact<bool, number_unsigned_function_t, SAX,
3713number_unsigned_t>::value,
3714"Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3715static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3716number_float_t, string_t>::value,
3717"Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3718static_assert(
3719is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3720"Missing/invalid function: bool string(string_t&)");
3721static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3722"Missing/invalid function: bool start_object(std::size_t)");
3723static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3724"Missing/invalid function: bool key(string_t&)");
3725static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3726"Missing/invalid function: bool end_object()");
3727static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3728"Missing/invalid function: bool start_array(std::size_t)");
3729static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3730"Missing/invalid function: bool end_array()");
3731static_assert(
3732is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3733"Missing/invalid function: bool parse_error(std::size_t, const "
3734"std::string&, const exception&)");
3735};
3736}
3737}
3738
3739// #include <nlohmann/detail/input/input_adapters.hpp>
3740
3741// #include <nlohmann/detail/input/json_sax.hpp>
3742
3743
3744#include <cstddef>
3745#include <string>
3746#include <vector>
3747
3748// #include <nlohmann/detail/input/parser.hpp>
3749
3750// #include <nlohmann/detail/exceptions.hpp>
3751
3752
3753namespace nlohmann
3754{
3755
3756/*!
3757@brief SAX interface
3758
3759This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
3760Each function is called in different situations while the input is parsed. The
3761boolean return value informs the parser whether to continue processing the
3762input.
3763*/
3764template<typename BasicJsonType>
3765struct json_sax
3766{
3767/// type for (signed) integers
3768using number_integer_t = typename BasicJsonType::number_integer_t;
3769/// type for unsigned integers
3770using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3771/// type for floating-point numbers
3772using number_float_t = typename BasicJsonType::number_float_t;
3773/// type for strings
3774using string_t = typename BasicJsonType::string_t;
3775
3776/*!
3777 @brief a null value was read
3778 @return whether parsing should proceed
3779 */
3780virtual bool null() = 0;
3781
3782/*!
3783 @brief a boolean value was read
3784 @param[in] val boolean value
3785 @return whether parsing should proceed
3786 */
3787virtual bool boolean(bool val) = 0;
3788
3789/*!
3790 @brief an integer number was read
3791 @param[in] val integer value
3792 @return whether parsing should proceed
3793 */
3794virtual bool number_integer(number_integer_t val) = 0;
3795
3796/*!
3797 @brief an unsigned integer number was read
3798 @param[in] val unsigned integer value
3799 @return whether parsing should proceed
3800 */
3801virtual bool number_unsigned(number_unsigned_t val) = 0;
3802
3803/*!
3804 @brief an floating-point number was read
3805 @param[in] val floating-point value
3806 @param[in] s raw token value
3807 @return whether parsing should proceed
3808 */
3809virtual bool number_float(number_float_t val, const string_t& s) = 0;
3810
3811/*!
3812 @brief a string was read
3813 @param[in] val string value
3814 @return whether parsing should proceed
3815 @note It is safe to move the passed string.
3816 */
3817virtual bool string(string_t& val) = 0;
3818
3819/*!
3820 @brief the beginning of an object was read
3821 @param[in] elements number of object elements or -1 if unknown
3822 @return whether parsing should proceed
3823 @note binary formats may report the number of elements
3824 */
3825virtual bool start_object(std::size_t elements) = 0;
3826
3827/*!
3828 @brief an object key was read
3829 @param[in] val object key
3830 @return whether parsing should proceed
3831 @note It is safe to move the passed string.
3832 */
3833virtual bool key(string_t& val) = 0;
3834
3835/*!
3836 @brief the end of an object was read
3837 @return whether parsing should proceed
3838 */
3839virtual bool end_object() = 0;
3840
3841/*!
3842 @brief the beginning of an array was read
3843 @param[in] elements number of array elements or -1 if unknown
3844 @return whether parsing should proceed
3845 @note binary formats may report the number of elements
3846 */
3847virtual bool start_array(std::size_t elements) = 0;
3848
3849/*!
3850 @brief the end of an array was read
3851 @return whether parsing should proceed
3852 */
3853virtual bool end_array() = 0;
3854
3855/*!
3856 @brief a parse error occurred
3857 @param[in] position the position in the input where the error occurs
3858 @param[in] last_token the last read token
3859 @param[in] error_msg a detailed error message
3860 @return whether parsing should proceed (must return false)
3861 */
3862virtual bool parse_error(std::size_t position,
3863const std::string& last_token,
3864const detail::exception& ex) = 0;
3865
3866virtual ~json_sax() = default;
3867};
3868
3869
3870namespace detail
3871{
3872/*!
3873@brief SAX implementation to create a JSON value from SAX events
3874
3875This class implements the @ref json_sax interface and processes the SAX events
3876to create a JSON value which makes it basically a DOM parser. The structure or
3877hierarchy of the JSON value is managed by the stack `ref_stack` which contains
3878a pointer to the respective array or object for each recursion depth.
3879
3880After successful parsing, the value that is passed by reference to the
3881constructor contains the parsed value.
3882
3883@tparam BasicJsonType the JSON type
3884*/
3885template<typename BasicJsonType>
3886class json_sax_dom_parser
3887{
3888public:
3889using number_integer_t = typename BasicJsonType::number_integer_t;
3890using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3891using number_float_t = typename BasicJsonType::number_float_t;
3892using string_t = typename BasicJsonType::string_t;
3893
3894/*!
3895 @param[in, out] r reference to a JSON value that is manipulated while
3896 parsing
3897 @param[in] allow_exceptions_ whether parse errors yield exceptions
3898 */
3899explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
3900: root(r), allow_exceptions(allow_exceptions_)
3901{}
3902
3903bool null()
3904{
3905handle_value(nullptr);
3906return true;
3907}
3908
3909bool boolean(bool val)
3910{
3911handle_value(val);
3912return true;
3913}
3914
3915bool number_integer(number_integer_t val)
3916{
3917handle_value(val);
3918return true;
3919}
3920
3921bool number_unsigned(number_unsigned_t val)
3922{
3923handle_value(val);
3924return true;
3925}
3926
3927bool number_float(number_float_t val, const string_t&)
3928{
3929handle_value(val);
3930return true;
3931}
3932
3933bool string(string_t& val)
3934{
3935handle_value(val);
3936return true;
3937}
3938
3939bool start_object(std::size_t len)
3940{
3941ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
3942
3943if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3944{
3945JSON_THROW(out_of_range::create(408,
3946"excessive object size: " + std::to_string(len)));
3947}
3948
3949return true;
3950}
3951
3952bool key(string_t& val)
3953{
3954// add null at given key and store the reference for later
3955object_element = &(ref_stack.back()->m_value.object->operator[](val));
3956return true;
3957}
3958
3959bool end_object()
3960{
3961ref_stack.pop_back();
3962return true;
3963}
3964
3965bool start_array(std::size_t len)
3966{
3967ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
3968
3969if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3970{
3971JSON_THROW(out_of_range::create(408,
3972"excessive array size: " + std::to_string(len)));
3973}
3974
3975return true;
3976}
3977
3978bool end_array()
3979{
3980ref_stack.pop_back();
3981return true;
3982}
3983
3984bool parse_error(std::size_t, const std::string&,
3985const detail::exception& ex)
3986{
3987errored = true;
3988if (allow_exceptions)
3989{
3990// determine the proper exception type from the id
3991switch ((ex.id / 100) % 100)
3992{
3993case 1:
3994JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
3995case 4:
3996JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
3997// LCOV_EXCL_START
3998case 2:
3999JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4000case 3:
4001JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4002case 5:
4003JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4004default:
4005assert(false);
4006// LCOV_EXCL_STOP
4007}
4008}
4009return false;
4010}
4011
4012constexpr bool is_errored() const
4013{
4014return errored;
4015}
4016
4017private:
4018/*!
4019 @invariant If the ref stack is empty, then the passed value will be the new
4020 root.
4021 @invariant If the ref stack contains a value, then it is an array or an
4022 object to which we can add elements
4023 */
4024template<typename Value>
4025BasicJsonType* handle_value(Value&& v)
4026{
4027if (ref_stack.empty())
4028{
4029root = BasicJsonType(std::forward<Value>(v));
4030return &root;
4031}
4032else
4033{
4034assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4035if (ref_stack.back()->is_array())
4036{
4037ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4038return &(ref_stack.back()->m_value.array->back());
4039}
4040else
4041{
4042assert(object_element);
4043*object_element = BasicJsonType(std::forward<Value>(v));
4044return object_element;
4045}
4046}
4047}
4048
4049/// the parsed JSON value
4050BasicJsonType& root;
4051/// stack to model hierarchy of values
4052std::vector<BasicJsonType*> ref_stack;
4053/// helper to hold the reference for the next object element
4054BasicJsonType* object_element = nullptr;
4055/// whether a syntax error occurred
4056bool errored = false;
4057/// whether to throw exceptions in case of errors
4058const bool allow_exceptions = true;
4059};
4060
4061template<typename BasicJsonType>
4062class json_sax_dom_callback_parser
4063{
4064public:
4065using number_integer_t = typename BasicJsonType::number_integer_t;
4066using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4067using number_float_t = typename BasicJsonType::number_float_t;
4068using string_t = typename BasicJsonType::string_t;
4069using parser_callback_t = typename BasicJsonType::parser_callback_t;
4070using parse_event_t = typename BasicJsonType::parse_event_t;
4071
4072json_sax_dom_callback_parser(BasicJsonType& r,
4073const parser_callback_t cb,
4074const bool allow_exceptions_ = true)
4075: root(r), callback(cb), allow_exceptions(allow_exceptions_)
4076{
4077keep_stack.push_back(true);
4078}
4079
4080bool null()
4081{
4082handle_value(nullptr);
4083return true;
4084}
4085
4086bool boolean(bool val)
4087{
4088handle_value(val);
4089return true;
4090}
4091
4092bool number_integer(number_integer_t val)
4093{
4094handle_value(val);
4095return true;
4096}
4097
4098bool number_unsigned(number_unsigned_t val)
4099{
4100handle_value(val);
4101return true;
4102}
4103
4104bool number_float(number_float_t val, const string_t&)
4105{
4106handle_value(val);
4107return true;
4108}
4109
4110bool string(string_t& val)
4111{
4112handle_value(val);
4113return true;
4114}
4115
4116bool start_object(std::size_t len)
4117{
4118// check callback for object start
4119const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4120keep_stack.push_back(keep);
4121
4122auto val = handle_value(BasicJsonType::value_t::object, true);
4123ref_stack.push_back(val.second);
4124
4125// check object limit
4126if (ref_stack.back())
4127{
4128if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4129{
4130JSON_THROW(out_of_range::create(408,
4131"excessive object size: " + std::to_string(len)));
4132}
4133}
4134
4135return true;
4136}
4137
4138bool key(string_t& val)
4139{
4140BasicJsonType k = BasicJsonType(val);
4141
4142// check callback for key
4143const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4144key_keep_stack.push_back(keep);
4145
4146// add discarded value at given key and store the reference for later
4147if (keep and ref_stack.back())
4148{
4149object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4150}
4151
4152return true;
4153}
4154
4155bool end_object()
4156{
4157if (ref_stack.back())
4158{
4159if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4160{
4161// discard object
4162*ref_stack.back() = discarded;
4163}
4164}
4165
4166assert(not ref_stack.empty());
4167assert(not keep_stack.empty());
4168ref_stack.pop_back();
4169keep_stack.pop_back();
4170
4171if (not ref_stack.empty() and ref_stack.back())
4172{
4173// remove discarded value
4174if (ref_stack.back()->is_object())
4175{
4176for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4177{
4178if (it->is_discarded())
4179{
4180ref_stack.back()->erase(it);
4181break;
4182}
4183}
4184}
4185}
4186
4187return true;
4188}
4189
4190bool start_array(std::size_t len)
4191{
4192const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4193keep_stack.push_back(keep);
4194
4195auto val = handle_value(BasicJsonType::value_t::array, true);
4196ref_stack.push_back(val.second);
4197
4198// check array limit
4199if (ref_stack.back())
4200{
4201if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4202{
4203JSON_THROW(out_of_range::create(408,
4204"excessive array size: " + std::to_string(len)));
4205}
4206}
4207
4208return true;
4209}
4210
4211bool end_array()
4212{
4213bool keep = true;
4214
4215if (ref_stack.back())
4216{
4217keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4218if (not keep)
4219{
4220// discard array
4221*ref_stack.back() = discarded;
4222}
4223}
4224
4225assert(not ref_stack.empty());
4226assert(not keep_stack.empty());
4227ref_stack.pop_back();
4228keep_stack.pop_back();
4229
4230// remove discarded value
4231if (not keep and not ref_stack.empty())
4232{
4233if (ref_stack.back()->is_array())
4234{
4235ref_stack.back()->m_value.array->pop_back();
4236}
4237}
4238
4239return true;
4240}
4241
4242bool parse_error(std::size_t, const std::string&,
4243const detail::exception& ex)
4244{
4245errored = true;
4246if (allow_exceptions)
4247{
4248// determine the proper exception type from the id
4249switch ((ex.id / 100) % 100)
4250{
4251case 1:
4252JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4253case 4:
4254JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4255// LCOV_EXCL_START
4256case 2:
4257JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4258case 3:
4259JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4260case 5:
4261JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4262default:
4263assert(false);
4264// LCOV_EXCL_STOP
4265}
4266}
4267return false;
4268}
4269
4270constexpr bool is_errored() const
4271{
4272return errored;
4273}
4274
4275private:
4276/*!
4277 @param[in] v value to add to the JSON value we build during parsing
4278 @param[in] skip_callback whether we should skip calling the callback
4279 function; this is required after start_array() and
4280 start_object() SAX events, because otherwise we would call the
4281 callback function with an empty array or object, respectively.
4282
4283 @invariant If the ref stack is empty, then the passed value will be the new
4284 root.
4285 @invariant If the ref stack contains a value, then it is an array or an
4286 object to which we can add elements
4287
4288 @return pair of boolean (whether value should be kept) and pointer (to the
4289 passed value in the ref_stack hierarchy; nullptr if not kept)
4290 */
4291template<typename Value>
4292std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4293{
4294assert(not keep_stack.empty());
4295
4296// do not handle this value if we know it would be added to a discarded
4297// container
4298if (not keep_stack.back())
4299{
4300return {false, nullptr};
4301}
4302
4303// create value
4304auto value = BasicJsonType(std::forward<Value>(v));
4305
4306// check callback
4307const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4308
4309// do not handle this value if we just learnt it shall be discarded
4310if (not keep)
4311{
4312return {false, nullptr};
4313}
4314
4315if (ref_stack.empty())
4316{
4317root = std::move(value);
4318return {true, &root};
4319}
4320else
4321{
4322// skip this value if we already decided to skip the parent
4323// (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4324if (not ref_stack.back())
4325{
4326return {false, nullptr};
4327}
4328
4329assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4330if (ref_stack.back()->is_array())
4331{
4332ref_stack.back()->m_value.array->push_back(std::move(value));
4333return {true, &(ref_stack.back()->m_value.array->back())};
4334}
4335else
4336{
4337// check if we should store an element for the current key
4338assert(not key_keep_stack.empty());
4339const bool store_element = key_keep_stack.back();
4340key_keep_stack.pop_back();
4341
4342if (not store_element)
4343{
4344return {false, nullptr};
4345}
4346
4347assert(object_element);
4348*object_element = std::move(value);
4349return {true, object_element};
4350}
4351}
4352}
4353
4354/// the parsed JSON value
4355BasicJsonType& root;
4356/// stack to model hierarchy of values
4357std::vector<BasicJsonType*> ref_stack;
4358/// stack to manage which values to keep
4359std::vector<bool> keep_stack;
4360/// stack to manage which object keys to keep
4361std::vector<bool> key_keep_stack;
4362/// helper to hold the reference for the next object element
4363BasicJsonType* object_element = nullptr;
4364/// whether a syntax error occurred
4365bool errored = false;
4366/// callback function
4367const parser_callback_t callback = nullptr;
4368/// whether to throw exceptions in case of errors
4369const bool allow_exceptions = true;
4370/// a discarded value for the callback
4371BasicJsonType discarded = BasicJsonType::value_t::discarded;
4372};
4373
4374template<typename BasicJsonType>
4375class json_sax_acceptor
4376{
4377public:
4378using number_integer_t = typename BasicJsonType::number_integer_t;
4379using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4380using number_float_t = typename BasicJsonType::number_float_t;
4381using string_t = typename BasicJsonType::string_t;
4382
4383bool null()
4384{
4385return true;
4386}
4387
4388bool boolean(bool)
4389{
4390return true;
4391}
4392
4393bool number_integer(number_integer_t)
4394{
4395return true;
4396}
4397
4398bool number_unsigned(number_unsigned_t)
4399{
4400return true;
4401}
4402
4403bool number_float(number_float_t, const string_t&)
4404{
4405return true;
4406}
4407
4408bool string(string_t&)
4409{
4410return true;
4411}
4412
4413bool start_object(std::size_t = std::size_t(-1))
4414{
4415return true;
4416}
4417
4418bool key(string_t&)
4419{
4420return true;
4421}
4422
4423bool end_object()
4424{
4425return true;
4426}
4427
4428bool start_array(std::size_t = std::size_t(-1))
4429{
4430return true;
4431}
4432
4433bool end_array()
4434{
4435return true;
4436}
4437
4438bool parse_error(std::size_t, const std::string&, const detail::exception&)
4439{
4440return false;
4441}
4442};
4443}
4444
4445}
4446
4447// #include <nlohmann/detail/input/lexer.hpp>
4448
4449// #include <nlohmann/detail/value_t.hpp>
4450
4451
4452namespace nlohmann
4453{
4454namespace detail
4455{
4456////////////
4457// parser //
4458////////////
4459
4460/*!
4461@brief syntax analysis
4462
4463This class implements a recursive decent parser.
4464*/
4465template<typename BasicJsonType>
4466class parser
4467{
4468using number_integer_t = typename BasicJsonType::number_integer_t;
4469using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4470using number_float_t = typename BasicJsonType::number_float_t;
4471using string_t = typename BasicJsonType::string_t;
4472using lexer_t = lexer<BasicJsonType>;
4473using token_type = typename lexer_t::token_type;
4474
4475public:
4476enum class parse_event_t : uint8_t
4477{
4478/// the parser read `{` and started to process a JSON object
4479object_start,
4480/// the parser read `}` and finished processing a JSON object
4481object_end,
4482/// the parser read `[` and started to process a JSON array
4483array_start,
4484/// the parser read `]` and finished processing a JSON array
4485array_end,
4486/// the parser read a key of a value in an object
4487key,
4488/// the parser finished reading a JSON value
4489value
4490};
4491
4492using parser_callback_t =
4493std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4494
4495/// a parser reading from an input adapter
4496explicit parser(detail::input_adapter_t&& adapter,
4497const parser_callback_t cb = nullptr,
4498const bool allow_exceptions_ = true)
4499: callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
4500{
4501// read first token
4502get_token();
4503}
4504
4505/*!
4506 @brief public parser interface
4507
4508 @param[in] strict whether to expect the last token to be EOF
4509 @param[in,out] result parsed JSON value
4510
4511 @throw parse_error.101 in case of an unexpected token
4512 @throw parse_error.102 if to_unicode fails or surrogate error
4513 @throw parse_error.103 if to_unicode fails
4514 */
4515void parse(const bool strict, BasicJsonType& result)
4516{
4517if (callback)
4518{
4519json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
4520sax_parse_internal(&sdp);
4521result.assert_invariant();
4522
4523// in strict mode, input must be completely read
4524if (strict and (get_token() != token_type::end_of_input))
4525{
4526sdp.parse_error(m_lexer.get_position(),
4527m_lexer.get_token_string(),
4528parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4529}
4530
4531// in case of an error, return discarded value
4532if (sdp.is_errored())
4533{
4534result = value_t::discarded;
4535return;
4536}
4537
4538// set top-level value to null if it was discarded by the callback
4539// function
4540if (result.is_discarded())
4541{
4542result = nullptr;
4543}
4544}
4545else
4546{
4547json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
4548sax_parse_internal(&sdp);
4549result.assert_invariant();
4550
4551// in strict mode, input must be completely read
4552if (strict and (get_token() != token_type::end_of_input))
4553{
4554sdp.parse_error(m_lexer.get_position(),
4555m_lexer.get_token_string(),
4556parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4557}
4558
4559// in case of an error, return discarded value
4560if (sdp.is_errored())
4561{
4562result = value_t::discarded;
4563return;
4564}
4565}
4566}
4567
4568/*!
4569 @brief public accept interface
4570
4571 @param[in] strict whether to expect the last token to be EOF
4572 @return whether the input is a proper JSON text
4573 */
4574bool accept(const bool strict = true)
4575{
4576json_sax_acceptor<BasicJsonType> sax_acceptor;
4577return sax_parse(&sax_acceptor, strict);
4578}
4579
4580template <typename SAX>
4581bool sax_parse(SAX* sax, const bool strict = true)
4582{
4583(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
4584const bool result = sax_parse_internal(sax);
4585
4586// strict mode: next byte must be EOF
4587if (result and strict and (get_token() != token_type::end_of_input))
4588{
4589return sax->parse_error(m_lexer.get_position(),
4590m_lexer.get_token_string(),
4591parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input)));
4592}
4593
4594return result;
4595}
4596
4597private:
4598template <typename SAX>
4599bool sax_parse_internal(SAX* sax)
4600{
4601// stack to remember the hieararchy of structured values we are parsing
4602// true = array; false = object
4603std::vector<bool> states;
4604// value to avoid a goto (see comment where set to true)
4605bool skip_to_state_evaluation = false;
4606
4607while (true)
4608{
4609if (not skip_to_state_evaluation)
4610{
4611// invariant: get_token() was called before each iteration
4612switch (last_token)
4613{
4614case token_type::begin_object:
4615{
4616if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
4617{
4618return false;
4619}
4620
4621// closing } -> we are done
4622if (get_token() == token_type::end_object)
4623{
4624if (JSON_UNLIKELY(not sax->end_object()))
4625{
4626return false;
4627}
4628break;
4629}
4630
4631// parse key
4632if (JSON_UNLIKELY(last_token != token_type::value_string))
4633{
4634return sax->parse_error(m_lexer.get_position(),
4635m_lexer.get_token_string(),
4636parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4637}
4638else
4639{
4640if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4641{
4642return false;
4643}
4644}
4645
4646// parse separator (:)
4647if (JSON_UNLIKELY(get_token() != token_type::name_separator))
4648{
4649return sax->parse_error(m_lexer.get_position(),
4650m_lexer.get_token_string(),
4651parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator)));
4652}
4653
4654// remember we are now inside an object
4655states.push_back(false);
4656
4657// parse values
4658get_token();
4659continue;
4660}
4661
4662case token_type::begin_array:
4663{
4664if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
4665{
4666return false;
4667}
4668
4669// closing ] -> we are done
4670if (get_token() == token_type::end_array)
4671{
4672if (JSON_UNLIKELY(not sax->end_array()))
4673{
4674return false;
4675}
4676break;
4677}
4678
4679// remember we are now inside an array
4680states.push_back(true);
4681
4682// parse values (no need to call get_token)
4683continue;
4684}
4685
4686case token_type::value_float:
4687{
4688const auto res = m_lexer.get_number_float();
4689
4690if (JSON_UNLIKELY(not std::isfinite(res)))
4691{
4692return sax->parse_error(m_lexer.get_position(),
4693m_lexer.get_token_string(),
4694out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
4695}
4696else
4697{
4698if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
4699{
4700return false;
4701}
4702break;
4703}
4704}
4705
4706case token_type::literal_false:
4707{
4708if (JSON_UNLIKELY(not sax->boolean(false)))
4709{
4710return false;
4711}
4712break;
4713}
4714
4715case token_type::literal_null:
4716{
4717if (JSON_UNLIKELY(not sax->null()))
4718{
4719return false;
4720}
4721break;
4722}
4723
4724case token_type::literal_true:
4725{
4726if (JSON_UNLIKELY(not sax->boolean(true)))
4727{
4728return false;
4729}
4730break;
4731}
4732
4733case token_type::value_integer:
4734{
4735if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
4736{
4737return false;
4738}
4739break;
4740}
4741
4742case token_type::value_string:
4743{
4744if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
4745{
4746return false;
4747}
4748break;
4749}
4750
4751case token_type::value_unsigned:
4752{
4753if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
4754{
4755return false;
4756}
4757break;
4758}
4759
4760case token_type::parse_error:
4761{
4762// using "uninitialized" to avoid "expected" message
4763return sax->parse_error(m_lexer.get_position(),
4764m_lexer.get_token_string(),
4765parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized)));
4766}
4767
4768default: // the last token was unexpected
4769{
4770return sax->parse_error(m_lexer.get_position(),
4771m_lexer.get_token_string(),
4772parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value)));
4773}
4774}
4775}
4776else
4777{
4778skip_to_state_evaluation = false;
4779}
4780
4781// we reached this line after we successfully parsed a value
4782if (states.empty())
4783{
4784// empty stack: we reached the end of the hieararchy: done
4785return true;
4786}
4787else
4788{
4789if (states.back()) // array
4790{
4791// comma -> next value
4792if (get_token() == token_type::value_separator)
4793{
4794// parse a new value
4795get_token();
4796continue;
4797}
4798
4799// closing ]
4800if (JSON_LIKELY(last_token == token_type::end_array))
4801{
4802if (JSON_UNLIKELY(not sax->end_array()))
4803{
4804return false;
4805}
4806
4807// We are done with this array. Before we can parse a
4808// new value, we need to evaluate the new state first.
4809// By setting skip_to_state_evaluation to false, we
4810// are effectively jumping to the beginning of this if.
4811assert(not states.empty());
4812states.pop_back();
4813skip_to_state_evaluation = true;
4814continue;
4815}
4816else
4817{
4818return sax->parse_error(m_lexer.get_position(),
4819m_lexer.get_token_string(),
4820parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array)));
4821}
4822}
4823else // object
4824{
4825// comma -> next value
4826if (get_token() == token_type::value_separator)
4827{
4828// parse key
4829if (JSON_UNLIKELY(get_token() != token_type::value_string))
4830{
4831return sax->parse_error(m_lexer.get_position(),
4832m_lexer.get_token_string(),
4833parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string)));
4834}
4835else
4836{
4837if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
4838{
4839return false;
4840}
4841}
4842
4843// parse separator (:)
4844if (JSON_UNLIKELY(get_token() != token_type::name_separator))
4845{
4846return sax->parse_error(m_lexer.get_position(),
4847m_lexer.get_token_string(),
4848parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator)));
4849}
4850
4851// parse values
4852get_token();
4853continue;
4854}
4855
4856// closing }
4857if (JSON_LIKELY(last_token == token_type::end_object))
4858{
4859if (JSON_UNLIKELY(not sax->end_object()))
4860{
4861return false;
4862}
4863
4864// We are done with this object. Before we can parse a
4865// new value, we need to evaluate the new state first.
4866// By setting skip_to_state_evaluation to false, we
4867// are effectively jumping to the beginning of this if.
4868assert(not states.empty());
4869states.pop_back();
4870skip_to_state_evaluation = true;
4871continue;
4872}
4873else
4874{
4875return sax->parse_error(m_lexer.get_position(),
4876m_lexer.get_token_string(),
4877parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object)));
4878}
4879}
4880}
4881}
4882}
4883
4884/// get next token from lexer
4885token_type get_token()
4886{
4887return (last_token = m_lexer.scan());
4888}
4889
4890std::string exception_message(const token_type expected)
4891{
4892std::string error_msg = "syntax error - ";
4893if (last_token == token_type::parse_error)
4894{
4895error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
4896m_lexer.get_token_string() + "'";
4897}
4898else
4899{
4900error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
4901}
4902
4903if (expected != token_type::uninitialized)
4904{
4905error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
4906}
4907
4908return error_msg;
4909}
4910
4911private:
4912/// callback function
4913const parser_callback_t callback = nullptr;
4914/// the type of the last read token
4915token_type last_token = token_type::uninitialized;
4916/// the lexer
4917lexer_t m_lexer;
4918/// whether to throw exceptions in case of errors
4919const bool allow_exceptions = true;
4920};
4921}
4922}
4923
4924// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
4925
4926
4927#include <cstddef> // ptrdiff_t
4928#include <limits> // numeric_limits
4929
4930namespace nlohmann
4931{
4932namespace detail
4933{
4934/*
4935@brief an iterator for primitive JSON types
4936
4937This class models an iterator for primitive JSON types (boolean, number,
4938string). It's only purpose is to allow the iterator/const_iterator classes
4939to "iterate" over primitive values. Internally, the iterator is modeled by
4940a `difference_type` variable. Value begin_value (`0`) models the begin,
4941end_value (`1`) models past the end.
4942*/
4943class primitive_iterator_t
4944{
4945private:
4946using difference_type = std::ptrdiff_t;
4947static constexpr difference_type begin_value = 0;
4948static constexpr difference_type end_value = begin_value + 1;
4949
4950/// iterator as signed integer type
4951difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
4952
4953public:
4954constexpr difference_type get_value() const noexcept
4955{
4956return m_it;
4957}
4958
4959/// set iterator to a defined beginning
4960void set_begin() noexcept
4961{
4962m_it = begin_value;
4963}
4964
4965/// set iterator to a defined past the end
4966void set_end() noexcept
4967{
4968m_it = end_value;
4969}
4970
4971/// return whether the iterator can be dereferenced
4972constexpr bool is_begin() const noexcept
4973{
4974return m_it == begin_value;
4975}
4976
4977/// return whether the iterator is at end
4978constexpr bool is_end() const noexcept
4979{
4980return m_it == end_value;
4981}
4982
4983friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
4984{
4985return lhs.m_it == rhs.m_it;
4986}
4987
4988friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
4989{
4990return lhs.m_it < rhs.m_it;
4991}
4992
4993primitive_iterator_t operator+(difference_type n) noexcept
4994{
4995auto result = *this;
4996result += n;
4997return result;
4998}
4999
5000friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5001{
5002return lhs.m_it - rhs.m_it;
5003}
5004
5005primitive_iterator_t& operator++() noexcept
5006{
5007++m_it;
5008return *this;
5009}
5010
5011primitive_iterator_t const operator++(int) noexcept
5012{
5013auto result = *this;
5014++m_it;
5015return result;
5016}
5017
5018primitive_iterator_t& operator--() noexcept
5019{
5020--m_it;
5021return *this;
5022}
5023
5024primitive_iterator_t const operator--(int) noexcept
5025{
5026auto result = *this;
5027--m_it;
5028return result;
5029}
5030
5031primitive_iterator_t& operator+=(difference_type n) noexcept
5032{
5033m_it += n;
5034return *this;
5035}
5036
5037primitive_iterator_t& operator-=(difference_type n) noexcept
5038{
5039m_it -= n;
5040return *this;
5041}
5042};
5043}
5044}
5045
5046// #include <nlohmann/detail/iterators/internal_iterator.hpp>
5047
5048
5049// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5050
5051
5052namespace nlohmann
5053{
5054namespace detail
5055{
5056/*!
5057@brief an iterator value
5058
5059@note This structure could easily be a union, but MSVC currently does not allow
5060unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
5061*/
5062template<typename BasicJsonType> struct internal_iterator
5063{
5064/// iterator for JSON objects
5065typename BasicJsonType::object_t::iterator object_iterator {};
5066/// iterator for JSON arrays
5067typename BasicJsonType::array_t::iterator array_iterator {};
5068/// generic iterator for all other types
5069primitive_iterator_t primitive_iterator {};
5070};
5071}
5072}
5073
5074// #include <nlohmann/detail/iterators/iter_impl.hpp>
5075
5076
5077#include <ciso646> // not
5078#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
5079#include <type_traits> // conditional, is_const, remove_const
5080
5081// #include <nlohmann/detail/exceptions.hpp>
5082
5083// #include <nlohmann/detail/iterators/internal_iterator.hpp>
5084
5085// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5086
5087// #include <nlohmann/detail/macro_scope.hpp>
5088
5089// #include <nlohmann/detail/meta/cpp_future.hpp>
5090
5091// #include <nlohmann/detail/value_t.hpp>
5092
5093
5094namespace nlohmann
5095{
5096namespace detail
5097{
5098// forward declare, to be able to friend it later on
5099template<typename IteratorType> class iteration_proxy;
5100
5101/*!
5102@brief a template for a bidirectional iterator for the @ref basic_json class
5103
5104This class implements a both iterators (iterator and const_iterator) for the
5105@ref basic_json class.
5106
5107@note An iterator is called *initialized* when a pointer to a JSON value has
5108 been set (e.g., by a constructor or a copy assignment). If the iterator is
5109 default-constructed, it is *uninitialized* and most methods are undefined.
5110 **The library uses assertions to detect calls on uninitialized iterators.**
5111
5112@requirement The class satisfies the following concept requirements:
5113-
5114[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5115 The iterator that can be moved can be moved in both directions (i.e.
5116 incremented and decremented).
5117
5118@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
5119 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
5120*/
5121template<typename BasicJsonType>
5122class iter_impl
5123{
5124/// allow basic_json to access private members
5125friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
5126friend BasicJsonType;
5127friend iteration_proxy<iter_impl>;
5128
5129using object_t = typename BasicJsonType::object_t;
5130using array_t = typename BasicJsonType::array_t;
5131// make sure BasicJsonType is basic_json or const basic_json
5132static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
5133"iter_impl only accepts (const) basic_json");
5134
5135public:
5136
5137/// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
5138/// The C++ Standard has never required user-defined iterators to derive from std::iterator.
5139/// A user-defined iterator should provide publicly accessible typedefs named
5140/// iterator_category, value_type, difference_type, pointer, and reference.
5141/// Note that value_type is required to be non-const, even for constant iterators.
5142using iterator_category = std::bidirectional_iterator_tag;
5143
5144/// the type of the values when the iterator is dereferenced
5145using value_type = typename BasicJsonType::value_type;
5146/// a type to represent differences between iterators
5147using difference_type = typename BasicJsonType::difference_type;
5148/// defines a pointer to the type iterated over (value_type)
5149using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
5150typename BasicJsonType::const_pointer,
5151typename BasicJsonType::pointer>::type;
5152/// defines a reference to the type iterated over (value_type)
5153using reference =
5154typename std::conditional<std::is_const<BasicJsonType>::value,
5155typename BasicJsonType::const_reference,
5156typename BasicJsonType::reference>::type;
5157
5158/// default constructor
5159iter_impl() = default;
5160
5161/*!
5162 @brief constructor for a given JSON instance
5163 @param[in] object pointer to a JSON object for this iterator
5164 @pre object != nullptr
5165 @post The iterator is initialized; i.e. `m_object != nullptr`.
5166 */
5167explicit iter_impl(pointer object) noexcept : m_object(object)
5168{
5169assert(m_object != nullptr);
5170
5171switch (m_object->m_type)
5172{
5173case value_t::object:
5174{
5175m_it.object_iterator = typename object_t::iterator();
5176break;
5177}
5178
5179case value_t::array:
5180{
5181m_it.array_iterator = typename array_t::iterator();
5182break;
5183}
5184
5185default:
5186{
5187m_it.primitive_iterator = primitive_iterator_t();
5188break;
5189}
5190}
5191}
5192
5193/*!
5194 @note The conventional copy constructor and copy assignment are implicitly
5195 defined. Combined with the following converting constructor and
5196 assignment, they support: (1) copy from iterator to iterator, (2)
5197 copy from const iterator to const iterator, and (3) conversion from
5198 iterator to const iterator. However conversion from const iterator
5199 to iterator is not defined.
5200 */
5201
5202/*!
5203 @brief converting constructor
5204 @param[in] other non-const iterator to copy from
5205 @note It is not checked whether @a other is initialized.
5206 */
5207iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5208: m_object(other.m_object), m_it(other.m_it) {}
5209
5210/*!
5211 @brief converting assignment
5212 @param[in,out] other non-const iterator to copy from
5213 @return const/non-const iterator
5214 @note It is not checked whether @a other is initialized.
5215 */
5216iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5217{
5218m_object = other.m_object;
5219m_it = other.m_it;
5220return *this;
5221}
5222
5223private:
5224/*!
5225 @brief set the iterator to the first value
5226 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5227 */
5228void set_begin() noexcept
5229{
5230assert(m_object != nullptr);
5231
5232switch (m_object->m_type)
5233{
5234case value_t::object:
5235{
5236m_it.object_iterator = m_object->m_value.object->begin();
5237break;
5238}
5239
5240case value_t::array:
5241{
5242m_it.array_iterator = m_object->m_value.array->begin();
5243break;
5244}
5245
5246case value_t::null:
5247{
5248// set to end so begin()==end() is true: null is empty
5249m_it.primitive_iterator.set_end();
5250break;
5251}
5252
5253default:
5254{
5255m_it.primitive_iterator.set_begin();
5256break;
5257}
5258}
5259}
5260
5261/*!
5262 @brief set the iterator past the last value
5263 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5264 */
5265void set_end() noexcept
5266{
5267assert(m_object != nullptr);
5268
5269switch (m_object->m_type)
5270{
5271case value_t::object:
5272{
5273m_it.object_iterator = m_object->m_value.object->end();
5274break;
5275}
5276
5277case value_t::array:
5278{
5279m_it.array_iterator = m_object->m_value.array->end();
5280break;
5281}
5282
5283default:
5284{
5285m_it.primitive_iterator.set_end();
5286break;
5287}
5288}
5289}
5290
5291public:
5292/*!
5293 @brief return a reference to the value pointed to by the iterator
5294 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5295 */
5296reference operator*() const
5297{
5298assert(m_object != nullptr);
5299
5300switch (m_object->m_type)
5301{
5302case value_t::object:
5303{
5304assert(m_it.object_iterator != m_object->m_value.object->end());
5305return m_it.object_iterator->second;
5306}
5307
5308case value_t::array:
5309{
5310assert(m_it.array_iterator != m_object->m_value.array->end());
5311return *m_it.array_iterator;
5312}
5313
5314case value_t::null:
5315JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5316
5317default:
5318{
5319if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5320{
5321return *m_object;
5322}
5323
5324JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5325}
5326}
5327}
5328
5329/*!
5330 @brief dereference the iterator
5331 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5332 */
5333pointer operator->() const
5334{
5335assert(m_object != nullptr);
5336
5337switch (m_object->m_type)
5338{
5339case value_t::object:
5340{
5341assert(m_it.object_iterator != m_object->m_value.object->end());
5342return &(m_it.object_iterator->second);
5343}
5344
5345case value_t::array:
5346{
5347assert(m_it.array_iterator != m_object->m_value.array->end());
5348return &*m_it.array_iterator;
5349}
5350
5351default:
5352{
5353if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5354{
5355return m_object;
5356}
5357
5358JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5359}
5360}
5361}
5362
5363/*!
5364 @brief post-increment (it++)
5365 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5366 */
5367iter_impl const operator++(int)
5368{
5369auto result = *this;
5370++(*this);
5371return result;
5372}
5373
5374/*!
5375 @brief pre-increment (++it)
5376 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5377 */
5378iter_impl& operator++()
5379{
5380assert(m_object != nullptr);
5381
5382switch (m_object->m_type)
5383{
5384case value_t::object:
5385{
5386std::advance(m_it.object_iterator, 1);
5387break;
5388}
5389
5390case value_t::array:
5391{
5392std::advance(m_it.array_iterator, 1);
5393break;
5394}
5395
5396default:
5397{
5398++m_it.primitive_iterator;
5399break;
5400}
5401}
5402
5403return *this;
5404}
5405
5406/*!
5407 @brief post-decrement (it--)
5408 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5409 */
5410iter_impl const operator--(int)
5411{
5412auto result = *this;
5413--(*this);
5414return result;
5415}
5416
5417/*!
5418 @brief pre-decrement (--it)
5419 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5420 */
5421iter_impl& operator--()
5422{
5423assert(m_object != nullptr);
5424
5425switch (m_object->m_type)
5426{
5427case value_t::object:
5428{
5429std::advance(m_it.object_iterator, -1);
5430break;
5431}
5432
5433case value_t::array:
5434{
5435std::advance(m_it.array_iterator, -1);
5436break;
5437}
5438
5439default:
5440{
5441--m_it.primitive_iterator;
5442break;
5443}
5444}
5445
5446return *this;
5447}
5448
5449/*!
5450 @brief comparison: equal
5451 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5452 */
5453bool operator==(const iter_impl& other) const
5454{
5455// if objects are not the same, the comparison is undefined
5456if (JSON_UNLIKELY(m_object != other.m_object))
5457{
5458JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5459}
5460
5461assert(m_object != nullptr);
5462
5463switch (m_object->m_type)
5464{
5465case value_t::object:
5466return (m_it.object_iterator == other.m_it.object_iterator);
5467
5468case value_t::array:
5469return (m_it.array_iterator == other.m_it.array_iterator);
5470
5471default:
5472return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5473}
5474}
5475
5476/*!
5477 @brief comparison: not equal
5478 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5479 */
5480bool operator!=(const iter_impl& other) const
5481{
5482return not operator==(other);
5483}
5484
5485/*!
5486 @brief comparison: smaller
5487 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5488 */
5489bool operator<(const iter_impl& other) const
5490{
5491// if objects are not the same, the comparison is undefined
5492if (JSON_UNLIKELY(m_object != other.m_object))
5493{
5494JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5495}
5496
5497assert(m_object != nullptr);
5498
5499switch (m_object->m_type)
5500{
5501case value_t::object:
5502JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
5503
5504case value_t::array:
5505return (m_it.array_iterator < other.m_it.array_iterator);
5506
5507default:
5508return (m_it.primitive_iterator < other.m_it.primitive_iterator);
5509}
5510}
5511
5512/*!
5513 @brief comparison: less than or equal
5514 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5515 */
5516bool operator<=(const iter_impl& other) const
5517{
5518return not other.operator < (*this);
5519}
5520
5521/*!
5522 @brief comparison: greater than
5523 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5524 */
5525bool operator>(const iter_impl& other) const
5526{
5527return not operator<=(other);
5528}
5529
5530/*!
5531 @brief comparison: greater than or equal
5532 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5533 */
5534bool operator>=(const iter_impl& other) const
5535{
5536return not operator<(other);
5537}
5538
5539/*!
5540 @brief add to iterator
5541 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5542 */
5543iter_impl& operator+=(difference_type i)
5544{
5545assert(m_object != nullptr);
5546
5547switch (m_object->m_type)
5548{
5549case value_t::object:
5550JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5551
5552case value_t::array:
5553{
5554std::advance(m_it.array_iterator, i);
5555break;
5556}
5557
5558default:
5559{
5560m_it.primitive_iterator += i;
5561break;
5562}
5563}
5564
5565return *this;
5566}
5567
5568/*!
5569 @brief subtract from iterator
5570 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5571 */
5572iter_impl& operator-=(difference_type i)
5573{
5574return operator+=(-i);
5575}
5576
5577/*!
5578 @brief add to iterator
5579 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5580 */
5581iter_impl operator+(difference_type i) const
5582{
5583auto result = *this;
5584result += i;
5585return result;
5586}
5587
5588/*!
5589 @brief addition of distance and iterator
5590 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5591 */
5592friend iter_impl operator+(difference_type i, const iter_impl& it)
5593{
5594auto result = it;
5595result += i;
5596return result;
5597}
5598
5599/*!
5600 @brief subtract from iterator
5601 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5602 */
5603iter_impl operator-(difference_type i) const
5604{
5605auto result = *this;
5606result -= i;
5607return result;
5608}
5609
5610/*!
5611 @brief return difference
5612 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5613 */
5614difference_type operator-(const iter_impl& other) const
5615{
5616assert(m_object != nullptr);
5617
5618switch (m_object->m_type)
5619{
5620case value_t::object:
5621JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5622
5623case value_t::array:
5624return m_it.array_iterator - other.m_it.array_iterator;
5625
5626default:
5627return m_it.primitive_iterator - other.m_it.primitive_iterator;
5628}
5629}
5630
5631/*!
5632 @brief access to successor
5633 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5634 */
5635reference operator[](difference_type n) const
5636{
5637assert(m_object != nullptr);
5638
5639switch (m_object->m_type)
5640{
5641case value_t::object:
5642JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
5643
5644case value_t::array:
5645return *std::next(m_it.array_iterator, n);
5646
5647case value_t::null:
5648JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5649
5650default:
5651{
5652if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
5653{
5654return *m_object;
5655}
5656
5657JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5658}
5659}
5660}
5661
5662/*!
5663 @brief return the key of an object iterator
5664 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5665 */
5666const typename object_t::key_type& key() const
5667{
5668assert(m_object != nullptr);
5669
5670if (JSON_LIKELY(m_object->is_object()))
5671{
5672return m_it.object_iterator->first;
5673}
5674
5675JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
5676}
5677
5678/*!
5679 @brief return the value of an iterator
5680 @pre The iterator is initialized; i.e. `m_object != nullptr`.
5681 */
5682reference value() const
5683{
5684return operator*();
5685}
5686
5687private:
5688/// associated JSON instance
5689pointer m_object = nullptr;
5690/// the actual iterator of the associated instance
5691internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it;
5692};
5693}
5694}
5695
5696// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5697
5698// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
5699
5700
5701#include <cstddef> // ptrdiff_t
5702#include <iterator> // reverse_iterator
5703#include <utility> // declval
5704
5705namespace nlohmann
5706{
5707namespace detail
5708{
5709//////////////////////
5710// reverse_iterator //
5711//////////////////////
5712
5713/*!
5714@brief a template for a reverse iterator class
5715
5716@tparam Base the base iterator type to reverse. Valid types are @ref
5717iterator (to create @ref reverse_iterator) and @ref const_iterator (to
5718create @ref const_reverse_iterator).
5719
5720@requirement The class satisfies the following concept requirements:
5721-
5722[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
5723 The iterator that can be moved can be moved in both directions (i.e.
5724 incremented and decremented).
5725- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
5726 It is possible to write to the pointed-to element (only if @a Base is
5727 @ref iterator).
5728
5729@since version 1.0.0
5730*/
5731template<typename Base>
5732class json_reverse_iterator : public std::reverse_iterator<Base>
5733{
5734public:
5735using difference_type = std::ptrdiff_t;
5736/// shortcut to the reverse iterator adapter
5737using base_iterator = std::reverse_iterator<Base>;
5738/// the reference type for the pointed-to element
5739using reference = typename Base::reference;
5740
5741/// create reverse iterator from iterator
5742explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
5743: base_iterator(it) {}
5744
5745/// create reverse iterator from base class
5746explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
5747
5748/// post-increment (it++)
5749json_reverse_iterator const operator++(int)
5750{
5751return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
5752}
5753
5754/// pre-increment (++it)
5755json_reverse_iterator& operator++()
5756{
5757return static_cast<json_reverse_iterator&>(base_iterator::operator++());
5758}
5759
5760/// post-decrement (it--)
5761json_reverse_iterator const operator--(int)
5762{
5763return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
5764}
5765
5766/// pre-decrement (--it)
5767json_reverse_iterator& operator--()
5768{
5769return static_cast<json_reverse_iterator&>(base_iterator::operator--());
5770}
5771
5772/// add to iterator
5773json_reverse_iterator& operator+=(difference_type i)
5774{
5775return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
5776}
5777
5778/// add to iterator
5779json_reverse_iterator operator+(difference_type i) const
5780{
5781return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
5782}
5783
5784/// subtract from iterator
5785json_reverse_iterator operator-(difference_type i) const
5786{
5787return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
5788}
5789
5790/// return difference
5791difference_type operator-(const json_reverse_iterator& other) const
5792{
5793return base_iterator(*this) - base_iterator(other);
5794}
5795
5796/// access to successor
5797reference operator[](difference_type n) const
5798{
5799return *(this->operator+(n));
5800}
5801
5802/// return the key of an object iterator
5803auto key() const -> decltype(std::declval<Base>().key())
5804{
5805auto it = --this->base();
5806return it.key();
5807}
5808
5809/// return the value of an iterator
5810reference value() const
5811{
5812auto it = --this->base();
5813return it.operator * ();
5814}
5815};
5816}
5817}
5818
5819// #include <nlohmann/detail/output/output_adapters.hpp>
5820
5821
5822#include <algorithm> // copy
5823#include <cstddef> // size_t
5824#include <ios> // streamsize
5825#include <iterator> // back_inserter
5826#include <memory> // shared_ptr, make_shared
5827#include <ostream> // basic_ostream
5828#include <string> // basic_string
5829#include <vector> // vector
5830
5831namespace nlohmann
5832{
5833namespace detail
5834{
5835/// abstract output adapter interface
5836template<typename CharType> struct output_adapter_protocol
5837{
5838virtual void write_character(CharType c) = 0;
5839virtual void write_characters(const CharType* s, std::size_t length) = 0;
5840virtual ~output_adapter_protocol() = default;
5841};
5842
5843/// a type to simplify interfaces
5844template<typename CharType>
5845using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
5846
5847/// output adapter for byte vectors
5848template<typename CharType>
5849class output_vector_adapter : public output_adapter_protocol<CharType>
5850{
5851public:
5852explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
5853
5854void write_character(CharType c) override
5855{
5856v.push_back(c);
5857}
5858
5859void write_characters(const CharType* s, std::size_t length) override
5860{
5861std::copy(s, s + length, std::back_inserter(v));
5862}
5863
5864private:
5865std::vector<CharType>& v;
5866};
5867
5868/// output adapter for output streams
5869template<typename CharType>
5870class output_stream_adapter : public output_adapter_protocol<CharType>
5871{
5872public:
5873explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
5874
5875void write_character(CharType c) override
5876{
5877stream.put(c);
5878}
5879
5880void write_characters(const CharType* s, std::size_t length) override
5881{
5882stream.write(s, static_cast<std::streamsize>(length));
5883}
5884
5885private:
5886std::basic_ostream<CharType>& stream;
5887};
5888
5889/// output adapter for basic_string
5890template<typename CharType, typename StringType = std::basic_string<CharType>>
5891class output_string_adapter : public output_adapter_protocol<CharType>
5892{
5893public:
5894explicit output_string_adapter(StringType& s) : str(s) {}
5895
5896void write_character(CharType c) override
5897{
5898str.push_back(c);
5899}
5900
5901void write_characters(const CharType* s, std::size_t length) override
5902{
5903str.append(s, length);
5904}
5905
5906private:
5907StringType& str;
5908};
5909
5910template<typename CharType, typename StringType = std::basic_string<CharType>>
5911class output_adapter
5912{
5913public:
5914output_adapter(std::vector<CharType>& vec)
5915: oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
5916
5917output_adapter(std::basic_ostream<CharType>& s)
5918: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
5919
5920output_adapter(StringType& s)
5921: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
5922
5923operator output_adapter_t<CharType>()
5924{
5925return oa;
5926}
5927
5928private:
5929output_adapter_t<CharType> oa = nullptr;
5930};
5931}
5932}
5933
5934// #include <nlohmann/detail/input/binary_reader.hpp>
5935
5936
5937#include <algorithm> // generate_n
5938#include <array> // array
5939#include <cassert> // assert
5940#include <cmath> // ldexp
5941#include <cstddef> // size_t
5942#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5943#include <cstdio> // snprintf
5944#include <cstring> // memcpy
5945#include <iterator> // back_inserter
5946#include <limits> // numeric_limits
5947#include <string> // char_traits, string
5948#include <utility> // make_pair, move
5949
5950// #include <nlohmann/detail/input/input_adapters.hpp>
5951
5952// #include <nlohmann/detail/input/json_sax.hpp>
5953
5954// #include <nlohmann/detail/exceptions.hpp>
5955
5956// #include <nlohmann/detail/macro_scope.hpp>
5957
5958// #include <nlohmann/detail/meta/is_sax.hpp>
5959
5960// #include <nlohmann/detail/value_t.hpp>
5961
5962
5963namespace nlohmann
5964{
5965namespace detail
5966{
5967///////////////////
5968// binary reader //
5969///////////////////
5970
5971/*!
5972@brief deserialization of CBOR, MessagePack, and UBJSON values
5973*/
5974template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5975class binary_reader
5976{
5977using number_integer_t = typename BasicJsonType::number_integer_t;
5978using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5979using number_float_t = typename BasicJsonType::number_float_t;
5980using string_t = typename BasicJsonType::string_t;
5981using json_sax_t = SAX;
5982
5983public:
5984/*!
5985 @brief create a binary reader
5986
5987 @param[in] adapter input adapter to read from
5988 */
5989explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
5990{
5991(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5992assert(ia);
5993}
5994
5995/*!
5996 @param[in] format the binary format to parse
5997 @param[in] sax_ a SAX event processor
5998 @param[in] strict whether to expect the input to be consumed completed
5999
6000 @return
6001 */
6002bool sax_parse(const input_format_t format,
6003json_sax_t* sax_,
6004const bool strict = true)
6005{
6006sax = sax_;
6007bool result = false;
6008
6009switch (format)
6010{
6011case input_format_t::cbor:
6012result = parse_cbor_internal();
6013break;
6014
6015case input_format_t::msgpack:
6016result = parse_msgpack_internal();
6017break;
6018
6019case input_format_t::ubjson:
6020result = parse_ubjson_internal();
6021break;
6022
6023// LCOV_EXCL_START
6024default:
6025assert(false);
6026// LCOV_EXCL_STOP
6027}
6028
6029// strict mode: next byte must be EOF
6030if (result and strict)
6031{
6032if (format == input_format_t::ubjson)
6033{
6034get_ignore_noop();
6035}
6036else
6037{
6038get();
6039}
6040
6041if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6042{
6043return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input"));
6044}
6045}
6046
6047return result;
6048}
6049
6050/*!
6051 @brief determine system byte order
6052
6053 @return true if and only if system's byte order is little endian
6054
6055 @note from http://stackoverflow.com/a/1001328/266378
6056 */
6057static constexpr bool little_endianess(int num = 1) noexcept
6058{
6059return (*reinterpret_cast<char*>(&num) == 1);
6060}
6061
6062private:
6063/*!
6064 @param[in] get_char whether a new character should be retrieved from the
6065 input (true, default) or whether the last read
6066 character should be considered instead
6067
6068 @return whether a valid CBOR value was passed to the SAX parser
6069 */
6070bool parse_cbor_internal(const bool get_char = true)
6071{
6072switch (get_char ? get() : current)
6073{
6074// EOF
6075case std::char_traits<char>::eof():
6076return unexpect_eof();
6077
6078// Integer 0x00..0x17 (0..23)
6079case 0x00:
6080case 0x01:
6081case 0x02:
6082case 0x03:
6083case 0x04:
6084case 0x05:
6085case 0x06:
6086case 0x07:
6087case 0x08:
6088case 0x09:
6089case 0x0A:
6090case 0x0B:
6091case 0x0C:
6092case 0x0D:
6093case 0x0E:
6094case 0x0F:
6095case 0x10:
6096case 0x11:
6097case 0x12:
6098case 0x13:
6099case 0x14:
6100case 0x15:
6101case 0x16:
6102case 0x17:
6103return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6104
6105case 0x18: // Unsigned integer (one-byte uint8_t follows)
6106{
6107uint8_t number;
6108return get_number(number) and sax->number_unsigned(number);
6109}
6110
6111case 0x19: // Unsigned integer (two-byte uint16_t follows)
6112{
6113uint16_t number;
6114return get_number(number) and sax->number_unsigned(number);
6115}
6116
6117case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6118{
6119uint32_t number;
6120return get_number(number) and sax->number_unsigned(number);
6121}
6122
6123case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6124{
6125uint64_t number;
6126return get_number(number) and sax->number_unsigned(number);
6127}
6128
6129// Negative integer -1-0x00..-1-0x17 (-1..-24)
6130case 0x20:
6131case 0x21:
6132case 0x22:
6133case 0x23:
6134case 0x24:
6135case 0x25:
6136case 0x26:
6137case 0x27:
6138case 0x28:
6139case 0x29:
6140case 0x2A:
6141case 0x2B:
6142case 0x2C:
6143case 0x2D:
6144case 0x2E:
6145case 0x2F:
6146case 0x30:
6147case 0x31:
6148case 0x32:
6149case 0x33:
6150case 0x34:
6151case 0x35:
6152case 0x36:
6153case 0x37:
6154return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6155
6156case 0x38: // Negative integer (one-byte uint8_t follows)
6157{
6158uint8_t number;
6159return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6160}
6161
6162case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6163{
6164uint16_t number;
6165return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6166}
6167
6168case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6169{
6170uint32_t number;
6171return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6172}
6173
6174case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6175{
6176uint64_t number;
6177return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1)
6178- static_cast<number_integer_t>(number));
6179}
6180
6181// UTF-8 string (0x00..0x17 bytes follow)
6182case 0x60:
6183case 0x61:
6184case 0x62:
6185case 0x63:
6186case 0x64:
6187case 0x65:
6188case 0x66:
6189case 0x67:
6190case 0x68:
6191case 0x69:
6192case 0x6A:
6193case 0x6B:
6194case 0x6C:
6195case 0x6D:
6196case 0x6E:
6197case 0x6F:
6198case 0x70:
6199case 0x71:
6200case 0x72:
6201case 0x73:
6202case 0x74:
6203case 0x75:
6204case 0x76:
6205case 0x77:
6206case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6207case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6208case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6209case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6210case 0x7F: // UTF-8 string (indefinite length)
6211{
6212string_t s;
6213return get_cbor_string(s) and sax->string(s);
6214}
6215
6216// array (0x00..0x17 data items follow)
6217case 0x80:
6218case 0x81:
6219case 0x82:
6220case 0x83:
6221case 0x84:
6222case 0x85:
6223case 0x86:
6224case 0x87:
6225case 0x88:
6226case 0x89:
6227case 0x8A:
6228case 0x8B:
6229case 0x8C:
6230case 0x8D:
6231case 0x8E:
6232case 0x8F:
6233case 0x90:
6234case 0x91:
6235case 0x92:
6236case 0x93:
6237case 0x94:
6238case 0x95:
6239case 0x96:
6240case 0x97:
6241return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6242
6243case 0x98: // array (one-byte uint8_t for n follows)
6244{
6245uint8_t len;
6246return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6247}
6248
6249case 0x99: // array (two-byte uint16_t for n follow)
6250{
6251uint16_t len;
6252return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6253}
6254
6255case 0x9A: // array (four-byte uint32_t for n follow)
6256{
6257uint32_t len;
6258return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6259}
6260
6261case 0x9B: // array (eight-byte uint64_t for n follow)
6262{
6263uint64_t len;
6264return get_number(len) and get_cbor_array(static_cast<std::size_t>(len));
6265}
6266
6267case 0x9F: // array (indefinite length)
6268return get_cbor_array(std::size_t(-1));
6269
6270// map (0x00..0x17 pairs of data items follow)
6271case 0xA0:
6272case 0xA1:
6273case 0xA2:
6274case 0xA3:
6275case 0xA4:
6276case 0xA5:
6277case 0xA6:
6278case 0xA7:
6279case 0xA8:
6280case 0xA9:
6281case 0xAA:
6282case 0xAB:
6283case 0xAC:
6284case 0xAD:
6285case 0xAE:
6286case 0xAF:
6287case 0xB0:
6288case 0xB1:
6289case 0xB2:
6290case 0xB3:
6291case 0xB4:
6292case 0xB5:
6293case 0xB6:
6294case 0xB7:
6295return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
6296
6297case 0xB8: // map (one-byte uint8_t for n follows)
6298{
6299uint8_t len;
6300return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6301}
6302
6303case 0xB9: // map (two-byte uint16_t for n follow)
6304{
6305uint16_t len;
6306return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6307}
6308
6309case 0xBA: // map (four-byte uint32_t for n follow)
6310{
6311uint32_t len;
6312return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6313}
6314
6315case 0xBB: // map (eight-byte uint64_t for n follow)
6316{
6317uint64_t len;
6318return get_number(len) and get_cbor_object(static_cast<std::size_t>(len));
6319}
6320
6321case 0xBF: // map (indefinite length)
6322return get_cbor_object(std::size_t(-1));
6323
6324case 0xF4: // false
6325return sax->boolean(false);
6326
6327case 0xF5: // true
6328return sax->boolean(true);
6329
6330case 0xF6: // null
6331return sax->null();
6332
6333case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6334{
6335const int byte1 = get();
6336if (JSON_UNLIKELY(not unexpect_eof()))
6337{
6338return false;
6339}
6340const int byte2 = get();
6341if (JSON_UNLIKELY(not unexpect_eof()))
6342{
6343return false;
6344}
6345
6346// code from RFC 7049, Appendix D, Figure 3:
6347// As half-precision floating-point numbers were only added
6348// to IEEE 754 in 2008, today's programming platforms often
6349// still only have limited support for them. It is very
6350// easy to include at least decoding support for them even
6351// without such support. An example of a small decoder for
6352// half-precision floating-point numbers in the C language
6353// is shown in Fig. 3.
6354const int half = (byte1 << 8) + byte2;
6355const double val = [&half]
6356{
6357const int exp = (half >> 10) & 0x1F;
6358const int mant = half & 0x3FF;
6359assert(0 <= exp and exp <= 32);
6360assert(0 <= mant and mant <= 1024);
6361switch (exp)
6362{
6363case 0:
6364return std::ldexp(mant, -24);
6365case 31:
6366return (mant == 0)
6367? std::numeric_limits<double>::infinity()
6368: std::numeric_limits<double>::quiet_NaN();
6369default:
6370return std::ldexp(mant + 1024, exp - 25);
6371}
6372}();
6373return sax->number_float((half & 0x8000) != 0
6374? static_cast<number_float_t>(-val)
6375: static_cast<number_float_t>(val), "");
6376}
6377
6378case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6379{
6380float number;
6381return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6382}
6383
6384case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6385{
6386double number;
6387return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6388}
6389
6390default: // anything else (0xFF is handled inside the other types)
6391{
6392auto last_token = get_token_string();
6393return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token));
6394}
6395}
6396}
6397
6398/*!
6399 @return whether a valid MessagePack value was passed to the SAX parser
6400 */
6401bool parse_msgpack_internal()
6402{
6403switch (get())
6404{
6405// EOF
6406case std::char_traits<char>::eof():
6407return unexpect_eof();
6408
6409// positive fixint
6410case 0x00:
6411case 0x01:
6412case 0x02:
6413case 0x03:
6414case 0x04:
6415case 0x05:
6416case 0x06:
6417case 0x07:
6418case 0x08:
6419case 0x09:
6420case 0x0A:
6421case 0x0B:
6422case 0x0C:
6423case 0x0D:
6424case 0x0E:
6425case 0x0F:
6426case 0x10:
6427case 0x11:
6428case 0x12:
6429case 0x13:
6430case 0x14:
6431case 0x15:
6432case 0x16:
6433case 0x17:
6434case 0x18:
6435case 0x19:
6436case 0x1A:
6437case 0x1B:
6438case 0x1C:
6439case 0x1D:
6440case 0x1E:
6441case 0x1F:
6442case 0x20:
6443case 0x21:
6444case 0x22:
6445case 0x23:
6446case 0x24:
6447case 0x25:
6448case 0x26:
6449case 0x27:
6450case 0x28:
6451case 0x29:
6452case 0x2A:
6453case 0x2B:
6454case 0x2C:
6455case 0x2D:
6456case 0x2E:
6457case 0x2F:
6458case 0x30:
6459case 0x31:
6460case 0x32:
6461case 0x33:
6462case 0x34:
6463case 0x35:
6464case 0x36:
6465case 0x37:
6466case 0x38:
6467case 0x39:
6468case 0x3A:
6469case 0x3B:
6470case 0x3C:
6471case 0x3D:
6472case 0x3E:
6473case 0x3F:
6474case 0x40:
6475case 0x41:
6476case 0x42:
6477case 0x43:
6478case 0x44:
6479case 0x45:
6480case 0x46:
6481case 0x47:
6482case 0x48:
6483case 0x49:
6484case 0x4A:
6485case 0x4B:
6486case 0x4C:
6487case 0x4D:
6488case 0x4E:
6489case 0x4F:
6490case 0x50:
6491case 0x51:
6492case 0x52:
6493case 0x53:
6494case 0x54:
6495case 0x55:
6496case 0x56:
6497case 0x57:
6498case 0x58:
6499case 0x59:
6500case 0x5A:
6501case 0x5B:
6502case 0x5C:
6503case 0x5D:
6504case 0x5E:
6505case 0x5F:
6506case 0x60:
6507case 0x61:
6508case 0x62:
6509case 0x63:
6510case 0x64:
6511case 0x65:
6512case 0x66:
6513case 0x67:
6514case 0x68:
6515case 0x69:
6516case 0x6A:
6517case 0x6B:
6518case 0x6C:
6519case 0x6D:
6520case 0x6E:
6521case 0x6F:
6522case 0x70:
6523case 0x71:
6524case 0x72:
6525case 0x73:
6526case 0x74:
6527case 0x75:
6528case 0x76:
6529case 0x77:
6530case 0x78:
6531case 0x79:
6532case 0x7A:
6533case 0x7B:
6534case 0x7C:
6535case 0x7D:
6536case 0x7E:
6537case 0x7F:
6538return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6539
6540// fixmap
6541case 0x80:
6542case 0x81:
6543case 0x82:
6544case 0x83:
6545case 0x84:
6546case 0x85:
6547case 0x86:
6548case 0x87:
6549case 0x88:
6550case 0x89:
6551case 0x8A:
6552case 0x8B:
6553case 0x8C:
6554case 0x8D:
6555case 0x8E:
6556case 0x8F:
6557return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
6558
6559// fixarray
6560case 0x90:
6561case 0x91:
6562case 0x92:
6563case 0x93:
6564case 0x94:
6565case 0x95:
6566case 0x96:
6567case 0x97:
6568case 0x98:
6569case 0x99:
6570case 0x9A:
6571case 0x9B:
6572case 0x9C:
6573case 0x9D:
6574case 0x9E:
6575case 0x9F:
6576return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
6577
6578// fixstr
6579case 0xA0:
6580case 0xA1:
6581case 0xA2:
6582case 0xA3:
6583case 0xA4:
6584case 0xA5:
6585case 0xA6:
6586case 0xA7:
6587case 0xA8:
6588case 0xA9:
6589case 0xAA:
6590case 0xAB:
6591case 0xAC:
6592case 0xAD:
6593case 0xAE:
6594case 0xAF:
6595case 0xB0:
6596case 0xB1:
6597case 0xB2:
6598case 0xB3:
6599case 0xB4:
6600case 0xB5:
6601case 0xB6:
6602case 0xB7:
6603case 0xB8:
6604case 0xB9:
6605case 0xBA:
6606case 0xBB:
6607case 0xBC:
6608case 0xBD:
6609case 0xBE:
6610case 0xBF:
6611{
6612string_t s;
6613return get_msgpack_string(s) and sax->string(s);
6614}
6615
6616case 0xC0: // nil
6617return sax->null();
6618
6619case 0xC2: // false
6620return sax->boolean(false);
6621
6622case 0xC3: // true
6623return sax->boolean(true);
6624
6625case 0xCA: // float 32
6626{
6627float number;
6628return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6629}
6630
6631case 0xCB: // float 64
6632{
6633double number;
6634return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
6635}
6636
6637case 0xCC: // uint 8
6638{
6639uint8_t number;
6640return get_number(number) and sax->number_unsigned(number);
6641}
6642
6643case 0xCD: // uint 16
6644{
6645uint16_t number;
6646return get_number(number) and sax->number_unsigned(number);
6647}
6648
6649case 0xCE: // uint 32
6650{
6651uint32_t number;
6652return get_number(number) and sax->number_unsigned(number);
6653}
6654
6655case 0xCF: // uint 64
6656{
6657uint64_t number;
6658return get_number(number) and sax->number_unsigned(number);
6659}
6660
6661case 0xD0: // int 8
6662{
6663int8_t number;
6664return get_number(number) and sax->number_integer(number);
6665}
6666
6667case 0xD1: // int 16
6668{
6669int16_t number;
6670return get_number(number) and sax->number_integer(number);
6671}
6672
6673case 0xD2: // int 32
6674{
6675int32_t number;
6676return get_number(number) and sax->number_integer(number);
6677}
6678
6679case 0xD3: // int 64
6680{
6681int64_t number;
6682return get_number(number) and sax->number_integer(number);
6683}
6684
6685case 0xD9: // str 8
6686case 0xDA: // str 16
6687case 0xDB: // str 32
6688{
6689string_t s;
6690return get_msgpack_string(s) and sax->string(s);
6691}
6692
6693case 0xDC: // array 16
6694{
6695uint16_t len;
6696return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6697}
6698
6699case 0xDD: // array 32
6700{
6701uint32_t len;
6702return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len));
6703}
6704
6705case 0xDE: // map 16
6706{
6707uint16_t len;
6708return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6709}
6710
6711case 0xDF: // map 32
6712{
6713uint32_t len;
6714return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len));
6715}
6716
6717// negative fixint
6718case 0xE0:
6719case 0xE1:
6720case 0xE2:
6721case 0xE3:
6722case 0xE4:
6723case 0xE5:
6724case 0xE6:
6725case 0xE7:
6726case 0xE8:
6727case 0xE9:
6728case 0xEA:
6729case 0xEB:
6730case 0xEC:
6731case 0xED:
6732case 0xEE:
6733case 0xEF:
6734case 0xF0:
6735case 0xF1:
6736case 0xF2:
6737case 0xF3:
6738case 0xF4:
6739case 0xF5:
6740case 0xF6:
6741case 0xF7:
6742case 0xF8:
6743case 0xF9:
6744case 0xFA:
6745case 0xFB:
6746case 0xFC:
6747case 0xFD:
6748case 0xFE:
6749case 0xFF:
6750return sax->number_integer(static_cast<int8_t>(current));
6751
6752default: // anything else
6753{
6754auto last_token = get_token_string();
6755return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token));
6756}
6757}
6758}
6759
6760/*!
6761 @param[in] get_char whether a new character should be retrieved from the
6762 input (true, default) or whether the last read
6763 character should be considered instead
6764
6765 @return whether a valid UBJSON value was passed to the SAX parser
6766 */
6767bool parse_ubjson_internal(const bool get_char = true)
6768{
6769return get_ubjson_value(get_char ? get_ignore_noop() : current);
6770}
6771
6772/*!
6773 @brief get next character from the input
6774
6775 This function provides the interface to the used input adapter. It does
6776 not throw in case the input reached EOF, but returns a -'ve valued
6777 `std::char_traits<char>::eof()` in that case.
6778
6779 @return character read from the input
6780 */
6781int get()
6782{
6783++chars_read;
6784return (current = ia->get_character());
6785}
6786
6787/*!
6788 @return character read from the input after ignoring all 'N' entries
6789 */
6790int get_ignore_noop()
6791{
6792do
6793{
6794get();
6795}
6796while (current == 'N');
6797
6798return current;
6799}
6800
6801/*
6802 @brief read a number from the input
6803
6804 @tparam NumberType the type of the number
6805 @param[out] result number of type @a NumberType
6806
6807 @return whether conversion completed
6808
6809 @note This function needs to respect the system's endianess, because
6810 bytes in CBOR, MessagePack, and UBJSON are stored in network order
6811 (big endian) and therefore need reordering on little endian systems.
6812 */
6813template<typename NumberType>
6814bool get_number(NumberType& result)
6815{
6816// step 1: read input into array with system's byte order
6817std::array<uint8_t, sizeof(NumberType)> vec;
6818for (std::size_t i = 0; i < sizeof(NumberType); ++i)
6819{
6820get();
6821if (JSON_UNLIKELY(not unexpect_eof()))
6822{
6823return false;
6824}
6825
6826// reverse byte order prior to conversion if necessary
6827if (is_little_endian)
6828{
6829vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
6830}
6831else
6832{
6833vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
6834}
6835}
6836
6837// step 2: convert array into number of type T and return
6838std::memcpy(&result, vec.data(), sizeof(NumberType));
6839return true;
6840}
6841
6842/*!
6843 @brief create a string by reading characters from the input
6844
6845 @tparam NumberType the type of the number
6846 @param[in] len number of characters to read
6847 @param[out] string created by reading @a len bytes
6848
6849 @return whether string creation completed
6850
6851 @note We can not reserve @a len bytes for the result, because @a len
6852 may be too large. Usually, @ref unexpect_eof() detects the end of
6853 the input before we run out of string memory.
6854 */
6855template<typename NumberType>
6856bool get_string(const NumberType len, string_t& result)
6857{
6858bool success = true;
6859std::generate_n(std::back_inserter(result), len, [this, &success]()
6860{
6861get();
6862if (JSON_UNLIKELY(not unexpect_eof()))
6863{
6864success = false;
6865}
6866return static_cast<char>(current);
6867});
6868return success;
6869}
6870
6871/*!
6872 @brief reads a CBOR string
6873
6874 This function first reads starting bytes to determine the expected
6875 string length and then copies this number of bytes into a string.
6876 Additionally, CBOR's strings with indefinite lengths are supported.
6877
6878 @param[out] result created string
6879
6880 @return whether string creation completed
6881 */
6882bool get_cbor_string(string_t& result)
6883{
6884if (JSON_UNLIKELY(not unexpect_eof()))
6885{
6886return false;
6887}
6888
6889switch (current)
6890{
6891// UTF-8 string (0x00..0x17 bytes follow)
6892case 0x60:
6893case 0x61:
6894case 0x62:
6895case 0x63:
6896case 0x64:
6897case 0x65:
6898case 0x66:
6899case 0x67:
6900case 0x68:
6901case 0x69:
6902case 0x6A:
6903case 0x6B:
6904case 0x6C:
6905case 0x6D:
6906case 0x6E:
6907case 0x6F:
6908case 0x70:
6909case 0x71:
6910case 0x72:
6911case 0x73:
6912case 0x74:
6913case 0x75:
6914case 0x76:
6915case 0x77:
6916{
6917return get_string(current & 0x1F, result);
6918}
6919
6920case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6921{
6922uint8_t len;
6923return get_number(len) and get_string(len, result);
6924}
6925
6926case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6927{
6928uint16_t len;
6929return get_number(len) and get_string(len, result);
6930}
6931
6932case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6933{
6934uint32_t len;
6935return get_number(len) and get_string(len, result);
6936}
6937
6938case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6939{
6940uint64_t len;
6941return get_number(len) and get_string(len, result);
6942}
6943
6944case 0x7F: // UTF-8 string (indefinite length)
6945{
6946while (get() != 0xFF)
6947{
6948string_t chunk;
6949if (not get_cbor_string(chunk))
6950{
6951return false;
6952}
6953result.append(chunk);
6954}
6955return true;
6956}
6957
6958default:
6959{
6960auto last_token = get_token_string();
6961return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token));
6962}
6963}
6964}
6965
6966/*!
6967 @param[in] len the length of the array or std::size_t(-1) for an
6968 array of indefinite size
6969 @return whether array creation completed
6970 */
6971bool get_cbor_array(const std::size_t len)
6972{
6973if (JSON_UNLIKELY(not sax->start_array(len)))
6974{
6975return false;
6976}
6977
6978if (len != std::size_t(-1))
6979for (std::size_t i = 0; i < len; ++i)
6980{
6981if (JSON_UNLIKELY(not parse_cbor_internal()))
6982{
6983return false;
6984}
6985}
6986else
6987{
6988while (get() != 0xFF)
6989{
6990if (JSON_UNLIKELY(not parse_cbor_internal(false)))
6991{
6992return false;
6993}
6994}
6995}
6996
6997return sax->end_array();
6998}
6999
7000/*!
7001 @param[in] len the length of the object or std::size_t(-1) for an
7002 object of indefinite size
7003 @return whether object creation completed
7004 */
7005bool get_cbor_object(const std::size_t len)
7006{
7007if (not JSON_UNLIKELY(sax->start_object(len)))
7008{
7009return false;
7010}
7011
7012string_t key;
7013if (len != std::size_t(-1))
7014{
7015for (std::size_t i = 0; i < len; ++i)
7016{
7017get();
7018if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7019{
7020return false;
7021}
7022
7023if (JSON_UNLIKELY(not parse_cbor_internal()))
7024{
7025return false;
7026}
7027key.clear();
7028}
7029}
7030else
7031{
7032while (get() != 0xFF)
7033{
7034if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7035{
7036return false;
7037}
7038
7039if (JSON_UNLIKELY(not parse_cbor_internal()))
7040{
7041return false;
7042}
7043key.clear();
7044}
7045}
7046
7047return sax->end_object();
7048}
7049
7050/*!
7051 @brief reads a MessagePack string
7052
7053 This function first reads starting bytes to determine the expected
7054 string length and then copies this number of bytes into a string.
7055
7056 @param[out] result created string
7057
7058 @return whether string creation completed
7059 */
7060bool get_msgpack_string(string_t& result)
7061{
7062if (JSON_UNLIKELY(not unexpect_eof()))
7063{
7064return false;
7065}
7066
7067switch (current)
7068{
7069// fixstr
7070case 0xA0:
7071case 0xA1:
7072case 0xA2:
7073case 0xA3:
7074case 0xA4:
7075case 0xA5:
7076case 0xA6:
7077case 0xA7:
7078case 0xA8:
7079case 0xA9:
7080case 0xAA:
7081case 0xAB:
7082case 0xAC:
7083case 0xAD:
7084case 0xAE:
7085case 0xAF:
7086case 0xB0:
7087case 0xB1:
7088case 0xB2:
7089case 0xB3:
7090case 0xB4:
7091case 0xB5:
7092case 0xB6:
7093case 0xB7:
7094case 0xB8:
7095case 0xB9:
7096case 0xBA:
7097case 0xBB:
7098case 0xBC:
7099case 0xBD:
7100case 0xBE:
7101case 0xBF:
7102{
7103return get_string(current & 0x1F, result);
7104}
7105
7106case 0xD9: // str 8
7107{
7108uint8_t len;
7109return get_number(len) and get_string(len, result);
7110}
7111
7112case 0xDA: // str 16
7113{
7114uint16_t len;
7115return get_number(len) and get_string(len, result);
7116}
7117
7118case 0xDB: // str 32
7119{
7120uint32_t len;
7121return get_number(len) and get_string(len, result);
7122}
7123
7124default:
7125{
7126auto last_token = get_token_string();
7127return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token));
7128}
7129}
7130}
7131
7132/*!
7133 @param[in] len the length of the array
7134 @return whether array creation completed
7135 */
7136bool get_msgpack_array(const std::size_t len)
7137{
7138if (JSON_UNLIKELY(not sax->start_array(len)))
7139{
7140return false;
7141}
7142
7143for (std::size_t i = 0; i < len; ++i)
7144{
7145if (JSON_UNLIKELY(not parse_msgpack_internal()))
7146{
7147return false;
7148}
7149}
7150
7151return sax->end_array();
7152}
7153
7154/*!
7155 @param[in] len the length of the object
7156 @return whether object creation completed
7157 */
7158bool get_msgpack_object(const std::size_t len)
7159{
7160if (JSON_UNLIKELY(not sax->start_object(len)))
7161{
7162return false;
7163}
7164
7165string_t key;
7166for (std::size_t i = 0; i < len; ++i)
7167{
7168get();
7169if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7170{
7171return false;
7172}
7173
7174if (JSON_UNLIKELY(not parse_msgpack_internal()))
7175{
7176return false;
7177}
7178key.clear();
7179}
7180
7181return sax->end_object();
7182}
7183
7184/*!
7185 @brief reads a UBJSON string
7186
7187 This function is either called after reading the 'S' byte explicitly
7188 indicating a string, or in case of an object key where the 'S' byte can be
7189 left out.
7190
7191 @param[out] result created string
7192 @param[in] get_char whether a new character should be retrieved from the
7193 input (true, default) or whether the last read
7194 character should be considered instead
7195
7196 @return whether string creation completed
7197 */
7198bool get_ubjson_string(string_t& result, const bool get_char = true)
7199{
7200if (get_char)
7201{
7202get(); // TODO: may we ignore N here?
7203}
7204
7205if (JSON_UNLIKELY(not unexpect_eof()))
7206{
7207return false;
7208}
7209
7210switch (current)
7211{
7212case 'U':
7213{
7214uint8_t len;
7215return get_number(len) and get_string(len, result);
7216}
7217
7218case 'i':
7219{
7220int8_t len;
7221return get_number(len) and get_string(len, result);
7222}
7223
7224case 'I':
7225{
7226int16_t len;
7227return get_number(len) and get_string(len, result);
7228}
7229
7230case 'l':
7231{
7232int32_t len;
7233return get_number(len) and get_string(len, result);
7234}
7235
7236case 'L':
7237{
7238int64_t len;
7239return get_number(len) and get_string(len, result);
7240}
7241
7242default:
7243auto last_token = get_token_string();
7244return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token));
7245}
7246}
7247
7248/*!
7249 @param[out] result determined size
7250 @return whether size determination completed
7251 */
7252bool get_ubjson_size_value(std::size_t& result)
7253{
7254switch (get_ignore_noop())
7255{
7256case 'U':
7257{
7258uint8_t number;
7259if (JSON_UNLIKELY(not get_number(number)))
7260{
7261return false;
7262}
7263result = static_cast<std::size_t>(number);
7264return true;
7265}
7266
7267case 'i':
7268{
7269int8_t number;
7270if (JSON_UNLIKELY(not get_number(number)))
7271{
7272return false;
7273}
7274result = static_cast<std::size_t>(number);
7275return true;
7276}
7277
7278case 'I':
7279{
7280int16_t number;
7281if (JSON_UNLIKELY(not get_number(number)))
7282{
7283return false;
7284}
7285result = static_cast<std::size_t>(number);
7286return true;
7287}
7288
7289case 'l':
7290{
7291int32_t number;
7292if (JSON_UNLIKELY(not get_number(number)))
7293{
7294return false;
7295}
7296result = static_cast<std::size_t>(number);
7297return true;
7298}
7299
7300case 'L':
7301{
7302int64_t number;
7303if (JSON_UNLIKELY(not get_number(number)))
7304{
7305return false;
7306}
7307result = static_cast<std::size_t>(number);
7308return true;
7309}
7310
7311default:
7312{
7313auto last_token = get_token_string();
7314return 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));
7315}
7316}
7317}
7318
7319/*!
7320 @brief determine the type and size for a container
7321
7322 In the optimized UBJSON format, a type and a size can be provided to allow
7323 for a more compact representation.
7324
7325 @param[out] result pair of the size and the type
7326
7327 @return whether pair creation completed
7328 */
7329bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7330{
7331result.first = string_t::npos; // size
7332result.second = 0; // type
7333
7334get_ignore_noop();
7335
7336if (current == '$')
7337{
7338result.second = get(); // must not ignore 'N', because 'N' maybe the type
7339if (JSON_UNLIKELY(not unexpect_eof()))
7340{
7341return false;
7342}
7343
7344get_ignore_noop();
7345if (JSON_UNLIKELY(current != '#'))
7346{
7347if (JSON_UNLIKELY(not unexpect_eof()))
7348{
7349return false;
7350}
7351auto last_token = get_token_string();
7352return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token));
7353}
7354
7355return get_ubjson_size_value(result.first);
7356}
7357else if (current == '#')
7358{
7359return get_ubjson_size_value(result.first);
7360}
7361return true;
7362}
7363
7364/*!
7365 @param prefix the previously read or set type prefix
7366 @return whether value creation completed
7367 */
7368bool get_ubjson_value(const int prefix)
7369{
7370switch (prefix)
7371{
7372case std::char_traits<char>::eof(): // EOF
7373return unexpect_eof();
7374
7375case 'T': // true
7376return sax->boolean(true);
7377case 'F': // false
7378return sax->boolean(false);
7379
7380case 'Z': // null
7381return sax->null();
7382
7383case 'U':
7384{
7385uint8_t number;
7386return get_number(number) and sax->number_unsigned(number);
7387}
7388
7389case 'i':
7390{
7391int8_t number;
7392return get_number(number) and sax->number_integer(number);
7393}
7394
7395case 'I':
7396{
7397int16_t number;
7398return get_number(number) and sax->number_integer(number);
7399}
7400
7401case 'l':
7402{
7403int32_t number;
7404return get_number(number) and sax->number_integer(number);
7405}
7406
7407case 'L':
7408{
7409int64_t number;
7410return get_number(number) and sax->number_integer(number);
7411}
7412
7413case 'd':
7414{
7415float number;
7416return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7417}
7418
7419case 'D':
7420{
7421double number;
7422return get_number(number) and sax->number_float(static_cast<number_float_t>(number), "");
7423}
7424
7425case 'C': // char
7426{
7427get();
7428if (JSON_UNLIKELY(not unexpect_eof()))
7429{
7430return false;
7431}
7432if (JSON_UNLIKELY(current > 127))
7433{
7434auto last_token = get_token_string();
7435return 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));
7436}
7437string_t s(1, static_cast<char>(current));
7438return sax->string(s);
7439}
7440
7441case 'S': // string
7442{
7443string_t s;
7444return get_ubjson_string(s) and sax->string(s);
7445}
7446
7447case '[': // array
7448return get_ubjson_array();
7449
7450case '{': // object
7451return get_ubjson_object();
7452
7453default: // anything else
7454{
7455auto last_token = get_token_string();
7456return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token));
7457}
7458}
7459}
7460
7461/*!
7462 @return whether array creation completed
7463 */
7464bool get_ubjson_array()
7465{
7466std::pair<std::size_t, int> size_and_type;
7467if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7468{
7469return false;
7470}
7471
7472if (size_and_type.first != string_t::npos)
7473{
7474if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
7475{
7476return false;
7477}
7478
7479if (size_and_type.second != 0)
7480{
7481if (size_and_type.second != 'N')
7482{
7483for (std::size_t i = 0; i < size_and_type.first; ++i)
7484{
7485if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7486{
7487return false;
7488}
7489}
7490}
7491}
7492else
7493{
7494for (std::size_t i = 0; i < size_and_type.first; ++i)
7495{
7496if (JSON_UNLIKELY(not parse_ubjson_internal()))
7497{
7498return false;
7499}
7500}
7501}
7502}
7503else
7504{
7505if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7506{
7507return false;
7508}
7509
7510while (current != ']')
7511{
7512if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
7513{
7514return false;
7515}
7516get_ignore_noop();
7517}
7518}
7519
7520return sax->end_array();
7521}
7522
7523/*!
7524 @return whether object creation completed
7525 */
7526bool get_ubjson_object()
7527{
7528std::pair<std::size_t, int> size_and_type;
7529if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7530{
7531return false;
7532}
7533
7534string_t key;
7535if (size_and_type.first != string_t::npos)
7536{
7537if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
7538{
7539return false;
7540}
7541
7542if (size_and_type.second != 0)
7543{
7544for (std::size_t i = 0; i < size_and_type.first; ++i)
7545{
7546if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7547{
7548return false;
7549}
7550if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7551{
7552return false;
7553}
7554key.clear();
7555}
7556}
7557else
7558{
7559for (std::size_t i = 0; i < size_and_type.first; ++i)
7560{
7561if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7562{
7563return false;
7564}
7565if (JSON_UNLIKELY(not parse_ubjson_internal()))
7566{
7567return false;
7568}
7569key.clear();
7570}
7571}
7572}
7573else
7574{
7575if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7576{
7577return false;
7578}
7579
7580while (current != '}')
7581{
7582if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7583{
7584return false;
7585}
7586if (JSON_UNLIKELY(not parse_ubjson_internal()))
7587{
7588return false;
7589}
7590get_ignore_noop();
7591key.clear();
7592}
7593}
7594
7595return sax->end_object();
7596}
7597
7598/*!
7599 @return whether the last read character is not EOF
7600 */
7601bool unexpect_eof() const
7602{
7603if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
7604{
7605return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input"));
7606}
7607return true;
7608}
7609
7610/*!
7611 @return a string representation of the last read byte
7612 */
7613std::string get_token_string() const
7614{
7615char cr[3];
7616snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
7617return std::string{cr};
7618}
7619
7620private:
7621/// input adapter
7622input_adapter_t ia = nullptr;
7623
7624/// the current character
7625int current = std::char_traits<char>::eof();
7626
7627/// the number of characters read
7628std::size_t chars_read = 0;
7629
7630/// whether we can assume little endianess
7631const bool is_little_endian = little_endianess();
7632
7633/// the SAX parser
7634json_sax_t* sax = nullptr;
7635};
7636}
7637}
7638
7639// #include <nlohmann/detail/output/binary_writer.hpp>
7640
7641
7642#include <algorithm> // reverse
7643#include <array> // array
7644#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
7645#include <cstring> // memcpy
7646#include <limits> // numeric_limits
7647
7648// #include <nlohmann/detail/input/binary_reader.hpp>
7649
7650// #include <nlohmann/detail/output/output_adapters.hpp>
7651
7652
7653namespace nlohmann
7654{
7655namespace detail
7656{
7657///////////////////
7658// binary writer //
7659///////////////////
7660
7661/*!
7662@brief serialization to CBOR and MessagePack values
7663*/
7664template<typename BasicJsonType, typename CharType>
7665class binary_writer
7666{
7667public:
7668/*!
7669 @brief create a binary writer
7670
7671 @param[in] adapter output adapter to write to
7672 */
7673explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
7674{
7675assert(oa);
7676}
7677
7678/*!
7679 @brief[in] j JSON value to serialize
7680 */
7681void write_cbor(const BasicJsonType& j)
7682{
7683switch (j.type())
7684{
7685case value_t::null:
7686{
7687oa->write_character(static_cast<CharType>(0xF6));
7688break;
7689}
7690
7691case value_t::boolean:
7692{
7693oa->write_character(j.m_value.boolean
7694? static_cast<CharType>(0xF5)
7695: static_cast<CharType>(0xF4));
7696break;
7697}
7698
7699case value_t::number_integer:
7700{
7701if (j.m_value.number_integer >= 0)
7702{
7703// CBOR does not differentiate between positive signed
7704// integers and unsigned integers. Therefore, we used the
7705// code from the value_t::number_unsigned case here.
7706if (j.m_value.number_integer <= 0x17)
7707{
7708write_number(static_cast<uint8_t>(j.m_value.number_integer));
7709}
7710else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7711{
7712oa->write_character(static_cast<CharType>(0x18));
7713write_number(static_cast<uint8_t>(j.m_value.number_integer));
7714}
7715else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
7716{
7717oa->write_character(static_cast<CharType>(0x19));
7718write_number(static_cast<uint16_t>(j.m_value.number_integer));
7719}
7720else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
7721{
7722oa->write_character(static_cast<CharType>(0x1A));
7723write_number(static_cast<uint32_t>(j.m_value.number_integer));
7724}
7725else
7726{
7727oa->write_character(static_cast<CharType>(0x1B));
7728write_number(static_cast<uint64_t>(j.m_value.number_integer));
7729}
7730}
7731else
7732{
7733// The conversions below encode the sign in the first
7734// byte, and the value is converted to a positive number.
7735const auto positive_number = -1 - j.m_value.number_integer;
7736if (j.m_value.number_integer >= -24)
7737{
7738write_number(static_cast<uint8_t>(0x20 + positive_number));
7739}
7740else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
7741{
7742oa->write_character(static_cast<CharType>(0x38));
7743write_number(static_cast<uint8_t>(positive_number));
7744}
7745else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
7746{
7747oa->write_character(static_cast<CharType>(0x39));
7748write_number(static_cast<uint16_t>(positive_number));
7749}
7750else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
7751{
7752oa->write_character(static_cast<CharType>(0x3A));
7753write_number(static_cast<uint32_t>(positive_number));
7754}
7755else
7756{
7757oa->write_character(static_cast<CharType>(0x3B));
7758write_number(static_cast<uint64_t>(positive_number));
7759}
7760}
7761break;
7762}
7763
7764case value_t::number_unsigned:
7765{
7766if (j.m_value.number_unsigned <= 0x17)
7767{
7768write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7769}
7770else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7771{
7772oa->write_character(static_cast<CharType>(0x18));
7773write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
7774}
7775else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7776{
7777oa->write_character(static_cast<CharType>(0x19));
7778write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
7779}
7780else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7781{
7782oa->write_character(static_cast<CharType>(0x1A));
7783write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
7784}
7785else
7786{
7787oa->write_character(static_cast<CharType>(0x1B));
7788write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
7789}
7790break;
7791}
7792
7793case value_t::number_float:
7794{
7795oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
7796write_number(j.m_value.number_float);
7797break;
7798}
7799
7800case value_t::string:
7801{
7802// step 1: write control byte and the string length
7803const auto N = j.m_value.string->size();
7804if (N <= 0x17)
7805{
7806write_number(static_cast<uint8_t>(0x60 + N));
7807}
7808else if (N <= (std::numeric_limits<uint8_t>::max)())
7809{
7810oa->write_character(static_cast<CharType>(0x78));
7811write_number(static_cast<uint8_t>(N));
7812}
7813else if (N <= (std::numeric_limits<uint16_t>::max)())
7814{
7815oa->write_character(static_cast<CharType>(0x79));
7816write_number(static_cast<uint16_t>(N));
7817}
7818else if (N <= (std::numeric_limits<uint32_t>::max)())
7819{
7820oa->write_character(static_cast<CharType>(0x7A));
7821write_number(static_cast<uint32_t>(N));
7822}
7823// LCOV_EXCL_START
7824else if (N <= (std::numeric_limits<uint64_t>::max)())
7825{
7826oa->write_character(static_cast<CharType>(0x7B));
7827write_number(static_cast<uint64_t>(N));
7828}
7829// LCOV_EXCL_STOP
7830
7831// step 2: write the string
7832oa->write_characters(
7833reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
7834j.m_value.string->size());
7835break;
7836}
7837
7838case value_t::array:
7839{
7840// step 1: write control byte and the array size
7841const auto N = j.m_value.array->size();
7842if (N <= 0x17)
7843{
7844write_number(static_cast<uint8_t>(0x80 + N));
7845}
7846else if (N <= (std::numeric_limits<uint8_t>::max)())
7847{
7848oa->write_character(static_cast<CharType>(0x98));
7849write_number(static_cast<uint8_t>(N));
7850}
7851else if (N <= (std::numeric_limits<uint16_t>::max)())
7852{
7853oa->write_character(static_cast<CharType>(0x99));
7854write_number(static_cast<uint16_t>(N));
7855}
7856else if (N <= (std::numeric_limits<uint32_t>::max)())
7857{
7858oa->write_character(static_cast<CharType>(0x9A));
7859write_number(static_cast<uint32_t>(N));
7860}
7861// LCOV_EXCL_START
7862else if (N <= (std::numeric_limits<uint64_t>::max)())
7863{
7864oa->write_character(static_cast<CharType>(0x9B));
7865write_number(static_cast<uint64_t>(N));
7866}
7867// LCOV_EXCL_STOP
7868
7869// step 2: write each element
7870for (const auto& el : *j.m_value.array)
7871{
7872write_cbor(el);
7873}
7874break;
7875}
7876
7877case value_t::object:
7878{
7879// step 1: write control byte and the object size
7880const auto N = j.m_value.object->size();
7881if (N <= 0x17)
7882{
7883write_number(static_cast<uint8_t>(0xA0 + N));
7884}
7885else if (N <= (std::numeric_limits<uint8_t>::max)())
7886{
7887oa->write_character(static_cast<CharType>(0xB8));
7888write_number(static_cast<uint8_t>(N));
7889}
7890else if (N <= (std::numeric_limits<uint16_t>::max)())
7891{
7892oa->write_character(static_cast<CharType>(0xB9));
7893write_number(static_cast<uint16_t>(N));
7894}
7895else if (N <= (std::numeric_limits<uint32_t>::max)())
7896{
7897oa->write_character(static_cast<CharType>(0xBA));
7898write_number(static_cast<uint32_t>(N));
7899}
7900// LCOV_EXCL_START
7901else if (N <= (std::numeric_limits<uint64_t>::max)())
7902{
7903oa->write_character(static_cast<CharType>(0xBB));
7904write_number(static_cast<uint64_t>(N));
7905}
7906// LCOV_EXCL_STOP
7907
7908// step 2: write each element
7909for (const auto& el : *j.m_value.object)
7910{
7911write_cbor(el.first);
7912write_cbor(el.second);
7913}
7914break;
7915}
7916
7917default:
7918break;
7919}
7920}
7921
7922/*!
7923 @brief[in] j JSON value to serialize
7924 */
7925void write_msgpack(const BasicJsonType& j)
7926{
7927switch (j.type())
7928{
7929case value_t::null: // nil
7930{
7931oa->write_character(static_cast<CharType>(0xC0));
7932break;
7933}
7934
7935case value_t::boolean: // true and false
7936{
7937oa->write_character(j.m_value.boolean
7938? static_cast<CharType>(0xC3)
7939: static_cast<CharType>(0xC2));
7940break;
7941}
7942
7943case value_t::number_integer:
7944{
7945if (j.m_value.number_integer >= 0)
7946{
7947// MessagePack does not differentiate between positive
7948// signed integers and unsigned integers. Therefore, we used
7949// the code from the value_t::number_unsigned case here.
7950if (j.m_value.number_unsigned < 128)
7951{
7952// positive fixnum
7953write_number(static_cast<uint8_t>(j.m_value.number_integer));
7954}
7955else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7956{
7957// uint 8
7958oa->write_character(static_cast<CharType>(0xCC));
7959write_number(static_cast<uint8_t>(j.m_value.number_integer));
7960}
7961else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7962{
7963// uint 16
7964oa->write_character(static_cast<CharType>(0xCD));
7965write_number(static_cast<uint16_t>(j.m_value.number_integer));
7966}
7967else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7968{
7969// uint 32
7970oa->write_character(static_cast<CharType>(0xCE));
7971write_number(static_cast<uint32_t>(j.m_value.number_integer));
7972}
7973else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7974{
7975// uint 64
7976oa->write_character(static_cast<CharType>(0xCF));
7977write_number(static_cast<uint64_t>(j.m_value.number_integer));
7978}
7979}
7980else
7981{
7982if (j.m_value.number_integer >= -32)
7983{
7984// negative fixnum
7985write_number(static_cast<int8_t>(j.m_value.number_integer));
7986}
7987else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
7988j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7989{
7990// int 8
7991oa->write_character(static_cast<CharType>(0xD0));
7992write_number(static_cast<int8_t>(j.m_value.number_integer));
7993}
7994else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
7995j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7996{
7997// int 16
7998oa->write_character(static_cast<CharType>(0xD1));
7999write_number(static_cast<int16_t>(j.m_value.number_integer));
8000}
8001else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
8002j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8003{
8004// int 32
8005oa->write_character(static_cast<CharType>(0xD2));
8006write_number(static_cast<int32_t>(j.m_value.number_integer));
8007}
8008else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
8009j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
8010{
8011// int 64
8012oa->write_character(static_cast<CharType>(0xD3));
8013write_number(static_cast<int64_t>(j.m_value.number_integer));
8014}
8015}
8016break;
8017}
8018
8019case value_t::number_unsigned:
8020{
8021if (j.m_value.number_unsigned < 128)
8022{
8023// positive fixnum
8024write_number(static_cast<uint8_t>(j.m_value.number_integer));
8025}
8026else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8027{
8028// uint 8
8029oa->write_character(static_cast<CharType>(0xCC));
8030write_number(static_cast<uint8_t>(j.m_value.number_integer));
8031}
8032else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8033{
8034// uint 16
8035oa->write_character(static_cast<CharType>(0xCD));
8036write_number(static_cast<uint16_t>(j.m_value.number_integer));
8037}
8038else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8039{
8040// uint 32
8041oa->write_character(static_cast<CharType>(0xCE));
8042write_number(static_cast<uint32_t>(j.m_value.number_integer));
8043}
8044else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8045{
8046// uint 64
8047oa->write_character(static_cast<CharType>(0xCF));
8048write_number(static_cast<uint64_t>(j.m_value.number_integer));
8049}
8050break;
8051}
8052
8053case value_t::number_float:
8054{
8055oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8056write_number(j.m_value.number_float);
8057break;
8058}
8059
8060case value_t::string:
8061{
8062// step 1: write control byte and the string length
8063const auto N = j.m_value.string->size();
8064if (N <= 31)
8065{
8066// fixstr
8067write_number(static_cast<uint8_t>(0xA0 | N));
8068}
8069else if (N <= (std::numeric_limits<uint8_t>::max)())
8070{
8071// str 8
8072oa->write_character(static_cast<CharType>(0xD9));
8073write_number(static_cast<uint8_t>(N));
8074}
8075else if (N <= (std::numeric_limits<uint16_t>::max)())
8076{
8077// str 16
8078oa->write_character(static_cast<CharType>(0xDA));
8079write_number(static_cast<uint16_t>(N));
8080}
8081else if (N <= (std::numeric_limits<uint32_t>::max)())
8082{
8083// str 32
8084oa->write_character(static_cast<CharType>(0xDB));
8085write_number(static_cast<uint32_t>(N));
8086}
8087
8088// step 2: write the string
8089oa->write_characters(
8090reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8091j.m_value.string->size());
8092break;
8093}
8094
8095case value_t::array:
8096{
8097// step 1: write control byte and the array size
8098const auto N = j.m_value.array->size();
8099if (N <= 15)
8100{
8101// fixarray
8102write_number(static_cast<uint8_t>(0x90 | N));
8103}
8104else if (N <= (std::numeric_limits<uint16_t>::max)())
8105{
8106// array 16
8107oa->write_character(static_cast<CharType>(0xDC));
8108write_number(static_cast<uint16_t>(N));
8109}
8110else if (N <= (std::numeric_limits<uint32_t>::max)())
8111{
8112// array 32
8113oa->write_character(static_cast<CharType>(0xDD));
8114write_number(static_cast<uint32_t>(N));
8115}
8116
8117// step 2: write each element
8118for (const auto& el : *j.m_value.array)
8119{
8120write_msgpack(el);
8121}
8122break;
8123}
8124
8125case value_t::object:
8126{
8127// step 1: write control byte and the object size
8128const auto N = j.m_value.object->size();
8129if (N <= 15)
8130{
8131// fixmap
8132write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8133}
8134else if (N <= (std::numeric_limits<uint16_t>::max)())
8135{
8136// map 16
8137oa->write_character(static_cast<CharType>(0xDE));
8138write_number(static_cast<uint16_t>(N));
8139}
8140else if (N <= (std::numeric_limits<uint32_t>::max)())
8141{
8142// map 32
8143oa->write_character(static_cast<CharType>(0xDF));
8144write_number(static_cast<uint32_t>(N));
8145}
8146
8147// step 2: write each element
8148for (const auto& el : *j.m_value.object)
8149{
8150write_msgpack(el.first);
8151write_msgpack(el.second);
8152}
8153break;
8154}
8155
8156default:
8157break;
8158}
8159}
8160
8161/*!
8162 @param[in] j JSON value to serialize
8163 @param[in] use_count whether to use '#' prefixes (optimized format)
8164 @param[in] use_type whether to use '$' prefixes (optimized format)
8165 @param[in] add_prefix whether prefixes need to be used for this value
8166 */
8167void write_ubjson(const BasicJsonType& j, const bool use_count,
8168const bool use_type, const bool add_prefix = true)
8169{
8170switch (j.type())
8171{
8172case value_t::null:
8173{
8174if (add_prefix)
8175{
8176oa->write_character(static_cast<CharType>('Z'));
8177}
8178break;
8179}
8180
8181case value_t::boolean:
8182{
8183if (add_prefix)
8184oa->write_character(j.m_value.boolean
8185? static_cast<CharType>('T')
8186: static_cast<CharType>('F'));
8187break;
8188}
8189
8190case value_t::number_integer:
8191{
8192write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
8193break;
8194}
8195
8196case value_t::number_unsigned:
8197{
8198write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
8199break;
8200}
8201
8202case value_t::number_float:
8203{
8204write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
8205break;
8206}
8207
8208case value_t::string:
8209{
8210if (add_prefix)
8211{
8212oa->write_character(static_cast<CharType>('S'));
8213}
8214write_number_with_ubjson_prefix(j.m_value.string->size(), true);
8215oa->write_characters(
8216reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8217j.m_value.string->size());
8218break;
8219}
8220
8221case value_t::array:
8222{
8223if (add_prefix)
8224{
8225oa->write_character(static_cast<CharType>('['));
8226}
8227
8228bool prefix_required = true;
8229if (use_type and not j.m_value.array->empty())
8230{
8231assert(use_count);
8232const CharType first_prefix = ubjson_prefix(j.front());
8233const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
8234[this, first_prefix](const BasicJsonType & v)
8235{
8236return ubjson_prefix(v) == first_prefix;
8237});
8238
8239if (same_prefix)
8240{
8241prefix_required = false;
8242oa->write_character(static_cast<CharType>('$'));
8243oa->write_character(first_prefix);
8244}
8245}
8246
8247if (use_count)
8248{
8249oa->write_character(static_cast<CharType>('#'));
8250write_number_with_ubjson_prefix(j.m_value.array->size(), true);
8251}
8252
8253for (const auto& el : *j.m_value.array)
8254{
8255write_ubjson(el, use_count, use_type, prefix_required);
8256}
8257
8258if (not use_count)
8259{
8260oa->write_character(static_cast<CharType>(']'));
8261}
8262
8263break;
8264}
8265
8266case value_t::object:
8267{
8268if (add_prefix)
8269{
8270oa->write_character(static_cast<CharType>('{'));
8271}
8272
8273bool prefix_required = true;
8274if (use_type and not j.m_value.object->empty())
8275{
8276assert(use_count);
8277const CharType first_prefix = ubjson_prefix(j.front());
8278const bool same_prefix = std::all_of(j.begin(), j.end(),
8279[this, first_prefix](const BasicJsonType & v)
8280{
8281return ubjson_prefix(v) == first_prefix;
8282});
8283
8284if (same_prefix)
8285{
8286prefix_required = false;
8287oa->write_character(static_cast<CharType>('$'));
8288oa->write_character(first_prefix);
8289}
8290}
8291
8292if (use_count)
8293{
8294oa->write_character(static_cast<CharType>('#'));
8295write_number_with_ubjson_prefix(j.m_value.object->size(), true);
8296}
8297
8298for (const auto& el : *j.m_value.object)
8299{
8300write_number_with_ubjson_prefix(el.first.size(), true);
8301oa->write_characters(
8302reinterpret_cast<const CharType*>(el.first.c_str()),
8303el.first.size());
8304write_ubjson(el.second, use_count, use_type, prefix_required);
8305}
8306
8307if (not use_count)
8308{
8309oa->write_character(static_cast<CharType>('}'));
8310}
8311
8312break;
8313}
8314
8315default:
8316break;
8317}
8318}
8319
8320private:
8321/*
8322 @brief write a number to output input
8323
8324 @param[in] n number of type @a NumberType
8325 @tparam NumberType the type of the number
8326
8327 @note This function needs to respect the system's endianess, because bytes
8328 in CBOR, MessagePack, and UBJSON are stored in network order (big
8329 endian) and therefore need reordering on little endian systems.
8330 */
8331template<typename NumberType>
8332void write_number(const NumberType n)
8333{
8334// step 1: write number to array of length NumberType
8335std::array<CharType, sizeof(NumberType)> vec;
8336std::memcpy(vec.data(), &n, sizeof(NumberType));
8337
8338// step 2: write array to output (with possible reordering)
8339if (is_little_endian)
8340{
8341// reverse byte order prior to conversion if necessary
8342std::reverse(vec.begin(), vec.end());
8343}
8344
8345oa->write_characters(vec.data(), sizeof(NumberType));
8346}
8347
8348// UBJSON: write number (floating point)
8349template<typename NumberType, typename std::enable_if<
8350std::is_floating_point<NumberType>::value, int>::type = 0>
8351void write_number_with_ubjson_prefix(const NumberType n,
8352const bool add_prefix)
8353{
8354if (add_prefix)
8355{
8356oa->write_character(get_ubjson_float_prefix(n));
8357}
8358write_number(n);
8359}
8360
8361// UBJSON: write number (unsigned integer)
8362template<typename NumberType, typename std::enable_if<
8363std::is_unsigned<NumberType>::value, int>::type = 0>
8364void write_number_with_ubjson_prefix(const NumberType n,
8365const bool add_prefix)
8366{
8367if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
8368{
8369if (add_prefix)
8370{
8371oa->write_character(static_cast<CharType>('i')); // int8
8372}
8373write_number(static_cast<uint8_t>(n));
8374}
8375else if (n <= (std::numeric_limits<uint8_t>::max)())
8376{
8377if (add_prefix)
8378{
8379oa->write_character(static_cast<CharType>('U')); // uint8
8380}
8381write_number(static_cast<uint8_t>(n));
8382}
8383else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
8384{
8385if (add_prefix)
8386{
8387oa->write_character(static_cast<CharType>('I')); // int16
8388}
8389write_number(static_cast<int16_t>(n));
8390}
8391else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
8392{
8393if (add_prefix)
8394{
8395oa->write_character(static_cast<CharType>('l')); // int32
8396}
8397write_number(static_cast<int32_t>(n));
8398}
8399else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
8400{
8401if (add_prefix)
8402{
8403oa->write_character(static_cast<CharType>('L')); // int64
8404}
8405write_number(static_cast<int64_t>(n));
8406}
8407else
8408{
8409JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8410}
8411}
8412
8413// UBJSON: write number (signed integer)
8414template<typename NumberType, typename std::enable_if<
8415std::is_signed<NumberType>::value and
8416not std::is_floating_point<NumberType>::value, int>::type = 0>
8417void write_number_with_ubjson_prefix(const NumberType n,
8418const bool add_prefix)
8419{
8420if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
8421{
8422if (add_prefix)
8423{
8424oa->write_character(static_cast<CharType>('i')); // int8
8425}
8426write_number(static_cast<int8_t>(n));
8427}
8428else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
8429{
8430if (add_prefix)
8431{
8432oa->write_character(static_cast<CharType>('U')); // uint8
8433}
8434write_number(static_cast<uint8_t>(n));
8435}
8436else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
8437{
8438if (add_prefix)
8439{
8440oa->write_character(static_cast<CharType>('I')); // int16
8441}
8442write_number(static_cast<int16_t>(n));
8443}
8444else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
8445{
8446if (add_prefix)
8447{
8448oa->write_character(static_cast<CharType>('l')); // int32
8449}
8450write_number(static_cast<int32_t>(n));
8451}
8452else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
8453{
8454if (add_prefix)
8455{
8456oa->write_character(static_cast<CharType>('L')); // int64
8457}
8458write_number(static_cast<int64_t>(n));
8459}
8460// LCOV_EXCL_START
8461else
8462{
8463JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
8464}
8465// LCOV_EXCL_STOP
8466}
8467
8468/*!
8469 @brief determine the type prefix of container values
8470
8471 @note This function does not need to be 100% accurate when it comes to
8472 integer limits. In case a number exceeds the limits of int64_t,
8473 this will be detected by a later call to function
8474 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
8475 value that does not fit the previous limits.
8476 */
8477CharType ubjson_prefix(const BasicJsonType& j) const noexcept
8478{
8479switch (j.type())
8480{
8481case value_t::null:
8482return 'Z';
8483
8484case value_t::boolean:
8485return j.m_value.boolean ? 'T' : 'F';
8486
8487case value_t::number_integer:
8488{
8489if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8490{
8491return 'i';
8492}
8493else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
8494{
8495return 'U';
8496}
8497else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8498{
8499return 'I';
8500}
8501else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8502{
8503return 'l';
8504}
8505else // no check and assume int64_t (see note above)
8506{
8507return 'L';
8508}
8509}
8510
8511case value_t::number_unsigned:
8512{
8513if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
8514{
8515return 'i';
8516}
8517else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8518{
8519return 'U';
8520}
8521else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
8522{
8523return 'I';
8524}
8525else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
8526{
8527return 'l';
8528}
8529else // no check and assume int64_t (see note above)
8530{
8531return 'L';
8532}
8533}
8534
8535case value_t::number_float:
8536return get_ubjson_float_prefix(j.m_value.number_float);
8537
8538case value_t::string:
8539return 'S';
8540
8541case value_t::array:
8542return '[';
8543
8544case value_t::object:
8545return '{';
8546
8547default: // discarded values
8548return 'N';
8549}
8550}
8551
8552static constexpr CharType get_cbor_float_prefix(float)
8553{
8554return static_cast<CharType>(0xFA); // Single-Precision Float
8555}
8556
8557static constexpr CharType get_cbor_float_prefix(double)
8558{
8559return static_cast<CharType>(0xFB); // Double-Precision Float
8560}
8561
8562static constexpr CharType get_msgpack_float_prefix(float)
8563{
8564return static_cast<CharType>(0xCA); // float 32
8565}
8566
8567static constexpr CharType get_msgpack_float_prefix(double)
8568{
8569return static_cast<CharType>(0xCB); // float 64
8570}
8571
8572static constexpr CharType get_ubjson_float_prefix(float)
8573{
8574return 'd'; // float 32
8575}
8576
8577static constexpr CharType get_ubjson_float_prefix(double)
8578{
8579return 'D'; // float 64
8580}
8581
8582private:
8583/// whether we can assume little endianess
8584const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
8585
8586/// the output
8587output_adapter_t<CharType> oa = nullptr;
8588};
8589}
8590}
8591
8592// #include <nlohmann/detail/output/serializer.hpp>
8593
8594
8595#include <algorithm> // reverse, remove, fill, find, none_of
8596#include <array> // array
8597#include <cassert> // assert
8598#include <ciso646> // and, or
8599#include <clocale> // localeconv, lconv
8600#include <cmath> // labs, isfinite, isnan, signbit
8601#include <cstddef> // size_t, ptrdiff_t
8602#include <cstdint> // uint8_t
8603#include <cstdio> // snprintf
8604#include <limits> // numeric_limits
8605#include <string> // string
8606#include <type_traits> // is_same
8607
8608// #include <nlohmann/detail/exceptions.hpp>
8609
8610// #include <nlohmann/detail/conversions/to_chars.hpp>
8611
8612
8613#include <cassert> // assert
8614#include <ciso646> // or, and, not
8615#include <cmath> // signbit, isfinite
8616#include <cstdint> // intN_t, uintN_t
8617#include <cstring> // memcpy, memmove
8618
8619namespace nlohmann
8620{
8621namespace detail
8622{
8623
8624/*!
8625@brief implements the Grisu2 algorithm for binary to decimal floating-point
8626conversion.
8627
8628This implementation is a slightly modified version of the reference
8629implementation which may be obtained from
8630http://florian.loitsch.com/publications (bench.tar.gz).
8631
8632The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
8633
8634For a detailed description of the algorithm see:
8635
8636[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
8637 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
8638 Language Design and Implementation, PLDI 2010
8639[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
8640 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
8641 Design and Implementation, PLDI 1996
8642*/
8643namespace dtoa_impl
8644{
8645
8646template <typename Target, typename Source>
8647Target reinterpret_bits(const Source source)
8648{
8649static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
8650
8651Target target;
8652std::memcpy(&target, &source, sizeof(Source));
8653return target;
8654}
8655
8656struct diyfp // f * 2^e
8657{
8658static constexpr int kPrecision = 64; // = q
8659
8660uint64_t f;
8661int e;
8662
8663constexpr diyfp() noexcept : f(0), e(0) {}
8664constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
8665
8666/*!
8667 @brief returns x - y
8668 @pre x.e == y.e and x.f >= y.f
8669 */
8670static diyfp sub(const diyfp& x, const diyfp& y) noexcept
8671{
8672assert(x.e == y.e);
8673assert(x.f >= y.f);
8674
8675return diyfp(x.f - y.f, x.e);
8676}
8677
8678/*!
8679 @brief returns x * y
8680 @note The result is rounded. (Only the upper q bits are returned.)
8681 */
8682static diyfp mul(const diyfp& x, const diyfp& y) noexcept
8683{
8684static_assert(kPrecision == 64, "internal error");
8685
8686// Computes:
8687// f = round((x.f * y.f) / 2^q)
8688// e = x.e + y.e + q
8689
8690// Emulate the 64-bit * 64-bit multiplication:
8691//
8692// p = u * v
8693// = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
8694// = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
8695// = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
8696// = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
8697// = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
8698// = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
8699// = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
8700//
8701// (Since Q might be larger than 2^32 - 1)
8702//
8703// = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
8704//
8705// (Q_hi + H does not overflow a 64-bit int)
8706//
8707// = p_lo + 2^64 p_hi
8708
8709const uint64_t u_lo = x.f & 0xFFFFFFFF;
8710const uint64_t u_hi = x.f >> 32;
8711const uint64_t v_lo = y.f & 0xFFFFFFFF;
8712const uint64_t v_hi = y.f >> 32;
8713
8714const uint64_t p0 = u_lo * v_lo;
8715const uint64_t p1 = u_lo * v_hi;
8716const uint64_t p2 = u_hi * v_lo;
8717const uint64_t p3 = u_hi * v_hi;
8718
8719const uint64_t p0_hi = p0 >> 32;
8720const uint64_t p1_lo = p1 & 0xFFFFFFFF;
8721const uint64_t p1_hi = p1 >> 32;
8722const uint64_t p2_lo = p2 & 0xFFFFFFFF;
8723const uint64_t p2_hi = p2 >> 32;
8724
8725uint64_t Q = p0_hi + p1_lo + p2_lo;
8726
8727// The full product might now be computed as
8728//
8729// p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
8730// p_lo = p0_lo + (Q << 32)
8731//
8732// But in this particular case here, the full p_lo is not required.
8733// Effectively we only need to add the highest bit in p_lo to p_hi (and
8734// Q_hi + 1 does not overflow).
8735
8736Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
8737
8738const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
8739
8740return diyfp(h, x.e + y.e + 64);
8741}
8742
8743/*!
8744 @brief normalize x such that the significand is >= 2^(q-1)
8745 @pre x.f != 0
8746 */
8747static diyfp normalize(diyfp x) noexcept
8748{
8749assert(x.f != 0);
8750
8751while ((x.f >> 63) == 0)
8752{
8753x.f <<= 1;
8754x.e--;
8755}
8756
8757return x;
8758}
8759
8760/*!
8761 @brief normalize x such that the result has the exponent E
8762 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
8763 */
8764static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
8765{
8766const int delta = x.e - target_exponent;
8767
8768assert(delta >= 0);
8769assert(((x.f << delta) >> delta) == x.f);
8770
8771return diyfp(x.f << delta, target_exponent);
8772}
8773};
8774
8775struct boundaries
8776{
8777diyfp w;
8778diyfp minus;
8779diyfp plus;
8780};
8781
8782/*!
8783Compute the (normalized) diyfp representing the input number 'value' and its
8784boundaries.
8785
8786@pre value must be finite and positive
8787*/
8788template <typename FloatType>
8789boundaries compute_boundaries(FloatType value)
8790{
8791assert(std::isfinite(value));
8792assert(value > 0);
8793
8794// Convert the IEEE representation into a diyfp.
8795//
8796// If v is denormal:
8797// value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
8798// If v is normalized:
8799// value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
8800
8801static_assert(std::numeric_limits<FloatType>::is_iec559,
8802"internal error: dtoa_short requires an IEEE-754 floating-point implementation");
8803
8804constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
8805constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
8806constexpr int kMinExp = 1 - kBias;
8807constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
8808
8809using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
8810
8811const uint64_t bits = reinterpret_bits<bits_type>(value);
8812const uint64_t E = bits >> (kPrecision - 1);
8813const uint64_t F = bits & (kHiddenBit - 1);
8814
8815const bool is_denormal = (E == 0);
8816const diyfp v = is_denormal
8817? diyfp(F, kMinExp)
8818: diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
8819
8820// Compute the boundaries m- and m+ of the floating-point value
8821// v = f * 2^e.
8822//
8823// Determine v- and v+, the floating-point predecessor and successor if v,
8824// respectively.
8825//
8826// v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
8827// = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
8828//
8829// v+ = v + 2^e
8830//
8831// Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
8832// between m- and m+ round to v, regardless of how the input rounding
8833// algorithm breaks ties.
8834//
8835// ---+-------------+-------------+-------------+-------------+--- (A)
8836// v- m- v m+ v+
8837//
8838// -----------------+------+------+-------------+-------------+--- (B)
8839// v- m- v m+ v+
8840
8841const bool lower_boundary_is_closer = (F == 0 and E > 1);
8842const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
8843const diyfp m_minus = lower_boundary_is_closer
8844? diyfp(4 * v.f - 1, v.e - 2) // (B)
8845: diyfp(2 * v.f - 1, v.e - 1); // (A)
8846
8847// Determine the normalized w+ = m+.
8848const diyfp w_plus = diyfp::normalize(m_plus);
8849
8850// Determine w- = m- such that e_(w-) = e_(w+).
8851const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
8852
8853return {diyfp::normalize(v), w_minus, w_plus};
8854}
8855
8856// Given normalized diyfp w, Grisu needs to find a (normalized) cached
8857// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
8858// within a certain range [alpha, gamma] (Definition 3.2 from [1])
8859//
8860// alpha <= e = e_c + e_w + q <= gamma
8861//
8862// or
8863//
8864// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
8865// <= f_c * f_w * 2^gamma
8866//
8867// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
8868//
8869// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
8870//
8871// or
8872//
8873// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
8874//
8875// The choice of (alpha,gamma) determines the size of the table and the form of
8876// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
8877// in practice:
8878//
8879// The idea is to cut the number c * w = f * 2^e into two parts, which can be
8880// processed independently: An integral part p1, and a fractional part p2:
8881//
8882// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
8883// = (f div 2^-e) + (f mod 2^-e) * 2^e
8884// = p1 + p2 * 2^e
8885//
8886// The conversion of p1 into decimal form requires a series of divisions and
8887// modulos by (a power of) 10. These operations are faster for 32-bit than for
8888// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
8889// achieved by choosing
8890//
8891// -e >= 32 or e <= -32 := gamma
8892//
8893// In order to convert the fractional part
8894//
8895// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
8896//
8897// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
8898// d[-i] are extracted in order:
8899//
8900// (10 * p2) div 2^-e = d[-1]
8901// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
8902//
8903// The multiplication by 10 must not overflow. It is sufficient to choose
8904//
8905// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
8906//
8907// Since p2 = f mod 2^-e < 2^-e,
8908//
8909// -e <= 60 or e >= -60 := alpha
8910
8911constexpr int kAlpha = -60;
8912constexpr int kGamma = -32;
8913
8914struct cached_power // c = f * 2^e ~= 10^k
8915{
8916uint64_t f;
8917int e;
8918int k;
8919};
8920
8921/*!
8922For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
8923power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
8924satisfies (Definition 3.2 from [1])
8925
8926 alpha <= e_c + e + q <= gamma.
8927*/
8928inline cached_power get_cached_power_for_binary_exponent(int e)
8929{
8930// Now
8931//
8932// alpha <= e_c + e + q <= gamma (1)
8933// ==> f_c * 2^alpha <= c * 2^e * 2^q
8934//
8935// and since the c's are normalized, 2^(q-1) <= f_c,
8936//
8937// ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
8938// ==> 2^(alpha - e - 1) <= c
8939//
8940// If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
8941//
8942// k = ceil( log_10( 2^(alpha - e - 1) ) )
8943// = ceil( (alpha - e - 1) * log_10(2) )
8944//
8945// From the paper:
8946// "In theory the result of the procedure could be wrong since c is rounded,
8947// and the computation itself is approximated [...]. In practice, however,
8948// this simple function is sufficient."
8949//
8950// For IEEE double precision floating-point numbers converted into
8951// normalized diyfp's w = f * 2^e, with q = 64,
8952//
8953// e >= -1022 (min IEEE exponent)
8954// -52 (p - 1)
8955// -52 (p - 1, possibly normalize denormal IEEE numbers)
8956// -11 (normalize the diyfp)
8957// = -1137
8958//
8959// and
8960//
8961// e <= +1023 (max IEEE exponent)
8962// -52 (p - 1)
8963// -11 (normalize the diyfp)
8964// = 960
8965//
8966// This binary exponent range [-1137,960] results in a decimal exponent
8967// range [-307,324]. One does not need to store a cached power for each
8968// k in this range. For each such k it suffices to find a cached power
8969// such that the exponent of the product lies in [alpha,gamma].
8970// This implies that the difference of the decimal exponents of adjacent
8971// table entries must be less than or equal to
8972//
8973// floor( (gamma - alpha) * log_10(2) ) = 8.
8974//
8975// (A smaller distance gamma-alpha would require a larger table.)
8976
8977// NB:
8978// Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
8979
8980constexpr int kCachedPowersSize = 79;
8981constexpr int kCachedPowersMinDecExp = -300;
8982constexpr int kCachedPowersDecStep = 8;
8983
8984static constexpr cached_power kCachedPowers[] =
8985{
8986{ 0xAB70FE17C79AC6CA, -1060, -300 },
8987{ 0xFF77B1FCBEBCDC4F, -1034, -292 },
8988{ 0xBE5691EF416BD60C, -1007, -284 },
8989{ 0x8DD01FAD907FFC3C, -980, -276 },
8990{ 0xD3515C2831559A83, -954, -268 },
8991{ 0x9D71AC8FADA6C9B5, -927, -260 },
8992{ 0xEA9C227723EE8BCB, -901, -252 },
8993{ 0xAECC49914078536D, -874, -244 },
8994{ 0x823C12795DB6CE57, -847, -236 },
8995{ 0xC21094364DFB5637, -821, -228 },
8996{ 0x9096EA6F3848984F, -794, -220 },
8997{ 0xD77485CB25823AC7, -768, -212 },
8998{ 0xA086CFCD97BF97F4, -741, -204 },
8999{ 0xEF340A98172AACE5, -715, -196 },
9000{ 0xB23867FB2A35B28E, -688, -188 },
9001{ 0x84C8D4DFD2C63F3B, -661, -180 },
9002{ 0xC5DD44271AD3CDBA, -635, -172 },
9003{ 0x936B9FCEBB25C996, -608, -164 },
9004{ 0xDBAC6C247D62A584, -582, -156 },
9005{ 0xA3AB66580D5FDAF6, -555, -148 },
9006{ 0xF3E2F893DEC3F126, -529, -140 },
9007{ 0xB5B5ADA8AAFF80B8, -502, -132 },
9008{ 0x87625F056C7C4A8B, -475, -124 },
9009{ 0xC9BCFF6034C13053, -449, -116 },
9010{ 0x964E858C91BA2655, -422, -108 },
9011{ 0xDFF9772470297EBD, -396, -100 },
9012{ 0xA6DFBD9FB8E5B88F, -369, -92 },
9013{ 0xF8A95FCF88747D94, -343, -84 },
9014{ 0xB94470938FA89BCF, -316, -76 },
9015{ 0x8A08F0F8BF0F156B, -289, -68 },
9016{ 0xCDB02555653131B6, -263, -60 },
9017{ 0x993FE2C6D07B7FAC, -236, -52 },
9018{ 0xE45C10C42A2B3B06, -210, -44 },
9019{ 0xAA242499697392D3, -183, -36 },
9020{ 0xFD87B5F28300CA0E, -157, -28 },
9021{ 0xBCE5086492111AEB, -130, -20 },
9022{ 0x8CBCCC096F5088CC, -103, -12 },
9023{ 0xD1B71758E219652C, -77, -4 },
9024{ 0x9C40000000000000, -50, 4 },
9025{ 0xE8D4A51000000000, -24, 12 },
9026{ 0xAD78EBC5AC620000, 3, 20 },
9027{ 0x813F3978F8940984, 30, 28 },
9028{ 0xC097CE7BC90715B3, 56, 36 },
9029{ 0x8F7E32CE7BEA5C70, 83, 44 },
9030{ 0xD5D238A4ABE98068, 109, 52 },
9031{ 0x9F4F2726179A2245, 136, 60 },
9032{ 0xED63A231D4C4FB27, 162, 68 },
9033{ 0xB0DE65388CC8ADA8, 189, 76 },
9034{ 0x83C7088E1AAB65DB, 216, 84 },
9035{ 0xC45D1DF942711D9A, 242, 92 },
9036{ 0x924D692CA61BE758, 269, 100 },
9037{ 0xDA01EE641A708DEA, 295, 108 },
9038{ 0xA26DA3999AEF774A, 322, 116 },
9039{ 0xF209787BB47D6B85, 348, 124 },
9040{ 0xB454E4A179DD1877, 375, 132 },
9041{ 0x865B86925B9BC5C2, 402, 140 },
9042{ 0xC83553C5C8965D3D, 428, 148 },
9043{ 0x952AB45CFA97A0B3, 455, 156 },
9044{ 0xDE469FBD99A05FE3, 481, 164 },
9045{ 0xA59BC234DB398C25, 508, 172 },
9046{ 0xF6C69A72A3989F5C, 534, 180 },
9047{ 0xB7DCBF5354E9BECE, 561, 188 },
9048{ 0x88FCF317F22241E2, 588, 196 },
9049{ 0xCC20CE9BD35C78A5, 614, 204 },
9050{ 0x98165AF37B2153DF, 641, 212 },
9051{ 0xE2A0B5DC971F303A, 667, 220 },
9052{ 0xA8D9D1535CE3B396, 694, 228 },
9053{ 0xFB9B7CD9A4A7443C, 720, 236 },
9054{ 0xBB764C4CA7A44410, 747, 244 },
9055{ 0x8BAB8EEFB6409C1A, 774, 252 },
9056{ 0xD01FEF10A657842C, 800, 260 },
9057{ 0x9B10A4E5E9913129, 827, 268 },
9058{ 0xE7109BFBA19C0C9D, 853, 276 },
9059{ 0xAC2820D9623BF429, 880, 284 },
9060{ 0x80444B5E7AA7CF85, 907, 292 },
9061{ 0xBF21E44003ACDD2D, 933, 300 },
9062{ 0x8E679C2F5E44FF8F, 960, 308 },
9063{ 0xD433179D9C8CB841, 986, 316 },
9064{ 0x9E19DB92B4E31BA9, 1013, 324 },
9065};
9066
9067// This computation gives exactly the same results for k as
9068// k = ceil((kAlpha - e - 1) * 0.30102999566398114)
9069// for |e| <= 1500, but doesn't require floating-point operations.
9070// NB: log_10(2) ~= 78913 / 2^18
9071assert(e >= -1500);
9072assert(e <= 1500);
9073const int f = kAlpha - e - 1;
9074const int k = (f * 78913) / (1 << 18) + (f > 0);
9075
9076const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
9077assert(index >= 0);
9078assert(index < kCachedPowersSize);
9079static_cast<void>(kCachedPowersSize); // Fix warning.
9080
9081const cached_power cached = kCachedPowers[index];
9082assert(kAlpha <= cached.e + e + 64);
9083assert(kGamma >= cached.e + e + 64);
9084
9085return cached;
9086}
9087
9088/*!
9089For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
9090For n == 0, returns 1 and sets pow10 := 1.
9091*/
9092inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
9093{
9094// LCOV_EXCL_START
9095if (n >= 1000000000)
9096{
9097pow10 = 1000000000;
9098return 10;
9099}
9100// LCOV_EXCL_STOP
9101else if (n >= 100000000)
9102{
9103pow10 = 100000000;
9104return 9;
9105}
9106else if (n >= 10000000)
9107{
9108pow10 = 10000000;
9109return 8;
9110}
9111else if (n >= 1000000)
9112{
9113pow10 = 1000000;
9114return 7;
9115}
9116else if (n >= 100000)
9117{
9118pow10 = 100000;
9119return 6;
9120}
9121else if (n >= 10000)
9122{
9123pow10 = 10000;
9124return 5;
9125}
9126else if (n >= 1000)
9127{
9128pow10 = 1000;
9129return 4;
9130}
9131else if (n >= 100)
9132{
9133pow10 = 100;
9134return 3;
9135}
9136else if (n >= 10)
9137{
9138pow10 = 10;
9139return 2;
9140}
9141else
9142{
9143pow10 = 1;
9144return 1;
9145}
9146}
9147
9148inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
9149uint64_t rest, uint64_t ten_k)
9150{
9151assert(len >= 1);
9152assert(dist <= delta);
9153assert(rest <= delta);
9154assert(ten_k > 0);
9155
9156// <--------------------------- delta ---->
9157// <---- dist --------->
9158// --------------[------------------+-------------------]--------------
9159// M- w M+
9160//
9161// ten_k
9162// <------>
9163// <---- rest ---->
9164// --------------[------------------+----+--------------]--------------
9165// w V
9166// = buf * 10^k
9167//
9168// ten_k represents a unit-in-the-last-place in the decimal representation
9169// stored in buf.
9170// Decrement buf by ten_k while this takes buf closer to w.
9171
9172// The tests are written in this order to avoid overflow in unsigned
9173// integer arithmetic.
9174
9175while (rest < dist
9176and delta - rest >= ten_k
9177and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
9178{
9179assert(buf[len - 1] != '0');
9180buf[len - 1]--;
9181rest += ten_k;
9182}
9183}
9184
9185/*!
9186Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
9187M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
9188*/
9189inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
9190diyfp M_minus, diyfp w, diyfp M_plus)
9191{
9192static_assert(kAlpha >= -60, "internal error");
9193static_assert(kGamma <= -32, "internal error");
9194
9195// Generates the digits (and the exponent) of a decimal floating-point
9196// number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
9197// w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
9198//
9199// <--------------------------- delta ---->
9200// <---- dist --------->
9201// --------------[------------------+-------------------]--------------
9202// M- w M+
9203//
9204// Grisu2 generates the digits of M+ from left to right and stops as soon as
9205// V is in [M-,M+].
9206
9207assert(M_plus.e >= kAlpha);
9208assert(M_plus.e <= kGamma);
9209
9210uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
9211uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
9212
9213// Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
9214//
9215// M+ = f * 2^e
9216// = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
9217// = ((p1 ) * 2^-e + (p2 )) * 2^e
9218// = p1 + p2 * 2^e
9219
9220const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
9221
9222uint32_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.)
9223uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
9224
9225// 1)
9226//
9227// Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
9228
9229assert(p1 > 0);
9230
9231uint32_t pow10;
9232const int k = find_largest_pow10(p1, pow10);
9233
9234// 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
9235//
9236// p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
9237// = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
9238//
9239// M+ = p1 + p2 * 2^e
9240// = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
9241// = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
9242// = d[k-1] * 10^(k-1) + ( rest) * 2^e
9243//
9244// Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
9245//
9246// p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
9247//
9248// but stop as soon as
9249//
9250// rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
9251
9252int n = k;
9253while (n > 0)
9254{
9255// Invariants:
9256// M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
9257// pow10 = 10^(n-1) <= p1 < 10^n
9258//
9259const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
9260const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
9261//
9262// M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
9263// = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
9264//
9265assert(d <= 9);
9266buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9267//
9268// M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
9269//
9270p1 = r;
9271n--;
9272//
9273// M+ = buffer * 10^n + (p1 + p2 * 2^e)
9274// pow10 = 10^n
9275//
9276
9277// Now check if enough digits have been generated.
9278// Compute
9279//
9280// p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
9281//
9282// Note:
9283// Since rest and delta share the same exponent e, it suffices to
9284// compare the significands.
9285const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
9286if (rest <= delta)
9287{
9288// V = buffer * 10^n, with M- <= V <= M+.
9289
9290decimal_exponent += n;
9291
9292// We may now just stop. But instead look if the buffer could be
9293// decremented to bring V closer to w.
9294//
9295// pow10 = 10^n is now 1 ulp in the decimal representation V.
9296// The rounding procedure works with diyfp's with an implicit
9297// exponent of e.
9298//
9299// 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
9300//
9301const uint64_t ten_n = uint64_t{pow10} << -one.e;
9302grisu2_round(buffer, length, dist, delta, rest, ten_n);
9303
9304return;
9305}
9306
9307pow10 /= 10;
9308//
9309// pow10 = 10^(n-1) <= p1 < 10^n
9310// Invariants restored.
9311}
9312
9313// 2)
9314//
9315// The digits of the integral part have been generated:
9316//
9317// M+ = d[k-1]...d[1]d[0] + p2 * 2^e
9318// = buffer + p2 * 2^e
9319//
9320// Now generate the digits of the fractional part p2 * 2^e.
9321//
9322// Note:
9323// No decimal point is generated: the exponent is adjusted instead.
9324//
9325// p2 actually represents the fraction
9326//
9327// p2 * 2^e
9328// = p2 / 2^-e
9329// = d[-1] / 10^1 + d[-2] / 10^2 + ...
9330//
9331// Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
9332//
9333// p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
9334// + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
9335//
9336// using
9337//
9338// 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
9339// = ( d) * 2^-e + ( r)
9340//
9341// or
9342// 10^m * p2 * 2^e = d + r * 2^e
9343//
9344// i.e.
9345//
9346// M+ = buffer + p2 * 2^e
9347// = buffer + 10^-m * (d + r * 2^e)
9348// = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
9349//
9350// and stop as soon as 10^-m * r * 2^e <= delta * 2^e
9351
9352assert(p2 > delta);
9353
9354int m = 0;
9355for (;;)
9356{
9357// Invariant:
9358// M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
9359// = buffer * 10^-m + 10^-m * (p2 ) * 2^e
9360// = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
9361// = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
9362//
9363assert(p2 <= UINT64_MAX / 10);
9364p2 *= 10;
9365const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
9366const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
9367//
9368// M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
9369// = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
9370// = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
9371//
9372assert(d <= 9);
9373buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
9374//
9375// M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
9376//
9377p2 = r;
9378m++;
9379//
9380// M+ = buffer * 10^-m + 10^-m * p2 * 2^e
9381// Invariant restored.
9382
9383// Check if enough digits have been generated.
9384//
9385// 10^-m * p2 * 2^e <= delta * 2^e
9386// p2 * 2^e <= 10^m * delta * 2^e
9387// p2 <= 10^m * delta
9388delta *= 10;
9389dist *= 10;
9390if (p2 <= delta)
9391{
9392break;
9393}
9394}
9395
9396// V = buffer * 10^-m, with M- <= V <= M+.
9397
9398decimal_exponent -= m;
9399
9400// 1 ulp in the decimal representation is now 10^-m.
9401// Since delta and dist are now scaled by 10^m, we need to do the
9402// same with ulp in order to keep the units in sync.
9403//
9404// 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
9405//
9406const uint64_t ten_m = one.f;
9407grisu2_round(buffer, length, dist, delta, p2, ten_m);
9408
9409// By construction this algorithm generates the shortest possible decimal
9410// number (Loitsch, Theorem 6.2) which rounds back to w.
9411// For an input number of precision p, at least
9412//
9413// N = 1 + ceil(p * log_10(2))
9414//
9415// decimal digits are sufficient to identify all binary floating-point
9416// numbers (Matula, "In-and-Out conversions").
9417// This implies that the algorithm does not produce more than N decimal
9418// digits.
9419//
9420// N = 17 for p = 53 (IEEE double precision)
9421// N = 9 for p = 24 (IEEE single precision)
9422}
9423
9424/*!
9425v = buf * 10^decimal_exponent
9426len is the length of the buffer (number of decimal digits)
9427The buffer must be large enough, i.e. >= max_digits10.
9428*/
9429inline void grisu2(char* buf, int& len, int& decimal_exponent,
9430diyfp m_minus, diyfp v, diyfp m_plus)
9431{
9432assert(m_plus.e == m_minus.e);
9433assert(m_plus.e == v.e);
9434
9435// --------(-----------------------+-----------------------)-------- (A)
9436// m- v m+
9437//
9438// --------------------(-----------+-----------------------)-------- (B)
9439// m- v m+
9440//
9441// First scale v (and m- and m+) such that the exponent is in the range
9442// [alpha, gamma].
9443
9444const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
9445
9446const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
9447
9448// The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
9449const diyfp w = diyfp::mul(v, c_minus_k);
9450const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
9451const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
9452
9453// ----(---+---)---------------(---+---)---------------(---+---)----
9454// w- w w+
9455// = c*m- = c*v = c*m+
9456//
9457// diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
9458// w+ are now off by a small amount.
9459// In fact:
9460//
9461// w - v * 10^k < 1 ulp
9462//
9463// To account for this inaccuracy, add resp. subtract 1 ulp.
9464//
9465// --------+---[---------------(---+---)---------------]---+--------
9466// w- M- w M+ w+
9467//
9468// Now any number in [M-, M+] (bounds included) will round to w when input,
9469// regardless of how the input rounding algorithm breaks ties.
9470//
9471// And digit_gen generates the shortest possible such number in [M-, M+].
9472// Note that this does not mean that Grisu2 always generates the shortest
9473// possible number in the interval (m-, m+).
9474const diyfp M_minus(w_minus.f + 1, w_minus.e);
9475const diyfp M_plus (w_plus.f - 1, w_plus.e );
9476
9477decimal_exponent = -cached.k; // = -(-k) = k
9478
9479grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
9480}
9481
9482/*!
9483v = buf * 10^decimal_exponent
9484len is the length of the buffer (number of decimal digits)
9485The buffer must be large enough, i.e. >= max_digits10.
9486*/
9487template <typename FloatType>
9488void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
9489{
9490static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
9491"internal error: not enough precision");
9492
9493assert(std::isfinite(value));
9494assert(value > 0);
9495
9496// If the neighbors (and boundaries) of 'value' are always computed for double-precision
9497// numbers, all float's can be recovered using strtod (and strtof). However, the resulting
9498// decimal representations are not exactly "short".
9499//
9500// The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
9501// says "value is converted to a string as if by std::sprintf in the default ("C") locale"
9502// and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
9503// does.
9504// On the other hand, the documentation for 'std::to_chars' requires that "parsing the
9505// representation using the corresponding std::from_chars function recovers value exactly". That
9506// indicates that single precision floating-point numbers should be recovered using
9507// 'std::strtof'.
9508//
9509// NB: If the neighbors are computed for single-precision numbers, there is a single float
9510// (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
9511// value is off by 1 ulp.
9512#if 0
9513const boundaries w = compute_boundaries(static_cast<double>(value));
9514#else
9515const boundaries w = compute_boundaries(value);
9516#endif
9517
9518grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
9519}
9520
9521/*!
9522@brief appends a decimal representation of e to buf
9523@return a pointer to the element following the exponent.
9524@pre -1000 < e < 1000
9525*/
9526inline char* append_exponent(char* buf, int e)
9527{
9528assert(e > -1000);
9529assert(e < 1000);
9530
9531if (e < 0)
9532{
9533e = -e;
9534*buf++ = '-';
9535}
9536else
9537{
9538*buf++ = '+';
9539}
9540
9541uint32_t k = static_cast<uint32_t>(e);
9542if (k < 10)
9543{
9544// Always print at least two digits in the exponent.
9545// This is for compatibility with printf("%g").
9546*buf++ = '0';
9547*buf++ = static_cast<char>('0' + k);
9548}
9549else if (k < 100)
9550{
9551*buf++ = static_cast<char>('0' + k / 10);
9552k %= 10;
9553*buf++ = static_cast<char>('0' + k);
9554}
9555else
9556{
9557*buf++ = static_cast<char>('0' + k / 100);
9558k %= 100;
9559*buf++ = static_cast<char>('0' + k / 10);
9560k %= 10;
9561*buf++ = static_cast<char>('0' + k);
9562}
9563
9564return buf;
9565}
9566
9567/*!
9568@brief prettify v = buf * 10^decimal_exponent
9569
9570If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
9571notation. Otherwise it will be printed in exponential notation.
9572
9573@pre min_exp < 0
9574@pre max_exp > 0
9575*/
9576inline char* format_buffer(char* buf, int len, int decimal_exponent,
9577int min_exp, int max_exp)
9578{
9579assert(min_exp < 0);
9580assert(max_exp > 0);
9581
9582const int k = len;
9583const int n = len + decimal_exponent;
9584
9585// v = buf * 10^(n-k)
9586// k is the length of the buffer (number of decimal digits)
9587// n is the position of the decimal point relative to the start of the buffer.
9588
9589if (k <= n and n <= max_exp)
9590{
9591// digits[000]
9592// len <= max_exp + 2
9593
9594std::memset(buf + k, '0', static_cast<size_t>(n - k));
9595// Make it look like a floating-point number (#362, #378)
9596buf[n + 0] = '.';
9597buf[n + 1] = '0';
9598return buf + (n + 2);
9599}
9600
9601if (0 < n and n <= max_exp)
9602{
9603// dig.its
9604// len <= max_digits10 + 1
9605
9606assert(k > n);
9607
9608std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
9609buf[n] = '.';
9610return buf + (k + 1);
9611}
9612
9613if (min_exp < n and n <= 0)
9614{
9615// 0.[000]digits
9616// len <= 2 + (-min_exp - 1) + max_digits10
9617
9618std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
9619buf[0] = '0';
9620buf[1] = '.';
9621std::memset(buf + 2, '0', static_cast<size_t>(-n));
9622return buf + (2 + (-n) + k);
9623}
9624
9625if (k == 1)
9626{
9627// dE+123
9628// len <= 1 + 5
9629
9630buf += 1;
9631}
9632else
9633{
9634// d.igitsE+123
9635// len <= max_digits10 + 1 + 5
9636
9637std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
9638buf[1] = '.';
9639buf += 1 + k;
9640}
9641
9642*buf++ = 'e';
9643return append_exponent(buf, n - 1);
9644}
9645
9646} // namespace dtoa_impl
9647
9648/*!
9649@brief generates a decimal representation of the floating-point number value in [first, last).
9650
9651The format of the resulting decimal representation is similar to printf's %g
9652format. Returns an iterator pointing past-the-end of the decimal representation.
9653
9654@note The input number must be finite, i.e. NaN's and Inf's are not supported.
9655@note The buffer must be large enough.
9656@note The result is NOT null-terminated.
9657*/
9658template <typename FloatType>
9659char* to_chars(char* first, char* last, FloatType value)
9660{
9661static_cast<void>(last); // maybe unused - fix warning
9662assert(std::isfinite(value));
9663
9664// Use signbit(value) instead of (value < 0) since signbit works for -0.
9665if (std::signbit(value))
9666{
9667value = -value;
9668*first++ = '-';
9669}
9670
9671if (value == 0) // +-0
9672{
9673*first++ = '0';
9674// Make it look like a floating-point number (#362, #378)
9675*first++ = '.';
9676*first++ = '0';
9677return first;
9678}
9679
9680assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
9681
9682// Compute v = buffer * 10^decimal_exponent.
9683// The decimal digits are stored in the buffer, which needs to be interpreted
9684// as an unsigned decimal integer.
9685// len is the length of the buffer, i.e. the number of decimal digits.
9686int len = 0;
9687int decimal_exponent = 0;
9688dtoa_impl::grisu2(first, len, decimal_exponent, value);
9689
9690assert(len <= std::numeric_limits<FloatType>::max_digits10);
9691
9692// Format the buffer like printf("%.*g", prec, value)
9693constexpr int kMinExp = -4;
9694// Use digits10 here to increase compatibility with version 2.
9695constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
9696
9697assert(last - first >= kMaxExp + 2);
9698assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
9699assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
9700
9701return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
9702}
9703
9704} // namespace detail
9705} // namespace nlohmann
9706
9707// #include <nlohmann/detail/macro_scope.hpp>
9708
9709// #include <nlohmann/detail/meta/cpp_future.hpp>
9710
9711// #include <nlohmann/detail/output/output_adapters.hpp>
9712
9713// #include <nlohmann/detail/value_t.hpp>
9714
9715
9716namespace nlohmann
9717{
9718namespace detail
9719{
9720///////////////////
9721// serialization //
9722///////////////////
9723
9724template<typename BasicJsonType>
9725class serializer
9726{
9727using string_t = typename BasicJsonType::string_t;
9728using number_float_t = typename BasicJsonType::number_float_t;
9729using number_integer_t = typename BasicJsonType::number_integer_t;
9730using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9731static constexpr uint8_t UTF8_ACCEPT = 0;
9732static constexpr uint8_t UTF8_REJECT = 1;
9733
9734public:
9735/*!
9736 @param[in] s output stream to serialize to
9737 @param[in] ichar indentation character to use
9738 */
9739serializer(output_adapter_t<char> s, const char ichar)
9740: o(std::move(s)), loc(std::localeconv()),
9741thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep)),
9742decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point)),
9743indent_char(ichar), indent_string(512, indent_char)
9744{}
9745
9746// delete because of pointer members
9747serializer(const serializer&) = delete;
9748serializer& operator=(const serializer&) = delete;
9749
9750/*!
9751 @brief internal implementation of the serialization function
9752
9753 This function is called by the public member function dump and organizes
9754 the serialization internally. The indentation level is propagated as
9755 additional parameter. In case of arrays and objects, the function is
9756 called recursively.
9757
9758 - strings and object keys are escaped using `escape_string()`
9759 - integer numbers are converted implicitly via `operator<<`
9760 - floating-point numbers are converted to a string using `"%g"` format
9761
9762 @param[in] val value to serialize
9763 @param[in] pretty_print whether the output shall be pretty-printed
9764 @param[in] indent_step the indent level
9765 @param[in] current_indent the current indent level (only used internally)
9766 */
9767void dump(const BasicJsonType& val, const bool pretty_print,
9768const bool ensure_ascii,
9769const unsigned int indent_step,
9770const unsigned int current_indent = 0)
9771{
9772switch (val.m_type)
9773{
9774case value_t::object:
9775{
9776if (val.m_value.object->empty())
9777{
9778o->write_characters("{}", 2);
9779return;
9780}
9781
9782if (pretty_print)
9783{
9784o->write_characters("{\n", 2);
9785
9786// variable to hold indentation for recursive calls
9787const auto new_indent = current_indent + indent_step;
9788if (JSON_UNLIKELY(indent_string.size() < new_indent))
9789{
9790indent_string.resize(indent_string.size() * 2, ' ');
9791}
9792
9793// first n-1 elements
9794auto i = val.m_value.object->cbegin();
9795for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9796{
9797o->write_characters(indent_string.c_str(), new_indent);
9798o->write_character('\"');
9799dump_escaped(i->first, ensure_ascii);
9800o->write_characters("\": ", 3);
9801dump(i->second, true, ensure_ascii, indent_step, new_indent);
9802o->write_characters(",\n", 2);
9803}
9804
9805// last element
9806assert(i != val.m_value.object->cend());
9807assert(std::next(i) == val.m_value.object->cend());
9808o->write_characters(indent_string.c_str(), new_indent);
9809o->write_character('\"');
9810dump_escaped(i->first, ensure_ascii);
9811o->write_characters("\": ", 3);
9812dump(i->second, true, ensure_ascii, indent_step, new_indent);
9813
9814o->write_character('\n');
9815o->write_characters(indent_string.c_str(), current_indent);
9816o->write_character('}');
9817}
9818else
9819{
9820o->write_character('{');
9821
9822// first n-1 elements
9823auto i = val.m_value.object->cbegin();
9824for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
9825{
9826o->write_character('\"');
9827dump_escaped(i->first, ensure_ascii);
9828o->write_characters("\":", 2);
9829dump(i->second, false, ensure_ascii, indent_step, current_indent);
9830o->write_character(',');
9831}
9832
9833// last element
9834assert(i != val.m_value.object->cend());
9835assert(std::next(i) == val.m_value.object->cend());
9836o->write_character('\"');
9837dump_escaped(i->first, ensure_ascii);
9838o->write_characters("\":", 2);
9839dump(i->second, false, ensure_ascii, indent_step, current_indent);
9840
9841o->write_character('}');
9842}
9843
9844return;
9845}
9846
9847case value_t::array:
9848{
9849if (val.m_value.array->empty())
9850{
9851o->write_characters("[]", 2);
9852return;
9853}
9854
9855if (pretty_print)
9856{
9857o->write_characters("[\n", 2);
9858
9859// variable to hold indentation for recursive calls
9860const auto new_indent = current_indent + indent_step;
9861if (JSON_UNLIKELY(indent_string.size() < new_indent))
9862{
9863indent_string.resize(indent_string.size() * 2, ' ');
9864}
9865
9866// first n-1 elements
9867for (auto i = val.m_value.array->cbegin();
9868i != val.m_value.array->cend() - 1; ++i)
9869{
9870o->write_characters(indent_string.c_str(), new_indent);
9871dump(*i, true, ensure_ascii, indent_step, new_indent);
9872o->write_characters(",\n", 2);
9873}
9874
9875// last element
9876assert(not val.m_value.array->empty());
9877o->write_characters(indent_string.c_str(), new_indent);
9878dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
9879
9880o->write_character('\n');
9881o->write_characters(indent_string.c_str(), current_indent);
9882o->write_character(']');
9883}
9884else
9885{
9886o->write_character('[');
9887
9888// first n-1 elements
9889for (auto i = val.m_value.array->cbegin();
9890i != val.m_value.array->cend() - 1; ++i)
9891{
9892dump(*i, false, ensure_ascii, indent_step, current_indent);
9893o->write_character(',');
9894}
9895
9896// last element
9897assert(not val.m_value.array->empty());
9898dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
9899
9900o->write_character(']');
9901}
9902
9903return;
9904}
9905
9906case value_t::string:
9907{
9908o->write_character('\"');
9909dump_escaped(*val.m_value.string, ensure_ascii);
9910o->write_character('\"');
9911return;
9912}
9913
9914case value_t::boolean:
9915{
9916if (val.m_value.boolean)
9917{
9918o->write_characters("true", 4);
9919}
9920else
9921{
9922o->write_characters("false", 5);
9923}
9924return;
9925}
9926
9927case value_t::number_integer:
9928{
9929dump_integer(val.m_value.number_integer);
9930return;
9931}
9932
9933case value_t::number_unsigned:
9934{
9935dump_integer(val.m_value.number_unsigned);
9936return;
9937}
9938
9939case value_t::number_float:
9940{
9941dump_float(val.m_value.number_float);
9942return;
9943}
9944
9945case value_t::discarded:
9946{
9947o->write_characters("<discarded>", 11);
9948return;
9949}
9950
9951case value_t::null:
9952{
9953o->write_characters("null", 4);
9954return;
9955}
9956}
9957}
9958
9959private:
9960/*!
9961 @brief dump escaped string
9962
9963 Escape a string by replacing certain special characters by a sequence of an
9964 escape character (backslash) and another character and other control
9965 characters by a sequence of "\u" followed by a four-digit hex
9966 representation. The escaped string is written to output stream @a o.
9967
9968 @param[in] s the string to escape
9969 @param[in] ensure_ascii whether to escape non-ASCII characters with
9970 \uXXXX sequences
9971
9972 @complexity Linear in the length of string @a s.
9973 */
9974void dump_escaped(const string_t& s, const bool ensure_ascii)
9975{
9976uint32_t codepoint;
9977uint8_t state = UTF8_ACCEPT;
9978std::size_t bytes = 0; // number of bytes written to string_buffer
9979
9980for (std::size_t i = 0; i < s.size(); ++i)
9981{
9982const auto byte = static_cast<uint8_t>(s[i]);
9983
9984switch (decode(state, codepoint, byte))
9985{
9986case UTF8_ACCEPT: // decode found a new code point
9987{
9988switch (codepoint)
9989{
9990case 0x08: // backspace
9991{
9992string_buffer[bytes++] = '\\';
9993string_buffer[bytes++] = 'b';
9994break;
9995}
9996
9997case 0x09: // horizontal tab
9998{
9999string_buffer[bytes++] = '\\';
10000string_buffer[bytes++] = 't';
10001break;
10002}
10003
10004case 0x0A: // newline
10005{
10006string_buffer[bytes++] = '\\';
10007string_buffer[bytes++] = 'n';
10008break;
10009}
10010
10011case 0x0C: // formfeed
10012{
10013string_buffer[bytes++] = '\\';
10014string_buffer[bytes++] = 'f';
10015break;
10016}
10017
10018case 0x0D: // carriage return
10019{
10020string_buffer[bytes++] = '\\';
10021string_buffer[bytes++] = 'r';
10022break;
10023}
10024
10025case 0x22: // quotation mark
10026{
10027string_buffer[bytes++] = '\\';
10028string_buffer[bytes++] = '\"';
10029break;
10030}
10031
10032case 0x5C: // reverse solidus
10033{
10034string_buffer[bytes++] = '\\';
10035string_buffer[bytes++] = '\\';
10036break;
10037}
10038
10039default:
10040{
10041// escape control characters (0x00..0x1F) or, if
10042// ensure_ascii parameter is used, non-ASCII characters
10043if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
10044{
10045if (codepoint <= 0xFFFF)
10046{
10047std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
10048static_cast<uint16_t>(codepoint));
10049bytes += 6;
10050}
10051else
10052{
10053std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
10054static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
10055static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
10056bytes += 12;
10057}
10058}
10059else
10060{
10061// copy byte to buffer (all previous bytes
10062// been copied have in default case above)
10063string_buffer[bytes++] = s[i];
10064}
10065break;
10066}
10067}
10068
10069// write buffer and reset index; there must be 13 bytes
10070// left, as this is the maximal number of bytes to be
10071// written ("\uxxxx\uxxxx\0") for one code point
10072if (string_buffer.size() - bytes < 13)
10073{
10074o->write_characters(string_buffer.data(), bytes);
10075bytes = 0;
10076}
10077break;
10078}
10079
10080case UTF8_REJECT: // decode found invalid UTF-8 byte
10081{
10082std::string sn(3, '\0');
10083snprintf(&sn[0], sn.size(), "%.2X", byte);
10084JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
10085}
10086
10087default: // decode found yet incomplete multi-byte code point
10088{
10089if (not ensure_ascii)
10090{
10091// code point will not be escaped - copy byte to buffer
10092string_buffer[bytes++] = s[i];
10093}
10094break;
10095}
10096}
10097}
10098
10099if (JSON_LIKELY(state == UTF8_ACCEPT))
10100{
10101// write buffer
10102if (bytes > 0)
10103{
10104o->write_characters(string_buffer.data(), bytes);
10105}
10106}
10107else
10108{
10109// we finish reading, but do not accept: string was incomplete
10110std::string sn(3, '\0');
10111snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
10112JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
10113}
10114}
10115
10116/*!
10117 @brief dump an integer
10118
10119 Dump a given integer to output stream @a o. Works internally with
10120 @a number_buffer.
10121
10122 @param[in] x integer number (signed or unsigned) to dump
10123 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
10124 */
10125template<typename NumberType, detail::enable_if_t<
10126std::is_same<NumberType, number_unsigned_t>::value or
10127std::is_same<NumberType, number_integer_t>::value,
10128int> = 0>
10129void dump_integer(NumberType x)
10130{
10131// special case for "0"
10132if (x == 0)
10133{
10134o->write_character('0');
10135return;
10136}
10137
10138const bool is_negative = (x <= 0) and (x != 0); // see issue #755
10139std::size_t i = 0;
10140
10141while (x != 0)
10142{
10143// spare 1 byte for '\0'
10144assert(i < number_buffer.size() - 1);
10145
10146const auto digit = std::labs(static_cast<long>(x % 10));
10147number_buffer[i++] = static_cast<char>('0' + digit);
10148x /= 10;
10149}
10150
10151if (is_negative)
10152{
10153// make sure there is capacity for the '-'
10154assert(i < number_buffer.size() - 2);
10155number_buffer[i++] = '-';
10156}
10157
10158std::reverse(number_buffer.begin(), number_buffer.begin() + i);
10159o->write_characters(number_buffer.data(), i);
10160}
10161
10162/*!
10163 @brief dump a floating-point number
10164
10165 Dump a given floating-point number to output stream @a o. Works internally
10166 with @a number_buffer.
10167
10168 @param[in] x floating-point number to dump
10169 */
10170void dump_float(number_float_t x)
10171{
10172// NaN / inf
10173if (not std::isfinite(x))
10174{
10175o->write_characters("null", 4);
10176return;
10177}
10178
10179// If number_float_t is an IEEE-754 single or double precision number,
10180// use the Grisu2 algorithm to produce short numbers which are
10181// guaranteed to round-trip, using strtof and strtod, resp.
10182//
10183// NB: The test below works if <long double> == <double>.
10184static constexpr bool is_ieee_single_or_double
10185= (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
10186(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);
10187
10188dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
10189}
10190
10191void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
10192{
10193char* begin = number_buffer.data();
10194char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
10195
10196o->write_characters(begin, static_cast<size_t>(end - begin));
10197}
10198
10199void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
10200{
10201// get number of digits for a float -> text -> float round-trip
10202static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
10203
10204// the actual conversion
10205std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
10206
10207// negative value indicates an error
10208assert(len > 0);
10209// check if buffer was large enough
10210assert(static_cast<std::size_t>(len) < number_buffer.size());
10211
10212// erase thousands separator
10213if (thousands_sep != '\0')
10214{
10215const auto end = std::remove(number_buffer.begin(),
10216number_buffer.begin() + len, thousands_sep);
10217std::fill(end, number_buffer.end(), '\0');
10218assert((end - number_buffer.begin()) <= len);
10219len = (end - number_buffer.begin());
10220}
10221
10222// convert decimal point to '.'
10223if (decimal_point != '\0' and decimal_point != '.')
10224{
10225const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
10226if (dec_pos != number_buffer.end())
10227{
10228*dec_pos = '.';
10229}
10230}
10231
10232o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
10233
10234// determine if need to append ".0"
10235const bool value_is_int_like =
10236std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
10237[](char c)
10238{
10239return (c == '.' or c == 'e');
10240});
10241
10242if (value_is_int_like)
10243{
10244o->write_characters(".0", 2);
10245}
10246}
10247
10248/*!
10249 @brief check whether a string is UTF-8 encoded
10250
10251 The function checks each byte of a string whether it is UTF-8 encoded. The
10252 result of the check is stored in the @a state parameter. The function must
10253 be called initially with state 0 (accept). State 1 means the string must
10254 be rejected, because the current byte is not allowed. If the string is
10255 completely processed, but the state is non-zero, the string ended
10256 prematurely; that is, the last byte indicated more bytes should have
10257 followed.
10258
10259 @param[in,out] state the state of the decoding
10260 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
10261 @param[in] byte next byte to decode
10262 @return new state
10263
10264 @note The function has been edited: a std::array is used.
10265
10266 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
10267 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
10268 */
10269static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
10270{
10271static const std::array<uint8_t, 400> utf8d =
10272{
10273{
102740, 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
102750, 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
102760, 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
102770, 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
102781, 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
102797, 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
102808, 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
102810xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
102820xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
102830x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
102841, 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
102851, 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
102861, 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
102871, 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
10288}
10289};
10290
10291const uint8_t type = utf8d[byte];
10292
10293codep = (state != UTF8_ACCEPT)
10294? (byte & 0x3fu) | (codep << 6)
10295: static_cast<uint32_t>(0xff >> type) & (byte);
10296
10297state = utf8d[256u + state * 16u + type];
10298return state;
10299}
10300
10301private:
10302/// the output of the serializer
10303output_adapter_t<char> o = nullptr;
10304
10305/// a (hopefully) large enough character buffer
10306std::array<char, 64> number_buffer{{}};
10307
10308/// the locale
10309const std::lconv* loc = nullptr;
10310/// the locale's thousand separator character
10311const char thousands_sep = '\0';
10312/// the locale's decimal point character
10313const char decimal_point = '\0';
10314
10315/// string buffer
10316std::array<char, 512> string_buffer{{}};
10317
10318/// the indentation character
10319const char indent_char;
10320/// the indentation string
10321string_t indent_string;
10322};
10323}
10324}
10325
10326// #include <nlohmann/detail/json_ref.hpp>
10327
10328
10329#include <initializer_list>
10330#include <utility>
10331
10332namespace nlohmann
10333{
10334namespace detail
10335{
10336template<typename BasicJsonType>
10337class json_ref
10338{
10339public:
10340using value_type = BasicJsonType;
10341
10342json_ref(value_type&& value)
10343: owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
10344{}
10345
10346json_ref(const value_type& value)
10347: value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
10348{}
10349
10350json_ref(std::initializer_list<json_ref> init)
10351: owned_value(init), value_ref(&owned_value), is_rvalue(true)
10352{}
10353
10354template<class... Args>
10355json_ref(Args&& ... args)
10356: owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
10357{}
10358
10359// class should be movable only
10360json_ref(json_ref&&) = default;
10361json_ref(const json_ref&) = delete;
10362json_ref& operator=(const json_ref&) = delete;
10363
10364value_type moved_or_copied() const
10365{
10366if (is_rvalue)
10367{
10368return std::move(*value_ref);
10369}
10370return *value_ref;
10371}
10372
10373value_type const& operator*() const
10374{
10375return *static_cast<value_type const*>(value_ref);
10376}
10377
10378value_type const* operator->() const
10379{
10380return static_cast<value_type const*>(value_ref);
10381}
10382
10383private:
10384mutable value_type owned_value = nullptr;
10385value_type* value_ref = nullptr;
10386const bool is_rvalue;
10387};
10388}
10389}
10390
10391// #include <nlohmann/detail/json_pointer.hpp>
10392
10393
10394#include <cassert> // assert
10395#include <numeric> // accumulate
10396#include <string> // string
10397#include <vector> // vector
10398
10399// #include <nlohmann/detail/macro_scope.hpp>
10400
10401// #include <nlohmann/detail/exceptions.hpp>
10402
10403// #include <nlohmann/detail/value_t.hpp>
10404
10405
10406namespace nlohmann
10407{
10408template<typename BasicJsonType>
10409class json_pointer
10410{
10411// allow basic_json to access private members
10412NLOHMANN_BASIC_JSON_TPL_DECLARATION
10413friend class basic_json;
10414
10415public:
10416/*!
10417 @brief create JSON pointer
10418
10419 Create a JSON pointer according to the syntax described in
10420 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
10421
10422 @param[in] s string representing the JSON pointer; if omitted, the empty
10423 string is assumed which references the whole JSON value
10424
10425 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
10426 not begin with a slash (`/`); see example below
10427
10428 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
10429 not followed by `0` (representing `~`) or `1` (representing `/`); see
10430 example below
10431
10432 @liveexample{The example shows the construction several valid JSON pointers
10433 as well as the exceptional behavior.,json_pointer}
10434
10435 @since version 2.0.0
10436 */
10437explicit json_pointer(const std::string& s = "")
10438: reference_tokens(split(s))
10439{}
10440
10441/*!
10442 @brief return a string representation of the JSON pointer
10443
10444 @invariant For each JSON pointer `ptr`, it holds:
10445 @code {.cpp}
10446 ptr == json_pointer(ptr.to_string());
10447 @endcode
10448
10449 @return a string representation of the JSON pointer
10450
10451 @liveexample{The example shows the result of `to_string`.,
10452 json_pointer__to_string}
10453
10454 @since version 2.0.0
10455 */
10456std::string to_string() const noexcept
10457{
10458return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10459std::string{},
10460[](const std::string & a, const std::string & b)
10461{
10462return a + "/" + escape(b);
10463});
10464}
10465
10466/// @copydoc to_string()
10467operator std::string() const
10468{
10469return to_string();
10470}
10471
10472/*!
10473 @param[in] s reference token to be converted into an array index
10474
10475 @return integer representation of @a s
10476
10477 @throw out_of_range.404 if string @a s could not be converted to an integer
10478 */
10479static int array_index(const std::string& s)
10480{
10481std::size_t processed_chars = 0;
10482const int res = std::stoi(s, &processed_chars);
10483
10484// check if the string was completely read
10485if (JSON_UNLIKELY(processed_chars != s.size()))
10486{
10487JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
10488}
10489
10490return res;
10491}
10492
10493private:
10494/*!
10495 @brief remove and return last reference pointer
10496 @throw out_of_range.405 if JSON pointer has no parent
10497 */
10498std::string pop_back()
10499{
10500if (JSON_UNLIKELY(is_root()))
10501{
10502JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10503}
10504
10505auto last = reference_tokens.back();
10506reference_tokens.pop_back();
10507return last;
10508}
10509
10510/// return whether pointer points to the root document
10511bool is_root() const
10512{
10513return reference_tokens.empty();
10514}
10515
10516json_pointer top() const
10517{
10518if (JSON_UNLIKELY(is_root()))
10519{
10520JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10521}
10522
10523json_pointer result = *this;
10524result.reference_tokens = {reference_tokens[0]};
10525return result;
10526}
10527
10528/*!
10529 @brief create and return a reference to the pointed to value
10530
10531 @complexity Linear in the number of reference tokens.
10532
10533 @throw parse_error.109 if array index is not a number
10534 @throw type_error.313 if value cannot be unflattened
10535 */
10536BasicJsonType& get_and_create(BasicJsonType& j) const
10537{
10538using size_type = typename BasicJsonType::size_type;
10539auto result = &j;
10540
10541// in case no reference tokens exist, return a reference to the JSON value
10542// j which will be overwritten by a primitive value
10543for (const auto& reference_token : reference_tokens)
10544{
10545switch (result->m_type)
10546{
10547case detail::value_t::null:
10548{
10549if (reference_token == "0")
10550{
10551// start a new array if reference token is 0
10552result = &result->operator[](0);
10553}
10554else
10555{
10556// start a new object otherwise
10557result = &result->operator[](reference_token);
10558}
10559break;
10560}
10561
10562case detail::value_t::object:
10563{
10564// create an entry in the object
10565result = &result->operator[](reference_token);
10566break;
10567}
10568
10569case detail::value_t::array:
10570{
10571// create an entry in the array
10572JSON_TRY
10573{
10574result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
10575}
10576JSON_CATCH(std::invalid_argument&)
10577{
10578JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10579}
10580break;
10581}
10582
10583/*
10584 The following code is only reached if there exists a reference
10585 token _and_ the current value is primitive. In this case, we have
10586 an error situation, because primitive values may only occur as
10587 single value; that is, with an empty list of reference tokens.
10588 */
10589default:
10590JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
10591}
10592}
10593
10594return *result;
10595}
10596
10597/*!
10598 @brief return a reference to the pointed to value
10599
10600 @note This version does not throw if a value is not present, but tries to
10601 create nested values instead. For instance, calling this function
10602 with pointer `"/this/that"` on a null value is equivalent to calling
10603 `operator[]("this").operator[]("that")` on that value, effectively
10604 changing the null value to an object.
10605
10606 @param[in] ptr a JSON value
10607
10608 @return reference to the JSON value pointed to by the JSON pointer
10609
10610 @complexity Linear in the length of the JSON pointer.
10611
10612 @throw parse_error.106 if an array index begins with '0'
10613 @throw parse_error.109 if an array index was not a number
10614 @throw out_of_range.404 if the JSON pointer can not be resolved
10615 */
10616BasicJsonType& get_unchecked(BasicJsonType* ptr) const
10617{
10618using size_type = typename BasicJsonType::size_type;
10619for (const auto& reference_token : reference_tokens)
10620{
10621// convert null values to arrays or objects before continuing
10622if (ptr->m_type == detail::value_t::null)
10623{
10624// check if reference token is a number
10625const bool nums =
10626std::all_of(reference_token.begin(), reference_token.end(),
10627[](const char x)
10628{
10629return (x >= '0' and x <= '9');
10630});
10631
10632// change value to array for numbers or "-" or to object otherwise
10633*ptr = (nums or reference_token == "-")
10634? detail::value_t::array
10635: detail::value_t::object;
10636}
10637
10638switch (ptr->m_type)
10639{
10640case detail::value_t::object:
10641{
10642// use unchecked object access
10643ptr = &ptr->operator[](reference_token);
10644break;
10645}
10646
10647case detail::value_t::array:
10648{
10649// error condition (cf. RFC 6901, Sect. 4)
10650if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10651{
10652JSON_THROW(detail::parse_error::create(106, 0,
10653"array index '" + reference_token +
10654"' must not begin with '0'"));
10655}
10656
10657if (reference_token == "-")
10658{
10659// explicitly treat "-" as index beyond the end
10660ptr = &ptr->operator[](ptr->m_value.array->size());
10661}
10662else
10663{
10664// convert array index to number; unchecked access
10665JSON_TRY
10666{
10667ptr = &ptr->operator[](
10668static_cast<size_type>(array_index(reference_token)));
10669}
10670JSON_CATCH(std::invalid_argument&)
10671{
10672JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10673}
10674}
10675break;
10676}
10677
10678default:
10679JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10680}
10681}
10682
10683return *ptr;
10684}
10685
10686/*!
10687 @throw parse_error.106 if an array index begins with '0'
10688 @throw parse_error.109 if an array index was not a number
10689 @throw out_of_range.402 if the array index '-' is used
10690 @throw out_of_range.404 if the JSON pointer can not be resolved
10691 */
10692BasicJsonType& get_checked(BasicJsonType* ptr) const
10693{
10694using size_type = typename BasicJsonType::size_type;
10695for (const auto& reference_token : reference_tokens)
10696{
10697switch (ptr->m_type)
10698{
10699case detail::value_t::object:
10700{
10701// note: at performs range check
10702ptr = &ptr->at(reference_token);
10703break;
10704}
10705
10706case detail::value_t::array:
10707{
10708if (JSON_UNLIKELY(reference_token == "-"))
10709{
10710// "-" always fails the range check
10711JSON_THROW(detail::out_of_range::create(402,
10712"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10713") is out of range"));
10714}
10715
10716// error condition (cf. RFC 6901, Sect. 4)
10717if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10718{
10719JSON_THROW(detail::parse_error::create(106, 0,
10720"array index '" + reference_token +
10721"' must not begin with '0'"));
10722}
10723
10724// note: at performs range check
10725JSON_TRY
10726{
10727ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10728}
10729JSON_CATCH(std::invalid_argument&)
10730{
10731JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10732}
10733break;
10734}
10735
10736default:
10737JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10738}
10739}
10740
10741return *ptr;
10742}
10743
10744/*!
10745 @brief return a const reference to the pointed to value
10746
10747 @param[in] ptr a JSON value
10748
10749 @return const reference to the JSON value pointed to by the JSON
10750 pointer
10751
10752 @throw parse_error.106 if an array index begins with '0'
10753 @throw parse_error.109 if an array index was not a number
10754 @throw out_of_range.402 if the array index '-' is used
10755 @throw out_of_range.404 if the JSON pointer can not be resolved
10756 */
10757const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
10758{
10759using size_type = typename BasicJsonType::size_type;
10760for (const auto& reference_token : reference_tokens)
10761{
10762switch (ptr->m_type)
10763{
10764case detail::value_t::object:
10765{
10766// use unchecked object access
10767ptr = &ptr->operator[](reference_token);
10768break;
10769}
10770
10771case detail::value_t::array:
10772{
10773if (JSON_UNLIKELY(reference_token == "-"))
10774{
10775// "-" cannot be used for const access
10776JSON_THROW(detail::out_of_range::create(402,
10777"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10778") is out of range"));
10779}
10780
10781// error condition (cf. RFC 6901, Sect. 4)
10782if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10783{
10784JSON_THROW(detail::parse_error::create(106, 0,
10785"array index '" + reference_token +
10786"' must not begin with '0'"));
10787}
10788
10789// use unchecked array access
10790JSON_TRY
10791{
10792ptr = &ptr->operator[](
10793static_cast<size_type>(array_index(reference_token)));
10794}
10795JSON_CATCH(std::invalid_argument&)
10796{
10797JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10798}
10799break;
10800}
10801
10802default:
10803JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10804}
10805}
10806
10807return *ptr;
10808}
10809
10810/*!
10811 @throw parse_error.106 if an array index begins with '0'
10812 @throw parse_error.109 if an array index was not a number
10813 @throw out_of_range.402 if the array index '-' is used
10814 @throw out_of_range.404 if the JSON pointer can not be resolved
10815 */
10816const BasicJsonType& get_checked(const BasicJsonType* ptr) const
10817{
10818using size_type = typename BasicJsonType::size_type;
10819for (const auto& reference_token : reference_tokens)
10820{
10821switch (ptr->m_type)
10822{
10823case detail::value_t::object:
10824{
10825// note: at performs range check
10826ptr = &ptr->at(reference_token);
10827break;
10828}
10829
10830case detail::value_t::array:
10831{
10832if (JSON_UNLIKELY(reference_token == "-"))
10833{
10834// "-" always fails the range check
10835JSON_THROW(detail::out_of_range::create(402,
10836"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10837") is out of range"));
10838}
10839
10840// error condition (cf. RFC 6901, Sect. 4)
10841if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10842{
10843JSON_THROW(detail::parse_error::create(106, 0,
10844"array index '" + reference_token +
10845"' must not begin with '0'"));
10846}
10847
10848// note: at performs range check
10849JSON_TRY
10850{
10851ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10852}
10853JSON_CATCH(std::invalid_argument&)
10854{
10855JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10856}
10857break;
10858}
10859
10860default:
10861JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10862}
10863}
10864
10865return *ptr;
10866}
10867
10868/*!
10869 @brief split the string input to reference tokens
10870
10871 @note This function is only called by the json_pointer constructor.
10872 All exceptions below are documented there.
10873
10874 @throw parse_error.107 if the pointer is not empty or begins with '/'
10875 @throw parse_error.108 if character '~' is not followed by '0' or '1'
10876 */
10877static std::vector<std::string> split(const std::string& reference_string)
10878{
10879std::vector<std::string> result;
10880
10881// special case: empty reference string -> no reference tokens
10882if (reference_string.empty())
10883{
10884return result;
10885}
10886
10887// check if nonempty reference string begins with slash
10888if (JSON_UNLIKELY(reference_string[0] != '/'))
10889{
10890JSON_THROW(detail::parse_error::create(107, 1,
10891"JSON pointer must be empty or begin with '/' - was: '" +
10892reference_string + "'"));
10893}
10894
10895// extract the reference tokens:
10896// - slash: position of the last read slash (or end of string)
10897// - start: position after the previous slash
10898for (
10899// search for the first slash after the first character
10900std::size_t slash = reference_string.find_first_of('/', 1),
10901// set the beginning of the first reference token
10902start = 1;
10903// we can stop if start == string::npos+1 = 0
10904start != 0;
10905// set the beginning of the next reference token
10906// (will eventually be 0 if slash == std::string::npos)
10907start = slash + 1,
10908// find next slash
10909slash = reference_string.find_first_of('/', start))
10910{
10911// use the text between the beginning of the reference token
10912// (start) and the last slash (slash).
10913auto reference_token = reference_string.substr(start, slash - start);
10914
10915// check reference tokens are properly escaped
10916for (std::size_t pos = reference_token.find_first_of('~');
10917pos != std::string::npos;
10918pos = reference_token.find_first_of('~', pos + 1))
10919{
10920assert(reference_token[pos] == '~');
10921
10922// ~ must be followed by 0 or 1
10923if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
10924(reference_token[pos + 1] != '0' and
10925reference_token[pos + 1] != '1')))
10926{
10927JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
10928}
10929}
10930
10931// finally, store the reference token
10932unescape(reference_token);
10933result.push_back(reference_token);
10934}
10935
10936return result;
10937}
10938
10939/*!
10940 @brief replace all occurrences of a substring by another string
10941
10942 @param[in,out] s the string to manipulate; changed so that all
10943 occurrences of @a f are replaced with @a t
10944 @param[in] f the substring to replace with @a t
10945 @param[in] t the string to replace @a f
10946
10947 @pre The search string @a f must not be empty. **This precondition is
10948 enforced with an assertion.**
10949
10950 @since version 2.0.0
10951 */
10952static void replace_substring(std::string& s, const std::string& f,
10953const std::string& t)
10954{
10955assert(not f.empty());
10956for (auto pos = s.find(f); // find first occurrence of f
10957pos != std::string::npos; // make sure f was found
10958s.replace(pos, f.size(), t), // replace with t, and
10959pos = s.find(f, pos + t.size())) // find next occurrence of f
10960{}
10961}
10962
10963/// escape "~"" to "~0" and "/" to "~1"
10964static std::string escape(std::string s)
10965{
10966replace_substring(s, "~", "~0");
10967replace_substring(s, "/", "~1");
10968return s;
10969}
10970
10971/// unescape "~1" to tilde and "~0" to slash (order is important!)
10972static void unescape(std::string& s)
10973{
10974replace_substring(s, "~1", "/");
10975replace_substring(s, "~0", "~");
10976}
10977
10978/*!
10979 @param[in] reference_string the reference string to the current value
10980 @param[in] value the value to consider
10981 @param[in,out] result the result object to insert values to
10982
10983 @note Empty objects or arrays are flattened to `null`.
10984 */
10985static void flatten(const std::string& reference_string,
10986const BasicJsonType& value,
10987BasicJsonType& result)
10988{
10989switch (value.m_type)
10990{
10991case detail::value_t::array:
10992{
10993if (value.m_value.array->empty())
10994{
10995// flatten empty array as null
10996result[reference_string] = nullptr;
10997}
10998else
10999{
11000// iterate array and use index as reference string
11001for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11002{
11003flatten(reference_string + "/" + std::to_string(i),
11004value.m_value.array->operator[](i), result);
11005}
11006}
11007break;
11008}
11009
11010case detail::value_t::object:
11011{
11012if (value.m_value.object->empty())
11013{
11014// flatten empty object as null
11015result[reference_string] = nullptr;
11016}
11017else
11018{
11019// iterate object and use keys as reference string
11020for (const auto& element : *value.m_value.object)
11021{
11022flatten(reference_string + "/" + escape(element.first), element.second, result);
11023}
11024}
11025break;
11026}
11027
11028default:
11029{
11030// add primitive value with its reference string
11031result[reference_string] = value;
11032break;
11033}
11034}
11035}
11036
11037/*!
11038 @param[in] value flattened JSON
11039
11040 @return unflattened JSON
11041
11042 @throw parse_error.109 if array index is not a number
11043 @throw type_error.314 if value is not an object
11044 @throw type_error.315 if object values are not primitive
11045 @throw type_error.313 if value cannot be unflattened
11046 */
11047static BasicJsonType
11048unflatten(const BasicJsonType& value)
11049{
11050if (JSON_UNLIKELY(not value.is_object()))
11051{
11052JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11053}
11054
11055BasicJsonType result;
11056
11057// iterate the JSON object values
11058for (const auto& element : *value.m_value.object)
11059{
11060if (JSON_UNLIKELY(not element.second.is_primitive()))
11061{
11062JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11063}
11064
11065// assign value to reference pointed to by JSON pointer; Note that if
11066// the JSON pointer is "" (i.e., points to the whole value), function
11067// get_and_create returns a reference to result itself. An assignment
11068// will then create a primitive value.
11069json_pointer(element.first).get_and_create(result) = element.second;
11070}
11071
11072return result;
11073}
11074
11075friend bool operator==(json_pointer const& lhs,
11076json_pointer const& rhs) noexcept
11077{
11078return (lhs.reference_tokens == rhs.reference_tokens);
11079}
11080
11081friend bool operator!=(json_pointer const& lhs,
11082json_pointer const& rhs) noexcept
11083{
11084return not (lhs == rhs);
11085}
11086
11087/// the reference tokens
11088std::vector<std::string> reference_tokens;
11089};
11090}
11091
11092// #include <nlohmann/adl_serializer.hpp>
11093
11094
11095#include <utility>
11096
11097// #include <nlohmann/detail/conversions/from_json.hpp>
11098
11099// #include <nlohmann/detail/conversions/to_json.hpp>
11100
11101
11102namespace nlohmann
11103{
11104template<typename, typename>
11105struct adl_serializer
11106{
11107/*!
11108 @brief convert a JSON value to any value type
11109
11110 This function is usually called by the `get()` function of the
11111 @ref basic_json class (either explicit or via conversion operators).
11112
11113 @param[in] j JSON value to read from
11114 @param[in,out] val value to write to
11115 */
11116template<typename BasicJsonType, typename ValueType>
11117static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
11118noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val))) -> decltype(
11119::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void()
11120)
11121{
11122::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
11123}
11124
11125/*!
11126 @brief convert any value type to a JSON value
11127
11128 This function is usually called by the constructors of the @ref basic_json
11129 class.
11130
11131 @param[in,out] j JSON value to write to
11132 @param[in] val value to read from
11133 */
11134template <typename BasicJsonType, typename ValueType>
11135static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
11136noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
11137-> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
11138void())
11139{
11140::nlohmann::to_json(j, std::forward<ValueType>(val));
11141}
11142};
11143}
11144
11145
11146/*!
11147@brief namespace for Niels Lohmann
11148@see https://github.com/nlohmann
11149@since version 1.0.0
11150*/
11151namespace nlohmann
11152{
11153
11154/*!
11155@brief a class to store JSON values
11156
11157@tparam ObjectType type for JSON objects (`std::map` by default; will be used
11158in @ref object_t)
11159@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
11160in @ref array_t)
11161@tparam StringType type for JSON strings and object keys (`std::string` by
11162default; will be used in @ref string_t)
11163@tparam BooleanType type for JSON booleans (`bool` by default; will be used
11164in @ref boolean_t)
11165@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
11166default; will be used in @ref number_integer_t)
11167@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
11168`uint64_t` by default; will be used in @ref number_unsigned_t)
11169@tparam NumberFloatType type for JSON floating-point numbers (`double` by
11170default; will be used in @ref number_float_t)
11171@tparam AllocatorType type of the allocator to use (`std::allocator` by
11172default)
11173@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
11174and `from_json()` (@ref adl_serializer by default)
11175
11176@requirement The class satisfies the following concept requirements:
11177- Basic
11178 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
11179 JSON values can be default constructed. The result will be a JSON null
11180 value.
11181 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
11182 A JSON value can be constructed from an rvalue argument.
11183 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
11184 A JSON value can be copy-constructed from an lvalue expression.
11185 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
11186 A JSON value van be assigned from an rvalue argument.
11187 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
11188 A JSON value can be copy-assigned from an lvalue expression.
11189 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
11190 JSON values can be destructed.
11191- Layout
11192 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
11193 JSON values have
11194 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
11195 All non-static data members are private and standard layout types, the
11196 class has no virtual functions or (virtual) base classes.
11197- Library-wide
11198 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
11199 JSON values can be compared with `==`, see @ref
11200 operator==(const_reference,const_reference).
11201 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
11202 JSON values can be compared with `<`, see @ref
11203 operator<(const_reference,const_reference).
11204 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
11205 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
11206 other compatible types, using unqualified function call @ref swap().
11207 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
11208 JSON values can be compared against `std::nullptr_t` objects which are used
11209 to model the `null` value.
11210- Container
11211 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
11212 JSON values can be used like STL containers and provide iterator access.
11213 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
11214 JSON values can be used like STL containers and provide reverse iterator
11215 access.
11216
11217@invariant The member variables @a m_value and @a m_type have the following
11218relationship:
11219- If `m_type == value_t::object`, then `m_value.object != nullptr`.
11220- If `m_type == value_t::array`, then `m_value.array != nullptr`.
11221- If `m_type == value_t::string`, then `m_value.string != nullptr`.
11222The invariants are checked by member function assert_invariant().
11223
11224@internal
11225@note ObjectType trick from http://stackoverflow.com/a/9860911
11226@endinternal
11227
11228@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
11229Format](http://rfc7159.net/rfc7159)
11230
11231@since version 1.0.0
11232
11233@nosubgrouping
11234*/
11235NLOHMANN_BASIC_JSON_TPL_DECLARATION
11236class basic_json
11237{
11238private:
11239template<detail::value_t> friend struct detail::external_constructor;
11240friend ::nlohmann::json_pointer<basic_json>;
11241friend ::nlohmann::detail::parser<basic_json>;
11242friend ::nlohmann::detail::serializer<basic_json>;
11243template<typename BasicJsonType>
11244friend class ::nlohmann::detail::iter_impl;
11245template<typename BasicJsonType, typename CharType>
11246friend class ::nlohmann::detail::binary_writer;
11247template<typename BasicJsonType, typename SAX>
11248friend class ::nlohmann::detail::binary_reader;
11249template<typename BasicJsonType>
11250friend class ::nlohmann::detail::json_sax_dom_parser;
11251template<typename BasicJsonType>
11252friend class ::nlohmann::detail::json_sax_dom_callback_parser;
11253
11254/// workaround type for MSVC
11255using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
11256
11257// convenience aliases for types residing in namespace detail;
11258using lexer = ::nlohmann::detail::lexer<basic_json>;
11259using parser = ::nlohmann::detail::parser<basic_json>;
11260
11261using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
11262template<typename BasicJsonType>
11263using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
11264template<typename BasicJsonType>
11265using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
11266template<typename Iterator>
11267using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
11268template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
11269
11270template<typename CharType>
11271using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
11272
11273using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
11274template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
11275
11276using serializer = ::nlohmann::detail::serializer<basic_json>;
11277
11278public:
11279using value_t = detail::value_t;
11280/// JSON Pointer, see @ref nlohmann::json_pointer
11281using json_pointer = ::nlohmann::json_pointer<basic_json>;
11282template<typename T, typename SFINAE>
11283using json_serializer = JSONSerializer<T, SFINAE>;
11284/// helper type for initializer lists of basic_json values
11285using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
11286
11287using input_format_t = detail::input_format_t;
11288/// SAX interface type, see @ref nlohmann::json_sax
11289using json_sax_t = json_sax<basic_json>;
11290
11291////////////////
11292// exceptions //
11293////////////////
11294
11295/// @name exceptions
11296/// Classes to implement user-defined exceptions.
11297/// @{
11298
11299/// @copydoc detail::exception
11300using exception = detail::exception;
11301/// @copydoc detail::parse_error
11302using parse_error = detail::parse_error;
11303/// @copydoc detail::invalid_iterator
11304using invalid_iterator = detail::invalid_iterator;
11305/// @copydoc detail::type_error
11306using type_error = detail::type_error;
11307/// @copydoc detail::out_of_range
11308using out_of_range = detail::out_of_range;
11309/// @copydoc detail::other_error
11310using other_error = detail::other_error;
11311
11312/// @}
11313
11314
11315/////////////////////
11316// container types //
11317/////////////////////
11318
11319/// @name container types
11320/// The canonic container types to use @ref basic_json like any other STL
11321/// container.
11322/// @{
11323
11324/// the type of elements in a basic_json container
11325using value_type = basic_json;
11326
11327/// the type of an element reference
11328using reference = value_type&;
11329/// the type of an element const reference
11330using const_reference = const value_type&;
11331
11332/// a type to represent differences between iterators
11333using difference_type = std::ptrdiff_t;
11334/// a type to represent container sizes
11335using size_type = std::size_t;
11336
11337/// the allocator type
11338using allocator_type = AllocatorType<basic_json>;
11339
11340/// the type of an element pointer
11341using pointer = typename std::allocator_traits<allocator_type>::pointer;
11342/// the type of an element const pointer
11343using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
11344
11345/// an iterator for a basic_json container
11346using iterator = iter_impl<basic_json>;
11347/// a const iterator for a basic_json container
11348using const_iterator = iter_impl<const basic_json>;
11349/// a reverse iterator for a basic_json container
11350using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
11351/// a const reverse iterator for a basic_json container
11352using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
11353
11354/// @}
11355
11356
11357/*!
11358 @brief returns the allocator associated with the container
11359 */
11360static allocator_type get_allocator()
11361{
11362return allocator_type();
11363}
11364
11365/*!
11366 @brief returns version information on the library
11367
11368 This function returns a JSON object with information about the library,
11369 including the version number and information on the platform and compiler.
11370
11371 @return JSON object holding version information
11372 key | description
11373 ----------- | ---------------
11374 `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).
11375 `copyright` | The copyright line for the library as string.
11376 `name` | The name of the library as string.
11377 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
11378 `url` | The URL of the project as string.
11379 `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).
11380
11381 @liveexample{The following code shows an example output of the `meta()`
11382 function.,meta}
11383
11384 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
11385 changes to any JSON value.
11386
11387 @complexity Constant.
11388
11389 @since 2.1.0
11390 */
11391static basic_json meta()
11392{
11393basic_json result;
11394
11395result["copyright"] = "(C) 2013-2017 Niels Lohmann";
11396result["name"] = "JSON for Modern C++";
11397result["url"] = "https://github.com/nlohmann/json";
11398result["version"]["string"] =
11399std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
11400std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
11401std::to_string(NLOHMANN_JSON_VERSION_PATCH);
11402result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
11403result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
11404result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
11405
11406#ifdef _WIN32
11407result["platform"] = "win32";
11408#elif defined __linux__
11409result["platform"] = "linux";
11410#elif defined __APPLE__
11411result["platform"] = "apple";
11412#elif defined __unix__
11413result["platform"] = "unix";
11414#else
11415result["platform"] = "unknown";
11416#endif
11417
11418#if defined(__ICC) || defined(__INTEL_COMPILER)
11419result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
11420#elif defined(__clang__)
11421result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
11422#elif defined(__GNUC__) || defined(__GNUG__)
11423result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
11424#elif defined(__HP_cc) || defined(__HP_aCC)
11425result["compiler"] = "hp"
11426#elif defined(__IBMCPP__)
11427result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
11428#elif defined(_MSC_VER)
11429result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
11430#elif defined(__PGI)
11431result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
11432#elif defined(__SUNPRO_CC)
11433result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
11434#else
11435result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
11436#endif
11437
11438#ifdef __cplusplus
11439result["compiler"]["c++"] = std::to_string(__cplusplus);
11440#else
11441result["compiler"]["c++"] = "unknown";
11442#endif
11443return result;
11444}
11445
11446
11447///////////////////////////
11448// JSON value data types //
11449///////////////////////////
11450
11451/// @name JSON value data types
11452/// The data types to store a JSON value. These types are derived from
11453/// the template arguments passed to class @ref basic_json.
11454/// @{
11455
11456#if defined(JSON_HAS_CPP_14)
11457// Use transparent comparator if possible, combined with perfect forwarding
11458// on find() and count() calls prevents unnecessary string construction.
11459using object_comparator_t = std::less<>;
11460#else
11461using object_comparator_t = std::less<StringType>;
11462#endif
11463
11464/*!
11465 @brief a type for an object
11466
11467 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
11468 > An object is an unordered collection of zero or more name/value pairs,
11469 > where a name is a string and a value is a string, number, boolean, null,
11470 > object, or array.
11471
11472 To store objects in C++, a type is defined by the template parameters
11473 described below.
11474
11475 @tparam ObjectType the container to store objects (e.g., `std::map` or
11476 `std::unordered_map`)
11477 @tparam StringType the type of the keys or names (e.g., `std::string`).
11478 The comparison function `std::less<StringType>` is used to order elements
11479 inside the container.
11480 @tparam AllocatorType the allocator to use for objects (e.g.,
11481 `std::allocator`)
11482
11483 #### Default type
11484
11485 With the default values for @a ObjectType (`std::map`), @a StringType
11486 (`std::string`), and @a AllocatorType (`std::allocator`), the default
11487 value for @a object_t is:
11488
11489 @code {.cpp}
11490 std::map<
11491 std::string, // key_type
11492 basic_json, // value_type
11493 std::less<std::string>, // key_compare
11494 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
11495 >
11496 @endcode
11497
11498 #### Behavior
11499
11500 The choice of @a object_t influences the behavior of the JSON class. With
11501 the default type, objects have the following behavior:
11502
11503 - When all names are unique, objects will be interoperable in the sense
11504 that all software implementations receiving that object will agree on
11505 the name-value mappings.
11506 - When the names within an object are not unique, it is unspecified which
11507 one of the values for a given key will be chosen. For instance,
11508 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
11509 `{"key": 2}`.
11510 - Internally, name/value pairs are stored in lexicographical order of the
11511 names. Objects will also be serialized (see @ref dump) in this order.
11512 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
11513 and serialized as `{"a": 2, "b": 1}`.
11514 - When comparing objects, the order of the name/value pairs is irrelevant.
11515 This makes objects interoperable in the sense that they will not be
11516 affected by these differences. For instance, `{"b": 1, "a": 2}` and
11517 `{"a": 2, "b": 1}` will be treated as equal.
11518
11519 #### Limits
11520
11521 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11522 > An implementation may set limits on the maximum depth of nesting.
11523
11524 In this class, the object's limit of nesting is not explicitly constrained.
11525 However, a maximum depth of nesting may be introduced by the compiler or
11526 runtime environment. A theoretical limit can be queried by calling the
11527 @ref max_size function of a JSON object.
11528
11529 #### Storage
11530
11531 Objects are stored as pointers in a @ref basic_json type. That is, for any
11532 access to object values, a pointer of type `object_t*` must be
11533 dereferenced.
11534
11535 @sa @ref array_t -- type for an array value
11536
11537 @since version 1.0.0
11538
11539 @note The order name/value pairs are added to the object is *not*
11540 preserved by the library. Therefore, iterating an object may return
11541 name/value pairs in a different order than they were originally stored. In
11542 fact, keys will be traversed in alphabetical order as `std::map` with
11543 `std::less` is used by default. Please note this behavior conforms to [RFC
11544 7159](http://rfc7159.net/rfc7159), because any order implements the
11545 specified "unordered" nature of JSON objects.
11546 */
11547using object_t = ObjectType<StringType,
11548basic_json,
11549object_comparator_t,
11550AllocatorType<std::pair<const StringType,
11551basic_json>>>;
11552
11553/*!
11554 @brief a type for an array
11555
11556 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
11557 > An array is an ordered sequence of zero or more values.
11558
11559 To store objects in C++, a type is defined by the template parameters
11560 explained below.
11561
11562 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
11563 `std::list`)
11564 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
11565
11566 #### Default type
11567
11568 With the default values for @a ArrayType (`std::vector`) and @a
11569 AllocatorType (`std::allocator`), the default value for @a array_t is:
11570
11571 @code {.cpp}
11572 std::vector<
11573 basic_json, // value_type
11574 std::allocator<basic_json> // allocator_type
11575 >
11576 @endcode
11577
11578 #### Limits
11579
11580 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11581 > An implementation may set limits on the maximum depth of nesting.
11582
11583 In this class, the array's limit of nesting is not explicitly constrained.
11584 However, a maximum depth of nesting may be introduced by the compiler or
11585 runtime environment. A theoretical limit can be queried by calling the
11586 @ref max_size function of a JSON array.
11587
11588 #### Storage
11589
11590 Arrays are stored as pointers in a @ref basic_json type. That is, for any
11591 access to array values, a pointer of type `array_t*` must be dereferenced.
11592
11593 @sa @ref object_t -- type for an object value
11594
11595 @since version 1.0.0
11596 */
11597using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
11598
11599/*!
11600 @brief a type for a string
11601
11602 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
11603 > A string is a sequence of zero or more Unicode characters.
11604
11605 To store objects in C++, a type is defined by the template parameter
11606 described below. Unicode values are split by the JSON class into
11607 byte-sized characters during deserialization.
11608
11609 @tparam StringType the container to store strings (e.g., `std::string`).
11610 Note this container is used for keys/names in objects, see @ref object_t.
11611
11612 #### Default type
11613
11614 With the default values for @a StringType (`std::string`), the default
11615 value for @a string_t is:
11616
11617 @code {.cpp}
11618 std::string
11619 @endcode
11620
11621 #### Encoding
11622
11623 Strings are stored in UTF-8 encoding. Therefore, functions like
11624 `std::string::size()` or `std::string::length()` return the number of
11625 bytes in the string rather than the number of characters or glyphs.
11626
11627 #### String comparison
11628
11629 [RFC 7159](http://rfc7159.net/rfc7159) states:
11630 > Software implementations are typically required to test names of object
11631 > members for equality. Implementations that transform the textual
11632 > representation into sequences of Unicode code units and then perform the
11633 > comparison numerically, code unit by code unit, are interoperable in the
11634 > sense that implementations will agree in all cases on equality or
11635 > inequality of two strings. For example, implementations that compare
11636 > strings with escaped characters unconverted may incorrectly find that
11637 > `"a\\b"` and `"a\u005Cb"` are not equal.
11638
11639 This implementation is interoperable as it does compare strings code unit
11640 by code unit.
11641
11642 #### Storage
11643
11644 String values are stored as pointers in a @ref basic_json type. That is,
11645 for any access to string values, a pointer of type `string_t*` must be
11646 dereferenced.
11647
11648 @since version 1.0.0
11649 */
11650using string_t = StringType;
11651
11652/*!
11653 @brief a type for a boolean
11654
11655 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
11656 type which differentiates the two literals `true` and `false`.
11657
11658 To store objects in C++, a type is defined by the template parameter @a
11659 BooleanType which chooses the type to use.
11660
11661 #### Default type
11662
11663 With the default values for @a BooleanType (`bool`), the default value for
11664 @a boolean_t is:
11665
11666 @code {.cpp}
11667 bool
11668 @endcode
11669
11670 #### Storage
11671
11672 Boolean values are stored directly inside a @ref basic_json type.
11673
11674 @since version 1.0.0
11675 */
11676using boolean_t = BooleanType;
11677
11678/*!
11679 @brief a type for a number (integer)
11680
11681 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11682 > The representation of numbers is similar to that used in most
11683 > programming languages. A number is represented in base 10 using decimal
11684 > digits. It contains an integer component that may be prefixed with an
11685 > optional minus sign, which may be followed by a fraction part and/or an
11686 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11687 > cannot be represented in the grammar below (such as Infinity and NaN)
11688 > are not permitted.
11689
11690 This description includes both integer and floating-point numbers.
11691 However, C++ allows more precise storage if it is known whether the number
11692 is a signed integer, an unsigned integer or a floating-point number.
11693 Therefore, three different types, @ref number_integer_t, @ref
11694 number_unsigned_t and @ref number_float_t are used.
11695
11696 To store integer numbers in C++, a type is defined by the template
11697 parameter @a NumberIntegerType which chooses the type to use.
11698
11699 #### Default type
11700
11701 With the default values for @a NumberIntegerType (`int64_t`), the default
11702 value for @a number_integer_t is:
11703
11704 @code {.cpp}
11705 int64_t
11706 @endcode
11707
11708 #### Default behavior
11709
11710 - The restrictions about leading zeros is not enforced in C++. Instead,
11711 leading zeros in integer literals lead to an interpretation as octal
11712 number. Internally, the value will be stored as decimal number. For
11713 instance, the C++ integer literal `010` will be serialized to `8`.
11714 During deserialization, leading zeros yield an error.
11715 - Not-a-number (NaN) values will be serialized to `null`.
11716
11717 #### Limits
11718
11719 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11720 > An implementation may set limits on the range and precision of numbers.
11721
11722 When the default type is used, the maximal integer number that can be
11723 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
11724 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
11725 that are out of range will yield over/underflow when used in a
11726 constructor. During deserialization, too large or small integer numbers
11727 will be automatically be stored as @ref number_unsigned_t or @ref
11728 number_float_t.
11729
11730 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11731 > Note that when such software is used, numbers that are integers and are
11732 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11733 > that implementations will agree exactly on their numeric values.
11734
11735 As this range is a subrange of the exactly supported range [INT64_MIN,
11736 INT64_MAX], this class's integer type is interoperable.
11737
11738 #### Storage
11739
11740 Integer number values are stored directly inside a @ref basic_json type.
11741
11742 @sa @ref number_float_t -- type for number values (floating-point)
11743
11744 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11745
11746 @since version 1.0.0
11747 */
11748using number_integer_t = NumberIntegerType;
11749
11750/*!
11751 @brief a type for a number (unsigned)
11752
11753 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11754 > The representation of numbers is similar to that used in most
11755 > programming languages. A number is represented in base 10 using decimal
11756 > digits. It contains an integer component that may be prefixed with an
11757 > optional minus sign, which may be followed by a fraction part and/or an
11758 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11759 > cannot be represented in the grammar below (such as Infinity and NaN)
11760 > are not permitted.
11761
11762 This description includes both integer and floating-point numbers.
11763 However, C++ allows more precise storage if it is known whether the number
11764 is a signed integer, an unsigned integer or a floating-point number.
11765 Therefore, three different types, @ref number_integer_t, @ref
11766 number_unsigned_t and @ref number_float_t are used.
11767
11768 To store unsigned integer numbers in C++, a type is defined by the
11769 template parameter @a NumberUnsignedType which chooses the type to use.
11770
11771 #### Default type
11772
11773 With the default values for @a NumberUnsignedType (`uint64_t`), the
11774 default value for @a number_unsigned_t is:
11775
11776 @code {.cpp}
11777 uint64_t
11778 @endcode
11779
11780 #### Default behavior
11781
11782 - The restrictions about leading zeros is not enforced in C++. Instead,
11783 leading zeros in integer literals lead to an interpretation as octal
11784 number. Internally, the value will be stored as decimal number. For
11785 instance, the C++ integer literal `010` will be serialized to `8`.
11786 During deserialization, leading zeros yield an error.
11787 - Not-a-number (NaN) values will be serialized to `null`.
11788
11789 #### Limits
11790
11791 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
11792 > An implementation may set limits on the range and precision of numbers.
11793
11794 When the default type is used, the maximal integer number that can be
11795 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
11796 number that can be stored is `0`. Integer numbers that are out of range
11797 will yield over/underflow when used in a constructor. During
11798 deserialization, too large or small integer numbers will be automatically
11799 be stored as @ref number_integer_t or @ref number_float_t.
11800
11801 [RFC 7159](http://rfc7159.net/rfc7159) further states:
11802 > Note that when such software is used, numbers that are integers and are
11803 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
11804 > that implementations will agree exactly on their numeric values.
11805
11806 As this range is a subrange (when considered in conjunction with the
11807 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
11808 this class's integer type is interoperable.
11809
11810 #### Storage
11811
11812 Integer number values are stored directly inside a @ref basic_json type.
11813
11814 @sa @ref number_float_t -- type for number values (floating-point)
11815 @sa @ref number_integer_t -- type for number values (integer)
11816
11817 @since version 2.0.0
11818 */
11819using number_unsigned_t = NumberUnsignedType;
11820
11821/*!
11822 @brief a type for a number (floating-point)
11823
11824 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
11825 > The representation of numbers is similar to that used in most
11826 > programming languages. A number is represented in base 10 using decimal
11827 > digits. It contains an integer component that may be prefixed with an
11828 > optional minus sign, which may be followed by a fraction part and/or an
11829 > exponent part. Leading zeros are not allowed. (...) Numeric values that
11830 > cannot be represented in the grammar below (such as Infinity and NaN)
11831 > are not permitted.
11832
11833 This description includes both integer and floating-point numbers.
11834 However, C++ allows more precise storage if it is known whether the number
11835 is a signed integer, an unsigned integer or a floating-point number.
11836 Therefore, three different types, @ref number_integer_t, @ref
11837 number_unsigned_t and @ref number_float_t are used.
11838
11839 To store floating-point numbers in C++, a type is defined by the template
11840 parameter @a NumberFloatType which chooses the type to use.
11841
11842 #### Default type
11843
11844 With the default values for @a NumberFloatType (`double`), the default
11845 value for @a number_float_t is:
11846
11847 @code {.cpp}
11848 double
11849 @endcode
11850
11851 #### Default behavior
11852
11853 - The restrictions about leading zeros is not enforced in C++. Instead,
11854 leading zeros in floating-point literals will be ignored. Internally,
11855 the value will be stored as decimal number. For instance, the C++
11856 floating-point literal `01.2` will be serialized to `1.2`. During
11857 deserialization, leading zeros yield an error.
11858 - Not-a-number (NaN) values will be serialized to `null`.
11859
11860 #### Limits
11861
11862 [RFC 7159](http://rfc7159.net/rfc7159) states:
11863 > This specification allows implementations to set limits on the range and
11864 > precision of numbers accepted. Since software that implements IEEE
11865 > 754-2008 binary64 (double precision) numbers is generally available and
11866 > widely used, good interoperability can be achieved by implementations
11867 > that expect no more precision or range than these provide, in the sense
11868 > that implementations will approximate JSON numbers within the expected
11869 > precision.
11870
11871 This implementation does exactly follow this approach, as it uses double
11872 precision floating-point numbers. Note values smaller than
11873 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
11874 will be stored as NaN internally and be serialized to `null`.
11875
11876 #### Storage
11877
11878 Floating-point number values are stored directly inside a @ref basic_json
11879 type.
11880
11881 @sa @ref number_integer_t -- type for number values (integer)
11882
11883 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
11884
11885 @since version 1.0.0
11886 */
11887using number_float_t = NumberFloatType;
11888
11889/// @}
11890
11891private:
11892
11893/// helper for exception-safe object creation
11894template<typename T, typename... Args>
11895static T* create(Args&& ... args)
11896{
11897AllocatorType<T> alloc;
11898using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
11899
11900auto deleter = [&](T * object)
11901{
11902AllocatorTraits::deallocate(alloc, object, 1);
11903};
11904std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
11905AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
11906assert(object != nullptr);
11907return object.release();
11908}
11909
11910////////////////////////
11911// JSON value storage //
11912////////////////////////
11913
11914/*!
11915 @brief a JSON value
11916
11917 The actual storage for a JSON value of the @ref basic_json class. This
11918 union combines the different storage types for the JSON value types
11919 defined in @ref value_t.
11920
11921 JSON type | value_t type | used type
11922 --------- | --------------- | ------------------------
11923 object | object | pointer to @ref object_t
11924 array | array | pointer to @ref array_t
11925 string | string | pointer to @ref string_t
11926 boolean | boolean | @ref boolean_t
11927 number | number_integer | @ref number_integer_t
11928 number | number_unsigned | @ref number_unsigned_t
11929 number | number_float | @ref number_float_t
11930 null | null | *no value is stored*
11931
11932 @note Variable-length types (objects, arrays, and strings) are stored as
11933 pointers. The size of the union should not exceed 64 bits if the default
11934 value types are used.
11935
11936 @since version 1.0.0
11937 */
11938union json_value
11939{
11940/// object (stored with pointer to save storage)
11941object_t* object;
11942/// array (stored with pointer to save storage)
11943array_t* array;
11944/// string (stored with pointer to save storage)
11945string_t* string;
11946/// boolean
11947boolean_t boolean;
11948/// number (integer)
11949number_integer_t number_integer;
11950/// number (unsigned integer)
11951number_unsigned_t number_unsigned;
11952/// number (floating-point)
11953number_float_t number_float;
11954
11955/// default constructor (for null values)
11956json_value() = default;
11957/// constructor for booleans
11958json_value(boolean_t v) noexcept : boolean(v) {}
11959/// constructor for numbers (integer)
11960json_value(number_integer_t v) noexcept : number_integer(v) {}
11961/// constructor for numbers (unsigned)
11962json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
11963/// constructor for numbers (floating-point)
11964json_value(number_float_t v) noexcept : number_float(v) {}
11965/// constructor for empty values of a given type
11966json_value(value_t t)
11967{
11968switch (t)
11969{
11970case value_t::object:
11971{
11972object = create<object_t>();
11973break;
11974}
11975
11976case value_t::array:
11977{
11978array = create<array_t>();
11979break;
11980}
11981
11982case value_t::string:
11983{
11984string = create<string_t>("");
11985break;
11986}
11987
11988case value_t::boolean:
11989{
11990boolean = boolean_t(false);
11991break;
11992}
11993
11994case value_t::number_integer:
11995{
11996number_integer = number_integer_t(0);
11997break;
11998}
11999
12000case value_t::number_unsigned:
12001{
12002number_unsigned = number_unsigned_t(0);
12003break;
12004}
12005
12006case value_t::number_float:
12007{
12008number_float = number_float_t(0.0);
12009break;
12010}
12011
12012case value_t::null:
12013{
12014object = nullptr; // silence warning, see #821
12015break;
12016}
12017
12018default:
12019{
12020object = nullptr; // silence warning, see #821
12021if (JSON_UNLIKELY(t == value_t::null))
12022{
12023JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.2.0")); // LCOV_EXCL_LINE
12024}
12025break;
12026}
12027}
12028}
12029
12030/// constructor for strings
12031json_value(const string_t& value)
12032{
12033string = create<string_t>(value);
12034}
12035
12036/// constructor for rvalue strings
12037json_value(string_t&& value)
12038{
12039string = create<string_t>(std::move(value));
12040}
12041
12042/// constructor for objects
12043json_value(const object_t& value)
12044{
12045object = create<object_t>(value);
12046}
12047
12048/// constructor for rvalue objects
12049json_value(object_t&& value)
12050{
12051object = create<object_t>(std::move(value));
12052}
12053
12054/// constructor for arrays
12055json_value(const array_t& value)
12056{
12057array = create<array_t>(value);
12058}
12059
12060/// constructor for rvalue arrays
12061json_value(array_t&& value)
12062{
12063array = create<array_t>(std::move(value));
12064}
12065
12066void destroy(value_t t) noexcept
12067{
12068switch (t)
12069{
12070case value_t::object:
12071{
12072AllocatorType<object_t> alloc;
12073std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
12074std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
12075break;
12076}
12077
12078case value_t::array:
12079{
12080AllocatorType<array_t> alloc;
12081std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
12082std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
12083break;
12084}
12085
12086case value_t::string:
12087{
12088AllocatorType<string_t> alloc;
12089std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
12090std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
12091break;
12092}
12093
12094default:
12095{
12096break;
12097}
12098}
12099}
12100};
12101
12102/*!
12103 @brief checks the class invariants
12104
12105 This function asserts the class invariants. It needs to be called at the
12106 end of every constructor to make sure that created objects respect the
12107 invariant. Furthermore, it has to be called each time the type of a JSON
12108 value is changed, because the invariant expresses a relationship between
12109 @a m_type and @a m_value.
12110 */
12111void assert_invariant() const noexcept
12112{
12113assert(m_type != value_t::object or m_value.object != nullptr);
12114assert(m_type != value_t::array or m_value.array != nullptr);
12115assert(m_type != value_t::string or m_value.string != nullptr);
12116}
12117
12118public:
12119//////////////////////////
12120// JSON parser callback //
12121//////////////////////////
12122
12123/*!
12124 @brief parser event types
12125
12126 The parser callback distinguishes the following events:
12127 - `object_start`: the parser read `{` and started to process a JSON object
12128 - `key`: the parser read a key of a value in an object
12129 - `object_end`: the parser read `}` and finished processing a JSON object
12130 - `array_start`: the parser read `[` and started to process a JSON array
12131 - `array_end`: the parser read `]` and finished processing a JSON array
12132 - `value`: the parser finished reading a JSON value
12133
12134 @image html callback_events.png "Example when certain parse events are triggered"
12135
12136 @sa @ref parser_callback_t for more information and examples
12137 */
12138using parse_event_t = typename parser::parse_event_t;
12139
12140/*!
12141 @brief per-element parser callback type
12142
12143 With a parser callback function, the result of parsing a JSON text can be
12144 influenced. When passed to @ref parse, it is called on certain events
12145 (passed as @ref parse_event_t via parameter @a event) with a set recursion
12146 depth @a depth and context JSON value @a parsed. The return value of the
12147 callback function is a boolean indicating whether the element that emitted
12148 the callback shall be kept or not.
12149
12150 We distinguish six scenarios (determined by the event type) in which the
12151 callback function can be called. The following table describes the values
12152 of the parameters @a depth, @a event, and @a parsed.
12153
12154 parameter @a event | description | parameter @a depth | parameter @a parsed
12155 ------------------ | ----------- | ------------------ | -------------------
12156 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
12157 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
12158 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
12159 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
12160 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
12161 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
12162
12163 @image html callback_events.png "Example when certain parse events are triggered"
12164
12165 Discarding a value (i.e., returning `false`) has different effects
12166 depending on the context in which function was called:
12167
12168 - Discarded values in structured types are skipped. That is, the parser
12169 will behave as if the discarded value was never read.
12170 - In case a value outside a structured type is skipped, it is replaced
12171 with `null`. This case happens if the top-level element is skipped.
12172
12173 @param[in] depth the depth of the recursion during parsing
12174
12175 @param[in] event an event of type parse_event_t indicating the context in
12176 the callback function has been called
12177
12178 @param[in,out] parsed the current intermediate parse result; note that
12179 writing to this value has no effect for parse_event_t::key events
12180
12181 @return Whether the JSON value which called the function during parsing
12182 should be kept (`true`) or not (`false`). In the latter case, it is either
12183 skipped completely or replaced by an empty discarded object.
12184
12185 @sa @ref parse for examples
12186
12187 @since version 1.0.0
12188 */
12189using parser_callback_t = typename parser::parser_callback_t;
12190
12191//////////////////
12192// constructors //
12193//////////////////
12194
12195/// @name constructors and destructors
12196/// Constructors of class @ref basic_json, copy/move constructor, copy
12197/// assignment, static functions creating objects, and the destructor.
12198/// @{
12199
12200/*!
12201 @brief create an empty value with a given type
12202
12203 Create an empty JSON value with a given type. The value will be default
12204 initialized with an empty value which depends on the type:
12205
12206 Value type | initial value
12207 ----------- | -------------
12208 null | `null`
12209 boolean | `false`
12210 string | `""`
12211 number | `0`
12212 object | `{}`
12213 array | `[]`
12214
12215 @param[in] v the type of the value to create
12216
12217 @complexity Constant.
12218
12219 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12220 changes to any JSON value.
12221
12222 @liveexample{The following code shows the constructor for different @ref
12223 value_t values,basic_json__value_t}
12224
12225 @sa @ref clear() -- restores the postcondition of this constructor
12226
12227 @since version 1.0.0
12228 */
12229basic_json(const value_t v)
12230: m_type(v), m_value(v)
12231{
12232assert_invariant();
12233}
12234
12235/*!
12236 @brief create a null object
12237
12238 Create a `null` JSON value. It either takes a null pointer as parameter
12239 (explicitly creating `null`) or no parameter (implicitly creating `null`).
12240 The passed null pointer itself is not read -- it is only used to choose
12241 the right constructor.
12242
12243 @complexity Constant.
12244
12245 @exceptionsafety No-throw guarantee: this constructor never throws
12246 exceptions.
12247
12248 @liveexample{The following code shows the constructor with and without a
12249 null pointer parameter.,basic_json__nullptr_t}
12250
12251 @since version 1.0.0
12252 */
12253basic_json(std::nullptr_t = nullptr) noexcept
12254: basic_json(value_t::null)
12255{
12256assert_invariant();
12257}
12258
12259/*!
12260 @brief create a JSON value
12261
12262 This is a "catch all" constructor for all compatible JSON types; that is,
12263 types for which a `to_json()` method exists. The constructor forwards the
12264 parameter @a val to that method (to `json_serializer<U>::to_json` method
12265 with `U = uncvref_t<CompatibleType>`, to be exact).
12266
12267 Template type @a CompatibleType includes, but is not limited to, the
12268 following types:
12269 - **arrays**: @ref array_t and all kinds of compatible containers such as
12270 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
12271 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
12272 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
12273 which a @ref basic_json value can be constructed.
12274 - **objects**: @ref object_t and all kinds of compatible associative
12275 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
12276 and `std::unordered_multimap` with a `key_type` compatible to
12277 @ref string_t and a `value_type` from which a @ref basic_json value can
12278 be constructed.
12279 - **strings**: @ref string_t, string literals, and all compatible string
12280 containers can be used.
12281 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
12282 @ref number_float_t, and all convertible number types such as `int`,
12283 `size_t`, `int64_t`, `float` or `double` can be used.
12284 - **boolean**: @ref boolean_t / `bool` can be used.
12285
12286 See the examples below.
12287
12288 @tparam CompatibleType a type such that:
12289 - @a CompatibleType is not derived from `std::istream`,
12290 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
12291 constructors),
12292 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
12293 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
12294 @ref json_pointer, @ref iterator, etc ...)
12295 - @ref @ref json_serializer<U> has a
12296 `to_json(basic_json_t&, CompatibleType&&)` method
12297
12298 @tparam U = `uncvref_t<CompatibleType>`
12299
12300 @param[in] val the value to be forwarded to the respective constructor
12301
12302 @complexity Usually linear in the size of the passed @a val, also
12303 depending on the implementation of the called `to_json()`
12304 method.
12305
12306 @exceptionsafety Depends on the called constructor. For types directly
12307 supported by the library (i.e., all types for which no `to_json()` function
12308 was provided), strong guarantee holds: if an exception is thrown, there are
12309 no changes to any JSON value.
12310
12311 @liveexample{The following code shows the constructor with several
12312 compatible types.,basic_json__CompatibleType}
12313
12314 @since version 2.1.0
12315 */
12316template <typename CompatibleType,
12317typename U = detail::uncvref_t<CompatibleType>,
12318detail::enable_if_t<
12319not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
12320basic_json(CompatibleType && val) noexcept(noexcept(
12321JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
12322std::forward<CompatibleType>(val))))
12323{
12324JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
12325assert_invariant();
12326}
12327
12328/*!
12329 @brief create a JSON value from an existing one
12330
12331 This is a constructor for existing @ref basic_json types.
12332 It does not hijack copy/move constructors, since the parameter has different
12333 template arguments than the current ones.
12334
12335 The constructor tries to convert the internal @ref m_value of the parameter.
12336
12337 @tparam BasicJsonType a type such that:
12338 - @a BasicJsonType is a @ref basic_json type.
12339 - @a BasicJsonType has different template arguments than @ref basic_json_t.
12340
12341 @param[in] val the @ref basic_json value to be converted.
12342
12343 @complexity Usually linear in the size of the passed @a val, also
12344 depending on the implementation of the called `to_json()`
12345 method.
12346
12347 @exceptionsafety Depends on the called constructor. For types directly
12348 supported by the library (i.e., all types for which no `to_json()` function
12349 was provided), strong guarantee holds: if an exception is thrown, there are
12350 no changes to any JSON value.
12351
12352 @since version 3.2.0
12353 */
12354template <typename BasicJsonType,
12355detail::enable_if_t<
12356detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
12357basic_json(const BasicJsonType& val)
12358{
12359using other_boolean_t = typename BasicJsonType::boolean_t;
12360using other_number_float_t = typename BasicJsonType::number_float_t;
12361using other_number_integer_t = typename BasicJsonType::number_integer_t;
12362using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12363using other_string_t = typename BasicJsonType::string_t;
12364using other_object_t = typename BasicJsonType::object_t;
12365using other_array_t = typename BasicJsonType::array_t;
12366
12367switch (val.type())
12368{
12369case value_t::boolean:
12370JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
12371break;
12372case value_t::number_float:
12373JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
12374break;
12375case value_t::number_integer:
12376JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
12377break;
12378case value_t::number_unsigned:
12379JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
12380break;
12381case value_t::string:
12382JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
12383break;
12384case value_t::object:
12385JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
12386break;
12387case value_t::array:
12388JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
12389break;
12390case value_t::null:
12391*this = nullptr;
12392break;
12393case value_t::discarded:
12394m_type = value_t::discarded;
12395break;
12396}
12397assert_invariant();
12398}
12399
12400/*!
12401 @brief create a container (array or object) from an initializer list
12402
12403 Creates a JSON value of type array or object from the passed initializer
12404 list @a init. In case @a type_deduction is `true` (default), the type of
12405 the JSON value to be created is deducted from the initializer list @a init
12406 according to the following rules:
12407
12408 1. If the list is empty, an empty JSON object value `{}` is created.
12409 2. If the list consists of pairs whose first element is a string, a JSON
12410 object value is created where the first elements of the pairs are
12411 treated as keys and the second elements are as values.
12412 3. In all other cases, an array is created.
12413
12414 The rules aim to create the best fit between a C++ initializer list and
12415 JSON values. The rationale is as follows:
12416
12417 1. The empty initializer list is written as `{}` which is exactly an empty
12418 JSON object.
12419 2. C++ has no way of describing mapped types other than to list a list of
12420 pairs. As JSON requires that keys must be of type string, rule 2 is the
12421 weakest constraint one can pose on initializer lists to interpret them
12422 as an object.
12423 3. In all other cases, the initializer list could not be interpreted as
12424 JSON object type, so interpreting it as JSON array type is safe.
12425
12426 With the rules described above, the following JSON values cannot be
12427 expressed by an initializer list:
12428
12429 - the empty array (`[]`): use @ref array(initializer_list_t)
12430 with an empty initializer list in this case
12431 - arrays whose elements satisfy rule 2: use @ref
12432 array(initializer_list_t) with the same initializer list
12433 in this case
12434
12435 @note When used without parentheses around an empty initializer list, @ref
12436 basic_json() is called instead of this function, yielding the JSON null
12437 value.
12438
12439 @param[in] init initializer list with JSON values
12440
12441 @param[in] type_deduction internal parameter; when set to `true`, the type
12442 of the JSON value is deducted from the initializer list @a init; when set
12443 to `false`, the type provided via @a manual_type is forced. This mode is
12444 used by the functions @ref array(initializer_list_t) and
12445 @ref object(initializer_list_t).
12446
12447 @param[in] manual_type internal parameter; when @a type_deduction is set
12448 to `false`, the created JSON value will use the provided type (only @ref
12449 value_t::array and @ref value_t::object are valid); when @a type_deduction
12450 is set to `true`, this parameter has no effect
12451
12452 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
12453 `value_t::object`, but @a init contains an element which is not a pair
12454 whose first element is a string. In this case, the constructor could not
12455 create an object. If @a type_deduction would have be `true`, an array
12456 would have been created. See @ref object(initializer_list_t)
12457 for an example.
12458
12459 @complexity Linear in the size of the initializer list @a init.
12460
12461 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12462 changes to any JSON value.
12463
12464 @liveexample{The example below shows how JSON values are created from
12465 initializer lists.,basic_json__list_init_t}
12466
12467 @sa @ref array(initializer_list_t) -- create a JSON array
12468 value from an initializer list
12469 @sa @ref object(initializer_list_t) -- create a JSON object
12470 value from an initializer list
12471
12472 @since version 1.0.0
12473 */
12474basic_json(initializer_list_t init,
12475bool type_deduction = true,
12476value_t manual_type = value_t::array)
12477{
12478// check if each element is an array with two elements whose first
12479// element is a string
12480bool is_an_object = std::all_of(init.begin(), init.end(),
12481[](const detail::json_ref<basic_json>& element_ref)
12482{
12483return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
12484});
12485
12486// adjust type if type deduction is not wanted
12487if (not type_deduction)
12488{
12489// if array is wanted, do not create an object though possible
12490if (manual_type == value_t::array)
12491{
12492is_an_object = false;
12493}
12494
12495// if object is wanted but impossible, throw an exception
12496if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
12497{
12498JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
12499}
12500}
12501
12502if (is_an_object)
12503{
12504// the initializer list is a list of pairs -> create object
12505m_type = value_t::object;
12506m_value = value_t::object;
12507
12508std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
12509{
12510auto element = element_ref.moved_or_copied();
12511m_value.object->emplace(
12512std::move(*((*element.m_value.array)[0].m_value.string)),
12513std::move((*element.m_value.array)[1]));
12514});
12515}
12516else
12517{
12518// the initializer list describes an array -> create array
12519m_type = value_t::array;
12520m_value.array = create<array_t>(init.begin(), init.end());
12521}
12522
12523assert_invariant();
12524}
12525
12526/*!
12527 @brief explicitly create an array from an initializer list
12528
12529 Creates a JSON array value from a given initializer list. That is, given a
12530 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
12531 initializer list is empty, the empty array `[]` is created.
12532
12533 @note This function is only needed to express two edge cases that cannot
12534 be realized with the initializer list constructor (@ref
12535 basic_json(initializer_list_t, bool, value_t)). These cases
12536 are:
12537 1. creating an array whose elements are all pairs whose first element is a
12538 string -- in this case, the initializer list constructor would create an
12539 object, taking the first elements as keys
12540 2. creating an empty array -- passing the empty initializer list to the
12541 initializer list constructor yields an empty object
12542
12543 @param[in] init initializer list with JSON values to create an array from
12544 (optional)
12545
12546 @return JSON array value
12547
12548 @complexity Linear in the size of @a init.
12549
12550 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12551 changes to any JSON value.
12552
12553 @liveexample{The following code shows an example for the `array`
12554 function.,array}
12555
12556 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12557 create a JSON value from an initializer list
12558 @sa @ref object(initializer_list_t) -- create a JSON object
12559 value from an initializer list
12560
12561 @since version 1.0.0
12562 */
12563static basic_json array(initializer_list_t init = {})
12564{
12565return basic_json(init, false, value_t::array);
12566}
12567
12568/*!
12569 @brief explicitly create an object from an initializer list
12570
12571 Creates a JSON object value from a given initializer list. The initializer
12572 lists elements must be pairs, and their first elements must be strings. If
12573 the initializer list is empty, the empty object `{}` is created.
12574
12575 @note This function is only added for symmetry reasons. In contrast to the
12576 related function @ref array(initializer_list_t), there are
12577 no cases which can only be expressed by this function. That is, any
12578 initializer list @a init can also be passed to the initializer list
12579 constructor @ref basic_json(initializer_list_t, bool, value_t).
12580
12581 @param[in] init initializer list to create an object from (optional)
12582
12583 @return JSON object value
12584
12585 @throw type_error.301 if @a init is not a list of pairs whose first
12586 elements are strings. In this case, no object can be created. When such a
12587 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
12588 an array would have been created from the passed initializer list @a init.
12589 See example below.
12590
12591 @complexity Linear in the size of @a init.
12592
12593 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12594 changes to any JSON value.
12595
12596 @liveexample{The following code shows an example for the `object`
12597 function.,object}
12598
12599 @sa @ref basic_json(initializer_list_t, bool, value_t) --
12600 create a JSON value from an initializer list
12601 @sa @ref array(initializer_list_t) -- create a JSON array
12602 value from an initializer list
12603
12604 @since version 1.0.0
12605 */
12606static basic_json object(initializer_list_t init = {})
12607{
12608return basic_json(init, false, value_t::object);
12609}
12610
12611/*!
12612 @brief construct an array with count copies of given value
12613
12614 Constructs a JSON array value by creating @a cnt copies of a passed value.
12615 In case @a cnt is `0`, an empty array is created.
12616
12617 @param[in] cnt the number of JSON copies of @a val to create
12618 @param[in] val the JSON value to copy
12619
12620 @post `std::distance(begin(),end()) == cnt` holds.
12621
12622 @complexity Linear in @a cnt.
12623
12624 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12625 changes to any JSON value.
12626
12627 @liveexample{The following code shows examples for the @ref
12628 basic_json(size_type\, const basic_json&)
12629 constructor.,basic_json__size_type_basic_json}
12630
12631 @since version 1.0.0
12632 */
12633basic_json(size_type cnt, const basic_json& val)
12634: m_type(value_t::array)
12635{
12636m_value.array = create<array_t>(cnt, val);
12637assert_invariant();
12638}
12639
12640/*!
12641 @brief construct a JSON container given an iterator range
12642
12643 Constructs the JSON value with the contents of the range `[first, last)`.
12644 The semantics depends on the different types a JSON value can have:
12645 - In case of a null type, invalid_iterator.206 is thrown.
12646 - In case of other primitive types (number, boolean, or string), @a first
12647 must be `begin()` and @a last must be `end()`. In this case, the value is
12648 copied. Otherwise, invalid_iterator.204 is thrown.
12649 - In case of structured types (array, object), the constructor behaves as
12650 similar versions for `std::vector` or `std::map`; that is, a JSON array
12651 or object is constructed from the values in the range.
12652
12653 @tparam InputIT an input iterator type (@ref iterator or @ref
12654 const_iterator)
12655
12656 @param[in] first begin of the range to copy from (included)
12657 @param[in] last end of the range to copy from (excluded)
12658
12659 @pre Iterators @a first and @a last must be initialized. **This
12660 precondition is enforced with an assertion (see warning).** If
12661 assertions are switched off, a violation of this precondition yields
12662 undefined behavior.
12663
12664 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
12665 checked efficiently. Only certain edge cases are detected; see the
12666 description of the exceptions below. A violation of this precondition
12667 yields undefined behavior.
12668
12669 @warning A precondition is enforced with a runtime assertion that will
12670 result in calling `std::abort` if this precondition is not met.
12671 Assertions can be disabled by defining `NDEBUG` at compile time.
12672 See https://en.cppreference.com/w/cpp/error/assert for more
12673 information.
12674
12675 @throw invalid_iterator.201 if iterators @a first and @a last are not
12676 compatible (i.e., do not belong to the same JSON value). In this case,
12677 the range `[first, last)` is undefined.
12678 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
12679 primitive type (number, boolean, or string), but @a first does not point
12680 to the first element any more. In this case, the range `[first, last)` is
12681 undefined. See example code below.
12682 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
12683 null value. In this case, the range `[first, last)` is undefined.
12684
12685 @complexity Linear in distance between @a first and @a last.
12686
12687 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12688 changes to any JSON value.
12689
12690 @liveexample{The example below shows several ways to create JSON values by
12691 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
12692
12693 @since version 1.0.0
12694 */
12695template<class InputIT, typename std::enable_if<
12696std::is_same<InputIT, typename basic_json_t::iterator>::value or
12697std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
12698basic_json(InputIT first, InputIT last)
12699{
12700assert(first.m_object != nullptr);
12701assert(last.m_object != nullptr);
12702
12703// make sure iterator fits the current value
12704if (JSON_UNLIKELY(first.m_object != last.m_object))
12705{
12706JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
12707}
12708
12709// copy type from first iterator
12710m_type = first.m_object->m_type;
12711
12712// check if iterator range is complete for primitive values
12713switch (m_type)
12714{
12715case value_t::boolean:
12716case value_t::number_float:
12717case value_t::number_integer:
12718case value_t::number_unsigned:
12719case value_t::string:
12720{
12721if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
12722or not last.m_it.primitive_iterator.is_end()))
12723{
12724JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
12725}
12726break;
12727}
12728
12729default:
12730break;
12731}
12732
12733switch (m_type)
12734{
12735case value_t::number_integer:
12736{
12737m_value.number_integer = first.m_object->m_value.number_integer;
12738break;
12739}
12740
12741case value_t::number_unsigned:
12742{
12743m_value.number_unsigned = first.m_object->m_value.number_unsigned;
12744break;
12745}
12746
12747case value_t::number_float:
12748{
12749m_value.number_float = first.m_object->m_value.number_float;
12750break;
12751}
12752
12753case value_t::boolean:
12754{
12755m_value.boolean = first.m_object->m_value.boolean;
12756break;
12757}
12758
12759case value_t::string:
12760{
12761m_value = *first.m_object->m_value.string;
12762break;
12763}
12764
12765case value_t::object:
12766{
12767m_value.object = create<object_t>(first.m_it.object_iterator,
12768last.m_it.object_iterator);
12769break;
12770}
12771
12772case value_t::array:
12773{
12774m_value.array = create<array_t>(first.m_it.array_iterator,
12775last.m_it.array_iterator);
12776break;
12777}
12778
12779default:
12780JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
12781std::string(first.m_object->type_name())));
12782}
12783
12784assert_invariant();
12785}
12786
12787
12788///////////////////////////////////////
12789// other constructors and destructor //
12790///////////////////////////////////////
12791
12792/// @private
12793basic_json(const detail::json_ref<basic_json>& ref)
12794: basic_json(ref.moved_or_copied())
12795{}
12796
12797/*!
12798 @brief copy constructor
12799
12800 Creates a copy of a given JSON value.
12801
12802 @param[in] other the JSON value to copy
12803
12804 @post `*this == other`
12805
12806 @complexity Linear in the size of @a other.
12807
12808 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12809 changes to any JSON value.
12810
12811 @requirement This function helps `basic_json` satisfying the
12812 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12813 requirements:
12814 - The complexity is linear.
12815 - As postcondition, it holds: `other == basic_json(other)`.
12816
12817 @liveexample{The following code shows an example for the copy
12818 constructor.,basic_json__basic_json}
12819
12820 @since version 1.0.0
12821 */
12822basic_json(const basic_json& other)
12823: m_type(other.m_type)
12824{
12825// check of passed value is valid
12826other.assert_invariant();
12827
12828switch (m_type)
12829{
12830case value_t::object:
12831{
12832m_value = *other.m_value.object;
12833break;
12834}
12835
12836case value_t::array:
12837{
12838m_value = *other.m_value.array;
12839break;
12840}
12841
12842case value_t::string:
12843{
12844m_value = *other.m_value.string;
12845break;
12846}
12847
12848case value_t::boolean:
12849{
12850m_value = other.m_value.boolean;
12851break;
12852}
12853
12854case value_t::number_integer:
12855{
12856m_value = other.m_value.number_integer;
12857break;
12858}
12859
12860case value_t::number_unsigned:
12861{
12862m_value = other.m_value.number_unsigned;
12863break;
12864}
12865
12866case value_t::number_float:
12867{
12868m_value = other.m_value.number_float;
12869break;
12870}
12871
12872default:
12873break;
12874}
12875
12876assert_invariant();
12877}
12878
12879/*!
12880 @brief move constructor
12881
12882 Move constructor. Constructs a JSON value with the contents of the given
12883 value @a other using move semantics. It "steals" the resources from @a
12884 other and leaves it as JSON null value.
12885
12886 @param[in,out] other value to move to this object
12887
12888 @post `*this` has the same value as @a other before the call.
12889 @post @a other is a JSON null value.
12890
12891 @complexity Constant.
12892
12893 @exceptionsafety No-throw guarantee: this constructor never throws
12894 exceptions.
12895
12896 @requirement This function helps `basic_json` satisfying the
12897 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
12898 requirements.
12899
12900 @liveexample{The code below shows the move constructor explicitly called
12901 via std::move.,basic_json__moveconstructor}
12902
12903 @since version 1.0.0
12904 */
12905basic_json(basic_json&& other) noexcept
12906: m_type(std::move(other.m_type)),
12907m_value(std::move(other.m_value))
12908{
12909// check that passed value is valid
12910other.assert_invariant();
12911
12912// invalidate payload
12913other.m_type = value_t::null;
12914other.m_value = {};
12915
12916assert_invariant();
12917}
12918
12919/*!
12920 @brief copy assignment
12921
12922 Copy assignment operator. Copies a JSON value via the "copy and swap"
12923 strategy: It is expressed in terms of the copy constructor, destructor,
12924 and the `swap()` member function.
12925
12926 @param[in] other value to copy from
12927
12928 @complexity Linear.
12929
12930 @requirement This function helps `basic_json` satisfying the
12931 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12932 requirements:
12933 - The complexity is linear.
12934
12935 @liveexample{The code below shows and example for the copy assignment. It
12936 creates a copy of value `a` which is then swapped with `b`. Finally\, the
12937 copy of `a` (which is the null value after the swap) is
12938 destroyed.,basic_json__copyassignment}
12939
12940 @since version 1.0.0
12941 */
12942reference& operator=(basic_json other) noexcept (
12943std::is_nothrow_move_constructible<value_t>::value and
12944std::is_nothrow_move_assignable<value_t>::value and
12945std::is_nothrow_move_constructible<json_value>::value and
12946std::is_nothrow_move_assignable<json_value>::value
12947)
12948{
12949// check that passed value is valid
12950other.assert_invariant();
12951
12952using std::swap;
12953swap(m_type, other.m_type);
12954swap(m_value, other.m_value);
12955
12956assert_invariant();
12957return *this;
12958}
12959
12960/*!
12961 @brief destructor
12962
12963 Destroys the JSON value and frees all allocated memory.
12964
12965 @complexity Linear.
12966
12967 @requirement This function helps `basic_json` satisfying the
12968 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
12969 requirements:
12970 - The complexity is linear.
12971 - All stored elements are destroyed and all memory is freed.
12972
12973 @since version 1.0.0
12974 */
12975~basic_json() noexcept
12976{
12977assert_invariant();
12978m_value.destroy(m_type);
12979}
12980
12981/// @}
12982
12983public:
12984///////////////////////
12985// object inspection //
12986///////////////////////
12987
12988/// @name object inspection
12989/// Functions to inspect the type of a JSON value.
12990/// @{
12991
12992/*!
12993 @brief serialization
12994
12995 Serialization function for JSON values. The function tries to mimic
12996 Python's `json.dumps()` function, and currently supports its @a indent
12997 and @a ensure_ascii parameters.
12998
12999 @param[in] indent If indent is nonnegative, then array elements and object
13000 members will be pretty-printed with that indent level. An indent level of
13001 `0` will only insert newlines. `-1` (the default) selects the most compact
13002 representation.
13003 @param[in] indent_char The character to use for indentation if @a indent is
13004 greater than `0`. The default is ` ` (space).
13005 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
13006 in the output are escaped with `\uXXXX` sequences, and the result consists
13007 of ASCII characters only.
13008
13009 @return string containing the serialization of the JSON value
13010
13011 @throw type_error.316 if a string stored inside the JSON value is not
13012 UTF-8 encoded
13013
13014 @complexity Linear.
13015
13016 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13017 changes in the JSON value.
13018
13019 @liveexample{The following example shows the effect of different @a indent\,
13020 @a indent_char\, and @a ensure_ascii parameters to the result of the
13021 serialization.,dump}
13022
13023 @see https://docs.python.org/2/library/json.html#json.dump
13024
13025 @since version 1.0.0; indentation character @a indent_char, option
13026 @a ensure_ascii and exceptions added in version 3.0.0
13027 */
13028string_t dump(const int indent = -1, const char indent_char = ' ',
13029const bool ensure_ascii = false) const
13030{
13031string_t result;
13032serializer s(detail::output_adapter<char, string_t>(result), indent_char);
13033
13034if (indent >= 0)
13035{
13036s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
13037}
13038else
13039{
13040s.dump(*this, false, ensure_ascii, 0);
13041}
13042
13043return result;
13044}
13045
13046/*!
13047 @brief return the type of the JSON value (explicit)
13048
13049 Return the type of the JSON value as a value from the @ref value_t
13050 enumeration.
13051
13052 @return the type of the JSON value
13053 Value type | return value
13054 ------------------------- | -------------------------
13055 null | value_t::null
13056 boolean | value_t::boolean
13057 string | value_t::string
13058 number (integer) | value_t::number_integer
13059 number (unsigned integer) | value_t::number_unsigned
13060 number (floating-point) | value_t::number_float
13061 object | value_t::object
13062 array | value_t::array
13063 discarded | value_t::discarded
13064
13065 @complexity Constant.
13066
13067 @exceptionsafety No-throw guarantee: this member function never throws
13068 exceptions.
13069
13070 @liveexample{The following code exemplifies `type()` for all JSON
13071 types.,type}
13072
13073 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
13074 @sa @ref type_name() -- return the type as string
13075
13076 @since version 1.0.0
13077 */
13078constexpr value_t type() const noexcept
13079{
13080return m_type;
13081}
13082
13083/*!
13084 @brief return whether type is primitive
13085
13086 This function returns true if and only if the JSON type is primitive
13087 (string, number, boolean, or null).
13088
13089 @return `true` if type is primitive (string, number, boolean, or null),
13090 `false` otherwise.
13091
13092 @complexity Constant.
13093
13094 @exceptionsafety No-throw guarantee: this member function never throws
13095 exceptions.
13096
13097 @liveexample{The following code exemplifies `is_primitive()` for all JSON
13098 types.,is_primitive}
13099
13100 @sa @ref is_structured() -- returns whether JSON value is structured
13101 @sa @ref is_null() -- returns whether JSON value is `null`
13102 @sa @ref is_string() -- returns whether JSON value is a string
13103 @sa @ref is_boolean() -- returns whether JSON value is a boolean
13104 @sa @ref is_number() -- returns whether JSON value is a number
13105
13106 @since version 1.0.0
13107 */
13108constexpr bool is_primitive() const noexcept
13109{
13110return is_null() or is_string() or is_boolean() or is_number();
13111}
13112
13113/*!
13114 @brief return whether type is structured
13115
13116 This function returns true if and only if the JSON type is structured
13117 (array or object).
13118
13119 @return `true` if type is structured (array or object), `false` otherwise.
13120
13121 @complexity Constant.
13122
13123 @exceptionsafety No-throw guarantee: this member function never throws
13124 exceptions.
13125
13126 @liveexample{The following code exemplifies `is_structured()` for all JSON
13127 types.,is_structured}
13128
13129 @sa @ref is_primitive() -- returns whether value is primitive
13130 @sa @ref is_array() -- returns whether value is an array
13131 @sa @ref is_object() -- returns whether value is an object
13132
13133 @since version 1.0.0
13134 */
13135constexpr bool is_structured() const noexcept
13136{
13137return is_array() or is_object();
13138}
13139
13140/*!
13141 @brief return whether value is null
13142
13143 This function returns true if and only if the JSON value is null.
13144
13145 @return `true` if type is null, `false` otherwise.
13146
13147 @complexity Constant.
13148
13149 @exceptionsafety No-throw guarantee: this member function never throws
13150 exceptions.
13151
13152 @liveexample{The following code exemplifies `is_null()` for all JSON
13153 types.,is_null}
13154
13155 @since version 1.0.0
13156 */
13157constexpr bool is_null() const noexcept
13158{
13159return (m_type == value_t::null);
13160}
13161
13162/*!
13163 @brief return whether value is a boolean
13164
13165 This function returns true if and only if the JSON value is a boolean.
13166
13167 @return `true` if type is boolean, `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_boolean()` for all JSON
13175 types.,is_boolean}
13176
13177 @since version 1.0.0
13178 */
13179constexpr bool is_boolean() const noexcept
13180{
13181return (m_type == value_t::boolean);
13182}
13183
13184/*!
13185 @brief return whether value is a number
13186
13187 This function returns true if and only if the JSON value is a number. This
13188 includes both integer (signed and unsigned) and floating-point values.
13189
13190 @return `true` if type is number (regardless whether integer, unsigned
13191 integer or floating-type), `false` otherwise.
13192
13193 @complexity Constant.
13194
13195 @exceptionsafety No-throw guarantee: this member function never throws
13196 exceptions.
13197
13198 @liveexample{The following code exemplifies `is_number()` for all JSON
13199 types.,is_number}
13200
13201 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13202 integer number
13203 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13204 number
13205 @sa @ref is_number_float() -- check if value is a floating-point number
13206
13207 @since version 1.0.0
13208 */
13209constexpr bool is_number() const noexcept
13210{
13211return is_number_integer() or is_number_float();
13212}
13213
13214/*!
13215 @brief return whether value is an integer number
13216
13217 This function returns true if and only if the JSON value is a signed or
13218 unsigned integer number. This excludes floating-point values.
13219
13220 @return `true` if type is an integer or unsigned integer number, `false`
13221 otherwise.
13222
13223 @complexity Constant.
13224
13225 @exceptionsafety No-throw guarantee: this member function never throws
13226 exceptions.
13227
13228 @liveexample{The following code exemplifies `is_number_integer()` for all
13229 JSON types.,is_number_integer}
13230
13231 @sa @ref is_number() -- check if value is a number
13232 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13233 number
13234 @sa @ref is_number_float() -- check if value is a floating-point number
13235
13236 @since version 1.0.0
13237 */
13238constexpr bool is_number_integer() const noexcept
13239{
13240return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
13241}
13242
13243/*!
13244 @brief return whether value is an unsigned integer number
13245
13246 This function returns true if and only if the JSON value is an unsigned
13247 integer number. This excludes floating-point and signed integer values.
13248
13249 @return `true` if type is an unsigned integer number, `false` otherwise.
13250
13251 @complexity Constant.
13252
13253 @exceptionsafety No-throw guarantee: this member function never throws
13254 exceptions.
13255
13256 @liveexample{The following code exemplifies `is_number_unsigned()` for all
13257 JSON types.,is_number_unsigned}
13258
13259 @sa @ref is_number() -- check if value is a number
13260 @sa @ref is_number_integer() -- check if value is an integer or unsigned
13261 integer number
13262 @sa @ref is_number_float() -- check if value is a floating-point number
13263
13264 @since version 2.0.0
13265 */
13266constexpr bool is_number_unsigned() const noexcept
13267{
13268return (m_type == value_t::number_unsigned);
13269}
13270
13271/*!
13272 @brief return whether value is a floating-point number
13273
13274 This function returns true if and only if the JSON value is a
13275 floating-point number. This excludes signed and unsigned integer values.
13276
13277 @return `true` if type is a floating-point number, `false` otherwise.
13278
13279 @complexity Constant.
13280
13281 @exceptionsafety No-throw guarantee: this member function never throws
13282 exceptions.
13283
13284 @liveexample{The following code exemplifies `is_number_float()` for all
13285 JSON types.,is_number_float}
13286
13287 @sa @ref is_number() -- check if value is number
13288 @sa @ref is_number_integer() -- check if value is an integer number
13289 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
13290 number
13291
13292 @since version 1.0.0
13293 */
13294constexpr bool is_number_float() const noexcept
13295{
13296return (m_type == value_t::number_float);
13297}
13298
13299/*!
13300 @brief return whether value is an object
13301
13302 This function returns true if and only if the JSON value is an object.
13303
13304 @return `true` if type is object, `false` otherwise.
13305
13306 @complexity Constant.
13307
13308 @exceptionsafety No-throw guarantee: this member function never throws
13309 exceptions.
13310
13311 @liveexample{The following code exemplifies `is_object()` for all JSON
13312 types.,is_object}
13313
13314 @since version 1.0.0
13315 */
13316constexpr bool is_object() const noexcept
13317{
13318return (m_type == value_t::object);
13319}
13320
13321/*!
13322 @brief return whether value is an array
13323
13324 This function returns true if and only if the JSON value is an array.
13325
13326 @return `true` if type is array, `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_array()` for all JSON
13334 types.,is_array}
13335
13336 @since version 1.0.0
13337 */
13338constexpr bool is_array() const noexcept
13339{
13340return (m_type == value_t::array);
13341}
13342
13343/*!
13344 @brief return whether value is a string
13345
13346 This function returns true if and only if the JSON value is a string.
13347
13348 @return `true` if type is string, `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_string()` for all JSON
13356 types.,is_string}
13357
13358 @since version 1.0.0
13359 */
13360constexpr bool is_string() const noexcept
13361{
13362return (m_type == value_t::string);
13363}
13364
13365/*!
13366 @brief return whether value is discarded
13367
13368 This function returns true if and only if the JSON value was discarded
13369 during parsing with a callback function (see @ref parser_callback_t).
13370
13371 @note This function will always be `false` for JSON values after parsing.
13372 That is, discarded values can only occur during parsing, but will be
13373 removed when inside a structured value or replaced by null in other cases.
13374
13375 @return `true` if type is discarded, `false` otherwise.
13376
13377 @complexity Constant.
13378
13379 @exceptionsafety No-throw guarantee: this member function never throws
13380 exceptions.
13381
13382 @liveexample{The following code exemplifies `is_discarded()` for all JSON
13383 types.,is_discarded}
13384
13385 @since version 1.0.0
13386 */
13387constexpr bool is_discarded() const noexcept
13388{
13389return (m_type == value_t::discarded);
13390}
13391
13392/*!
13393 @brief return the type of the JSON value (implicit)
13394
13395 Implicitly return the type of the JSON value as a value from the @ref
13396 value_t enumeration.
13397
13398 @return the type of the JSON value
13399
13400 @complexity Constant.
13401
13402 @exceptionsafety No-throw guarantee: this member function never throws
13403 exceptions.
13404
13405 @liveexample{The following code exemplifies the @ref value_t operator for
13406 all JSON types.,operator__value_t}
13407
13408 @sa @ref type() -- return the type of the JSON value (explicit)
13409 @sa @ref type_name() -- return the type as string
13410
13411 @since version 1.0.0
13412 */
13413constexpr operator value_t() const noexcept
13414{
13415return m_type;
13416}
13417
13418/// @}
13419
13420private:
13421//////////////////
13422// value access //
13423//////////////////
13424
13425/// get a boolean (explicit)
13426boolean_t get_impl(boolean_t* /*unused*/) const
13427{
13428if (JSON_LIKELY(is_boolean()))
13429{
13430return m_value.boolean;
13431}
13432
13433JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
13434}
13435
13436/// get a pointer to the value (object)
13437object_t* get_impl_ptr(object_t* /*unused*/) noexcept
13438{
13439return is_object() ? m_value.object : nullptr;
13440}
13441
13442/// get a pointer to the value (object)
13443constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
13444{
13445return is_object() ? m_value.object : nullptr;
13446}
13447
13448/// get a pointer to the value (array)
13449array_t* get_impl_ptr(array_t* /*unused*/) noexcept
13450{
13451return is_array() ? m_value.array : nullptr;
13452}
13453
13454/// get a pointer to the value (array)
13455constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
13456{
13457return is_array() ? m_value.array : nullptr;
13458}
13459
13460/// get a pointer to the value (string)
13461string_t* get_impl_ptr(string_t* /*unused*/) noexcept
13462{
13463return is_string() ? m_value.string : nullptr;
13464}
13465
13466/// get a pointer to the value (string)
13467constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
13468{
13469return is_string() ? m_value.string : nullptr;
13470}
13471
13472/// get a pointer to the value (boolean)
13473boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
13474{
13475return is_boolean() ? &m_value.boolean : nullptr;
13476}
13477
13478/// get a pointer to the value (boolean)
13479constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
13480{
13481return is_boolean() ? &m_value.boolean : nullptr;
13482}
13483
13484/// get a pointer to the value (integer number)
13485number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
13486{
13487return is_number_integer() ? &m_value.number_integer : nullptr;
13488}
13489
13490/// get a pointer to the value (integer number)
13491constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
13492{
13493return is_number_integer() ? &m_value.number_integer : nullptr;
13494}
13495
13496/// get a pointer to the value (unsigned number)
13497number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
13498{
13499return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13500}
13501
13502/// get a pointer to the value (unsigned number)
13503constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
13504{
13505return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
13506}
13507
13508/// get a pointer to the value (floating-point number)
13509number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
13510{
13511return is_number_float() ? &m_value.number_float : nullptr;
13512}
13513
13514/// get a pointer to the value (floating-point number)
13515constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
13516{
13517return is_number_float() ? &m_value.number_float : nullptr;
13518}
13519
13520/*!
13521 @brief helper function to implement get_ref()
13522
13523 This function helps to implement get_ref() without code duplication for
13524 const and non-const overloads
13525
13526 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
13527
13528 @throw type_error.303 if ReferenceType does not match underlying value
13529 type of the current JSON
13530 */
13531template<typename ReferenceType, typename ThisType>
13532static ReferenceType get_ref_impl(ThisType& obj)
13533{
13534// delegate the call to get_ptr<>()
13535auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
13536
13537if (JSON_LIKELY(ptr != nullptr))
13538{
13539return *ptr;
13540}
13541
13542JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
13543}
13544
13545public:
13546/// @name value access
13547/// Direct access to the stored value of a JSON value.
13548/// @{
13549
13550/*!
13551 @brief get special-case overload
13552
13553 This overloads avoids a lot of template boilerplate, it can be seen as the
13554 identity method
13555
13556 @tparam BasicJsonType == @ref basic_json
13557
13558 @return a copy of *this
13559
13560 @complexity Constant.
13561
13562 @since version 2.1.0
13563 */
13564template<typename BasicJsonType, detail::enable_if_t<
13565std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
13566int> = 0>
13567basic_json get() const
13568{
13569return *this;
13570}
13571
13572/*!
13573 @brief get special-case overload
13574
13575 This overloads converts the current @ref basic_json in a different
13576 @ref basic_json type
13577
13578 @tparam BasicJsonType == @ref basic_json
13579
13580 @return a copy of *this, converted into @tparam BasicJsonType
13581
13582 @complexity Depending on the implementation of the called `from_json()`
13583 method.
13584
13585 @since version 3.2.0
13586 */
13587template<typename BasicJsonType, detail::enable_if_t<
13588not std::is_same<BasicJsonType, basic_json>::value and
13589detail::is_basic_json<BasicJsonType>::value, int> = 0>
13590BasicJsonType get() const
13591{
13592return *this;
13593}
13594
13595/*!
13596 @brief get a value (explicit)
13597
13598 Explicit type conversion between the JSON value and a compatible value
13599 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13600 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13601 The value is converted by calling the @ref json_serializer<ValueType>
13602 `from_json()` method.
13603
13604 The function is equivalent to executing
13605 @code {.cpp}
13606 ValueType ret;
13607 JSONSerializer<ValueType>::from_json(*this, ret);
13608 return ret;
13609 @endcode
13610
13611 This overloads is chosen if:
13612 - @a ValueType is not @ref basic_json,
13613 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13614 `void from_json(const basic_json&, ValueType&)`, and
13615 - @ref json_serializer<ValueType> does not have a `from_json()` method of
13616 the form `ValueType from_json(const basic_json&)`
13617
13618 @tparam ValueTypeCV the provided value type
13619 @tparam ValueType the returned value type
13620
13621 @return copy of the JSON value, converted to @a ValueType
13622
13623 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13624
13625 @liveexample{The example below shows several conversions from JSON values
13626 to other types. There a few things to note: (1) Floating-point numbers can
13627 be converted to integers\, (2) A JSON array can be converted to a standard
13628 `std::vector<short>`\, (3) A JSON object can be converted to C++
13629 associative containers such as `std::unordered_map<std::string\,
13630 json>`.,get__ValueType_const}
13631
13632 @since version 2.1.0
13633 */
13634template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13635detail::enable_if_t <
13636not detail::is_basic_json<ValueType>::value and
13637detail::has_from_json<basic_json_t, ValueType>::value and
13638not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13639int> = 0>
13640ValueType get() const noexcept(noexcept(
13641JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
13642{
13643// we cannot static_assert on ValueTypeCV being non-const, because
13644// there is support for get<const basic_json_t>(), which is why we
13645// still need the uncvref
13646static_assert(not std::is_reference<ValueTypeCV>::value,
13647"get() cannot be used with reference types, you might want to use get_ref()");
13648static_assert(std::is_default_constructible<ValueType>::value,
13649"types must be DefaultConstructible when used with get()");
13650
13651ValueType ret;
13652JSONSerializer<ValueType>::from_json(*this, ret);
13653return ret;
13654}
13655
13656/*!
13657 @brief get a value (explicit); special case
13658
13659 Explicit type conversion between the JSON value and a compatible value
13660 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
13661 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
13662 The value is converted by calling the @ref json_serializer<ValueType>
13663 `from_json()` method.
13664
13665 The function is equivalent to executing
13666 @code {.cpp}
13667 return JSONSerializer<ValueTypeCV>::from_json(*this);
13668 @endcode
13669
13670 This overloads is chosen if:
13671 - @a ValueType is not @ref basic_json and
13672 - @ref json_serializer<ValueType> has a `from_json()` method of the form
13673 `ValueType from_json(const basic_json&)`
13674
13675 @note If @ref json_serializer<ValueType> has both overloads of
13676 `from_json()`, this one is chosen.
13677
13678 @tparam ValueTypeCV the provided value type
13679 @tparam ValueType the returned value type
13680
13681 @return copy of the JSON value, converted to @a ValueType
13682
13683 @throw what @ref json_serializer<ValueType> `from_json()` method throws
13684
13685 @since version 2.1.0
13686 */
13687template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
13688detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
13689detail::has_non_default_from_json<basic_json_t, ValueType>::value,
13690int> = 0>
13691ValueType get() const noexcept(noexcept(
13692JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
13693{
13694static_assert(not std::is_reference<ValueTypeCV>::value,
13695"get() cannot be used with reference types, you might want to use get_ref()");
13696return JSONSerializer<ValueTypeCV>::from_json(*this);
13697}
13698
13699/*!
13700 @brief get a pointer value (explicit)
13701
13702 Explicit pointer access to the internally stored JSON value. No copies are
13703 made.
13704
13705 @warning The pointer becomes invalid if the underlying JSON object
13706 changes.
13707
13708 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13709 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13710 @ref number_unsigned_t, or @ref number_float_t.
13711
13712 @return pointer to the internally stored JSON value if the requested
13713 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13714
13715 @complexity Constant.
13716
13717 @liveexample{The example below shows how pointers to internal values of a
13718 JSON value can be requested. Note that no type conversions are made and a
13719 `nullptr` is returned if the value and the requested pointer type does not
13720 match.,get__PointerType}
13721
13722 @sa @ref get_ptr() for explicit pointer-member access
13723
13724 @since version 1.0.0
13725 */
13726template<typename PointerType, typename std::enable_if<
13727std::is_pointer<PointerType>::value, int>::type = 0>
13728PointerType get() noexcept
13729{
13730// delegate the call to get_ptr
13731return get_ptr<PointerType>();
13732}
13733
13734/*!
13735 @brief get a pointer value (explicit)
13736 @copydoc get()
13737 */
13738template<typename PointerType, typename std::enable_if<
13739std::is_pointer<PointerType>::value, int>::type = 0>
13740constexpr const PointerType get() const noexcept
13741{
13742// delegate the call to get_ptr
13743return get_ptr<PointerType>();
13744}
13745
13746/*!
13747 @brief get a pointer value (implicit)
13748
13749 Implicit pointer access to the internally stored JSON value. No copies are
13750 made.
13751
13752 @warning Writing data to the pointee of the result yields an undefined
13753 state.
13754
13755 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
13756 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
13757 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
13758 assertion.
13759
13760 @return pointer to the internally stored JSON value if the requested
13761 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
13762
13763 @complexity Constant.
13764
13765 @liveexample{The example below shows how pointers to internal values of a
13766 JSON value can be requested. Note that no type conversions are made and a
13767 `nullptr` is returned if the value and the requested pointer type does not
13768 match.,get_ptr}
13769
13770 @since version 1.0.0
13771 */
13772template<typename PointerType, typename std::enable_if<
13773std::is_pointer<PointerType>::value, int>::type = 0>
13774PointerType get_ptr() noexcept
13775{
13776// get the type of the PointerType (remove pointer and const)
13777using pointee_t = typename std::remove_const<typename
13778std::remove_pointer<typename
13779std::remove_const<PointerType>::type>::type>::type;
13780// make sure the type matches the allowed types
13781static_assert(
13782std::is_same<object_t, pointee_t>::value
13783or std::is_same<array_t, pointee_t>::value
13784or std::is_same<string_t, pointee_t>::value
13785or std::is_same<boolean_t, pointee_t>::value
13786or std::is_same<number_integer_t, pointee_t>::value
13787or std::is_same<number_unsigned_t, pointee_t>::value
13788or std::is_same<number_float_t, pointee_t>::value
13789, "incompatible pointer type");
13790
13791// delegate the call to get_impl_ptr<>()
13792return get_impl_ptr(static_cast<PointerType>(nullptr));
13793}
13794
13795/*!
13796 @brief get a pointer value (implicit)
13797 @copydoc get_ptr()
13798 */
13799template<typename PointerType, typename std::enable_if<
13800std::is_pointer<PointerType>::value and
13801std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
13802constexpr const PointerType get_ptr() const noexcept
13803{
13804// get the type of the PointerType (remove pointer and const)
13805using pointee_t = typename std::remove_const<typename
13806std::remove_pointer<typename
13807std::remove_const<PointerType>::type>::type>::type;
13808// make sure the type matches the allowed types
13809static_assert(
13810std::is_same<object_t, pointee_t>::value
13811or std::is_same<array_t, pointee_t>::value
13812or std::is_same<string_t, pointee_t>::value
13813or std::is_same<boolean_t, pointee_t>::value
13814or std::is_same<number_integer_t, pointee_t>::value
13815or std::is_same<number_unsigned_t, pointee_t>::value
13816or std::is_same<number_float_t, pointee_t>::value
13817, "incompatible pointer type");
13818
13819// delegate the call to get_impl_ptr<>() const
13820return get_impl_ptr(static_cast<PointerType>(nullptr));
13821}
13822
13823/*!
13824 @brief get a reference value (implicit)
13825
13826 Implicit reference access to the internally stored JSON value. No copies
13827 are made.
13828
13829 @warning Writing data to the referee of the result yields an undefined
13830 state.
13831
13832 @tparam ReferenceType reference type; must be a reference to @ref array_t,
13833 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
13834 @ref number_float_t. Enforced by static assertion.
13835
13836 @return reference to the internally stored JSON value if the requested
13837 reference type @a ReferenceType fits to the JSON value; throws
13838 type_error.303 otherwise
13839
13840 @throw type_error.303 in case passed type @a ReferenceType is incompatible
13841 with the stored JSON value; see example below
13842
13843 @complexity Constant.
13844
13845 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
13846
13847 @since version 1.1.0
13848 */
13849template<typename ReferenceType, typename std::enable_if<
13850std::is_reference<ReferenceType>::value, int>::type = 0>
13851ReferenceType get_ref()
13852{
13853// delegate call to get_ref_impl
13854return get_ref_impl<ReferenceType>(*this);
13855}
13856
13857/*!
13858 @brief get a reference value (implicit)
13859 @copydoc get_ref()
13860 */
13861template<typename ReferenceType, typename std::enable_if<
13862std::is_reference<ReferenceType>::value and
13863std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
13864ReferenceType get_ref() const
13865{
13866// delegate call to get_ref_impl
13867return get_ref_impl<ReferenceType>(*this);
13868}
13869
13870/*!
13871 @brief get a value (implicit)
13872
13873 Implicit type conversion between the JSON value and a compatible value.
13874 The call is realized by calling @ref get() const.
13875
13876 @tparam ValueType non-pointer type compatible to the JSON value, for
13877 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
13878 `std::vector` types for JSON arrays. The character type of @ref string_t
13879 as well as an initializer list of this type is excluded to avoid
13880 ambiguities as these types implicitly convert to `std::string`.
13881
13882 @return copy of the JSON value, converted to type @a ValueType
13883
13884 @throw type_error.302 in case passed type @a ValueType is incompatible
13885 to the JSON value type (e.g., the JSON value is of type boolean, but a
13886 string is requested); see example below
13887
13888 @complexity Linear in the size of the JSON value.
13889
13890 @liveexample{The example below shows several conversions from JSON values
13891 to other types. There a few things to note: (1) Floating-point numbers can
13892 be converted to integers\, (2) A JSON array can be converted to a standard
13893 `std::vector<short>`\, (3) A JSON object can be converted to C++
13894 associative containers such as `std::unordered_map<std::string\,
13895 json>`.,operator__ValueType}
13896
13897 @since version 1.0.0
13898 */
13899template < typename ValueType, typename std::enable_if <
13900not std::is_pointer<ValueType>::value and
13901not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
13902not std::is_same<ValueType, typename string_t::value_type>::value and
13903not detail::is_basic_json<ValueType>::value
13904#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
13905and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
13906#if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
13907and not std::is_same<ValueType, typename std::string_view>::value
13908#endif
13909#endif
13910, int >::type = 0 >
13911operator ValueType() const
13912{
13913// delegate the call to get<>() const
13914return get<ValueType>();
13915}
13916
13917/// @}
13918
13919
13920////////////////////
13921// element access //
13922////////////////////
13923
13924/// @name element access
13925/// Access to the JSON value.
13926/// @{
13927
13928/*!
13929 @brief access specified array element with bounds checking
13930
13931 Returns a reference to the element at specified location @a idx, with
13932 bounds checking.
13933
13934 @param[in] idx index of the element to access
13935
13936 @return reference to the element at index @a idx
13937
13938 @throw type_error.304 if the JSON value is not an array; in this case,
13939 calling `at` with an index makes no sense. See example below.
13940 @throw out_of_range.401 if the index @a idx is out of range of the array;
13941 that is, `idx >= size()`. See example below.
13942
13943 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13944 changes in the JSON value.
13945
13946 @complexity Constant.
13947
13948 @since version 1.0.0
13949
13950 @liveexample{The example below shows how array elements can be read and
13951 written using `at()`. It also demonstrates the different exceptions that
13952 can be thrown.,at__size_type}
13953 */
13954reference at(size_type idx)
13955{
13956// at only works for arrays
13957if (JSON_LIKELY(is_array()))
13958{
13959JSON_TRY
13960{
13961return m_value.array->at(idx);
13962}
13963JSON_CATCH (std::out_of_range&)
13964{
13965// create better exception explanation
13966JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
13967}
13968}
13969else
13970{
13971JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
13972}
13973}
13974
13975/*!
13976 @brief access specified array element with bounds checking
13977
13978 Returns a const reference to the element at specified location @a idx,
13979 with bounds checking.
13980
13981 @param[in] idx index of the element to access
13982
13983 @return const reference to the element at index @a idx
13984
13985 @throw type_error.304 if the JSON value is not an array; in this case,
13986 calling `at` with an index makes no sense. See example below.
13987 @throw out_of_range.401 if the index @a idx is out of range of the array;
13988 that is, `idx >= size()`. See example below.
13989
13990 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13991 changes in the JSON value.
13992
13993 @complexity Constant.
13994
13995 @since version 1.0.0
13996
13997 @liveexample{The example below shows how array elements can be read using
13998 `at()`. It also demonstrates the different exceptions that can be thrown.,
13999 at__size_type_const}
14000 */
14001const_reference at(size_type idx) const
14002{
14003// at only works for arrays
14004if (JSON_LIKELY(is_array()))
14005{
14006JSON_TRY
14007{
14008return m_value.array->at(idx);
14009}
14010JSON_CATCH (std::out_of_range&)
14011{
14012// create better exception explanation
14013JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14014}
14015}
14016else
14017{
14018JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14019}
14020}
14021
14022/*!
14023 @brief access specified object element with bounds checking
14024
14025 Returns a reference to the element at with specified key @a key, with
14026 bounds checking.
14027
14028 @param[in] key key of the element to access
14029
14030 @return reference to the element at key @a key
14031
14032 @throw type_error.304 if the JSON value is not an object; in this case,
14033 calling `at` with a key makes no sense. See example below.
14034 @throw out_of_range.403 if the key @a key is is not stored in the object;
14035 that is, `find(key) == end()`. See example below.
14036
14037 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14038 changes in the JSON value.
14039
14040 @complexity Logarithmic in the size of the container.
14041
14042 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14043 access by reference
14044 @sa @ref value() for access by value with a default value
14045
14046 @since version 1.0.0
14047
14048 @liveexample{The example below shows how object elements can be read and
14049 written using `at()`. It also demonstrates the different exceptions that
14050 can be thrown.,at__object_t_key_type}
14051 */
14052reference at(const typename object_t::key_type& key)
14053{
14054// at only works for objects
14055if (JSON_LIKELY(is_object()))
14056{
14057JSON_TRY
14058{
14059return m_value.object->at(key);
14060}
14061JSON_CATCH (std::out_of_range&)
14062{
14063// create better exception explanation
14064JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14065}
14066}
14067else
14068{
14069JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14070}
14071}
14072
14073/*!
14074 @brief access specified object element with bounds checking
14075
14076 Returns a const reference to the element at with specified key @a key,
14077 with bounds checking.
14078
14079 @param[in] key key of the element to access
14080
14081 @return const reference to the element at key @a key
14082
14083 @throw type_error.304 if the JSON value is not an object; in this case,
14084 calling `at` with a key makes no sense. See example below.
14085 @throw out_of_range.403 if the key @a key is is not stored in the object;
14086 that is, `find(key) == end()`. See example below.
14087
14088 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14089 changes in the JSON value.
14090
14091 @complexity Logarithmic in the size of the container.
14092
14093 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14094 access by reference
14095 @sa @ref value() for access by value with a default value
14096
14097 @since version 1.0.0
14098
14099 @liveexample{The example below shows how object elements can be read using
14100 `at()`. It also demonstrates the different exceptions that can be thrown.,
14101 at__object_t_key_type_const}
14102 */
14103const_reference at(const typename object_t::key_type& key) const
14104{
14105// at only works for objects
14106if (JSON_LIKELY(is_object()))
14107{
14108JSON_TRY
14109{
14110return m_value.object->at(key);
14111}
14112JSON_CATCH (std::out_of_range&)
14113{
14114// create better exception explanation
14115JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
14116}
14117}
14118else
14119{
14120JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
14121}
14122}
14123
14124/*!
14125 @brief access specified array element
14126
14127 Returns a reference to the element at specified location @a idx.
14128
14129 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
14130 then the array is silently filled up with `null` values to make `idx` a
14131 valid reference to the last stored element.
14132
14133 @param[in] idx index of the element to access
14134
14135 @return reference to the element at index @a idx
14136
14137 @throw type_error.305 if the JSON value is not an array or null; in that
14138 cases, using the [] operator with an index makes no sense.
14139
14140 @complexity Constant if @a idx is in the range of the array. Otherwise
14141 linear in `idx - size()`.
14142
14143 @liveexample{The example below shows how array elements can be read and
14144 written using `[]` operator. Note the addition of `null`
14145 values.,operatorarray__size_type}
14146
14147 @since version 1.0.0
14148 */
14149reference operator[](size_type idx)
14150{
14151// implicitly convert null value to an empty array
14152if (is_null())
14153{
14154m_type = value_t::array;
14155m_value.array = create<array_t>();
14156assert_invariant();
14157}
14158
14159// operator[] only works for arrays
14160if (JSON_LIKELY(is_array()))
14161{
14162// fill up array with null values if given idx is outside range
14163if (idx >= m_value.array->size())
14164{
14165m_value.array->insert(m_value.array->end(),
14166idx - m_value.array->size() + 1,
14167basic_json());
14168}
14169
14170return m_value.array->operator[](idx);
14171}
14172
14173JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
14174}
14175
14176/*!
14177 @brief access specified array element
14178
14179 Returns a const reference to the element at specified location @a idx.
14180
14181 @param[in] idx index of the element to access
14182
14183 @return const reference to the element at index @a idx
14184
14185 @throw type_error.305 if the JSON value is not an array; in that case,
14186 using the [] operator with an index makes no sense.
14187
14188 @complexity Constant.
14189
14190 @liveexample{The example below shows how array elements can be read using
14191 the `[]` operator.,operatorarray__size_type_const}
14192
14193 @since version 1.0.0
14194 */
14195const_reference operator[](size_type idx) const
14196{
14197// const operator[] only works for arrays
14198if (JSON_LIKELY(is_array()))
14199{
14200return m_value.array->operator[](idx);
14201}
14202
14203JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
14204}
14205
14206/*!
14207 @brief access specified object element
14208
14209 Returns a reference to the element at with specified key @a key.
14210
14211 @note If @a key is not found in the object, then it is silently added to
14212 the object and filled with a `null` value to make `key` a valid reference.
14213 In case the value was `null` before, it is converted to an object.
14214
14215 @param[in] key key of the element to access
14216
14217 @return reference to the element at key @a key
14218
14219 @throw type_error.305 if the JSON value is not an object or null; in that
14220 cases, using the [] operator with a key makes no sense.
14221
14222 @complexity Logarithmic in the size of the container.
14223
14224 @liveexample{The example below shows how object elements can be read and
14225 written using the `[]` operator.,operatorarray__key_type}
14226
14227 @sa @ref at(const typename object_t::key_type&) for access by reference
14228 with range checking
14229 @sa @ref value() for access by value with a default value
14230
14231 @since version 1.0.0
14232 */
14233reference operator[](const typename object_t::key_type& key)
14234{
14235// implicitly convert null value to an empty object
14236if (is_null())
14237{
14238m_type = value_t::object;
14239m_value.object = create<object_t>();
14240assert_invariant();
14241}
14242
14243// operator[] only works for objects
14244if (JSON_LIKELY(is_object()))
14245{
14246return m_value.object->operator[](key);
14247}
14248
14249JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14250}
14251
14252/*!
14253 @brief read-only access specified object element
14254
14255 Returns a const reference to the element at with specified key @a key. No
14256 bounds checking is performed.
14257
14258 @warning If the element with key @a key does not exist, the behavior is
14259 undefined.
14260
14261 @param[in] key key of the element to access
14262
14263 @return const reference to the element at key @a key
14264
14265 @pre The element with key @a key must exist. **This precondition is
14266 enforced with an assertion.**
14267
14268 @throw type_error.305 if the JSON value is not an object; in that case,
14269 using the [] operator with a key makes no sense.
14270
14271 @complexity Logarithmic in the size of the container.
14272
14273 @liveexample{The example below shows how object elements can be read using
14274 the `[]` operator.,operatorarray__key_type_const}
14275
14276 @sa @ref at(const typename object_t::key_type&) for access by reference
14277 with range checking
14278 @sa @ref value() for access by value with a default value
14279
14280 @since version 1.0.0
14281 */
14282const_reference operator[](const typename object_t::key_type& key) const
14283{
14284// const operator[] only works for objects
14285if (JSON_LIKELY(is_object()))
14286{
14287assert(m_value.object->find(key) != m_value.object->end());
14288return m_value.object->find(key)->second;
14289}
14290
14291JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14292}
14293
14294/*!
14295 @brief access specified object element
14296
14297 Returns a reference to the element at with specified key @a key.
14298
14299 @note If @a key is not found in the object, then it is silently added to
14300 the object and filled with a `null` value to make `key` a valid reference.
14301 In case the value was `null` before, it is converted to an object.
14302
14303 @param[in] key key of the element to access
14304
14305 @return reference to the element at key @a key
14306
14307 @throw type_error.305 if the JSON value is not an object or null; in that
14308 cases, using the [] operator with a key makes no sense.
14309
14310 @complexity Logarithmic in the size of the container.
14311
14312 @liveexample{The example below shows how object elements can be read and
14313 written using the `[]` operator.,operatorarray__key_type}
14314
14315 @sa @ref at(const typename object_t::key_type&) for access by reference
14316 with range checking
14317 @sa @ref value() for access by value with a default value
14318
14319 @since version 1.1.0
14320 */
14321template<typename T>
14322reference operator[](T* key)
14323{
14324// implicitly convert null to object
14325if (is_null())
14326{
14327m_type = value_t::object;
14328m_value = value_t::object;
14329assert_invariant();
14330}
14331
14332// at only works for objects
14333if (JSON_LIKELY(is_object()))
14334{
14335return m_value.object->operator[](key);
14336}
14337
14338JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14339}
14340
14341/*!
14342 @brief read-only access specified object element
14343
14344 Returns a const reference to the element at with specified key @a key. No
14345 bounds checking is performed.
14346
14347 @warning If the element with key @a key does not exist, the behavior is
14348 undefined.
14349
14350 @param[in] key key of the element to access
14351
14352 @return const reference to the element at key @a key
14353
14354 @pre The element with key @a key must exist. **This precondition is
14355 enforced with an assertion.**
14356
14357 @throw type_error.305 if the JSON value is not an object; in that case,
14358 using the [] operator with a key makes no sense.
14359
14360 @complexity Logarithmic in the size of the container.
14361
14362 @liveexample{The example below shows how object elements can be read using
14363 the `[]` operator.,operatorarray__key_type_const}
14364
14365 @sa @ref at(const typename object_t::key_type&) for access by reference
14366 with range checking
14367 @sa @ref value() for access by value with a default value
14368
14369 @since version 1.1.0
14370 */
14371template<typename T>
14372const_reference operator[](T* key) const
14373{
14374// at only works for objects
14375if (JSON_LIKELY(is_object()))
14376{
14377assert(m_value.object->find(key) != m_value.object->end());
14378return m_value.object->find(key)->second;
14379}
14380
14381JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
14382}
14383
14384/*!
14385 @brief access specified object element with default value
14386
14387 Returns either a copy of an object's element at the specified key @a key
14388 or a given default value if no element with key @a key exists.
14389
14390 The function is basically equivalent to executing
14391 @code {.cpp}
14392 try {
14393 return at(key);
14394 } catch(out_of_range) {
14395 return default_value;
14396 }
14397 @endcode
14398
14399 @note Unlike @ref at(const typename object_t::key_type&), this function
14400 does not throw if the given key @a key was not found.
14401
14402 @note Unlike @ref operator[](const typename object_t::key_type& key), this
14403 function does not implicitly add an element to the position defined by @a
14404 key. This function is furthermore also applicable to const objects.
14405
14406 @param[in] key key of the element to access
14407 @param[in] default_value the value to return if @a key is not found
14408
14409 @tparam ValueType type compatible to JSON values, for instance `int` for
14410 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14411 JSON arrays. Note the type of the expected value at @a key and the default
14412 value @a default_value must be compatible.
14413
14414 @return copy of the element at key @a key or @a default_value if @a key
14415 is not found
14416
14417 @throw type_error.306 if the JSON value is not an object; in that case,
14418 using `value()` with a key makes no sense.
14419
14420 @complexity Logarithmic in the size of the container.
14421
14422 @liveexample{The example below shows how object elements can be queried
14423 with a default value.,basic_json__value}
14424
14425 @sa @ref at(const typename object_t::key_type&) for access by reference
14426 with range checking
14427 @sa @ref operator[](const typename object_t::key_type&) for unchecked
14428 access by reference
14429
14430 @since version 1.0.0
14431 */
14432template<class ValueType, typename std::enable_if<
14433std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14434ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
14435{
14436// at only works for objects
14437if (JSON_LIKELY(is_object()))
14438{
14439// if key is found, return value and given default value otherwise
14440const auto it = find(key);
14441if (it != end())
14442{
14443return *it;
14444}
14445
14446return default_value;
14447}
14448
14449JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14450}
14451
14452/*!
14453 @brief overload for a default value of type const char*
14454 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
14455 */
14456string_t value(const typename object_t::key_type& key, const char* default_value) const
14457{
14458return value(key, string_t(default_value));
14459}
14460
14461/*!
14462 @brief access specified object element via JSON Pointer with default value
14463
14464 Returns either a copy of an object's element at the specified key @a key
14465 or a given default value if no element with key @a key exists.
14466
14467 The function is basically equivalent to executing
14468 @code {.cpp}
14469 try {
14470 return at(ptr);
14471 } catch(out_of_range) {
14472 return default_value;
14473 }
14474 @endcode
14475
14476 @note Unlike @ref at(const json_pointer&), this function does not throw
14477 if the given key @a key was not found.
14478
14479 @param[in] ptr a JSON pointer to the element to access
14480 @param[in] default_value the value to return if @a ptr found no value
14481
14482 @tparam ValueType type compatible to JSON values, for instance `int` for
14483 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
14484 JSON arrays. Note the type of the expected value at @a key and the default
14485 value @a default_value must be compatible.
14486
14487 @return copy of the element at key @a key or @a default_value if @a key
14488 is not found
14489
14490 @throw type_error.306 if the JSON value is not an object; in that case,
14491 using `value()` with a key makes no sense.
14492
14493 @complexity Logarithmic in the size of the container.
14494
14495 @liveexample{The example below shows how object elements can be queried
14496 with a default value.,basic_json__value_ptr}
14497
14498 @sa @ref operator[](const json_pointer&) for unchecked access by reference
14499
14500 @since version 2.0.2
14501 */
14502template<class ValueType, typename std::enable_if<
14503std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
14504ValueType value(const json_pointer& ptr, const ValueType& default_value) const
14505{
14506// at only works for objects
14507if (JSON_LIKELY(is_object()))
14508{
14509// if pointer resolves a value, return it or use default value
14510JSON_TRY
14511{
14512return ptr.get_checked(this);
14513}
14514JSON_INTERNAL_CATCH (out_of_range&)
14515{
14516return default_value;
14517}
14518}
14519
14520JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
14521}
14522
14523/*!
14524 @brief overload for a default value of type const char*
14525 @copydoc basic_json::value(const json_pointer&, ValueType) const
14526 */
14527string_t value(const json_pointer& ptr, const char* default_value) const
14528{
14529return value(ptr, string_t(default_value));
14530}
14531
14532/*!
14533 @brief access the first element
14534
14535 Returns a reference to the first element in the container. For a JSON
14536 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
14537
14538 @return In case of a structured type (array or object), a reference to the
14539 first element is returned. In case of number, string, or boolean values, a
14540 reference to the value is returned.
14541
14542 @complexity Constant.
14543
14544 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14545 or an empty array or object (undefined behavior, **guarded by
14546 assertions**).
14547 @post The JSON value remains unchanged.
14548
14549 @throw invalid_iterator.214 when called on `null` value
14550
14551 @liveexample{The following code shows an example for `front()`.,front}
14552
14553 @sa @ref back() -- access the last element
14554
14555 @since version 1.0.0
14556 */
14557reference front()
14558{
14559return *begin();
14560}
14561
14562/*!
14563 @copydoc basic_json::front()
14564 */
14565const_reference front() const
14566{
14567return *cbegin();
14568}
14569
14570/*!
14571 @brief access the last element
14572
14573 Returns a reference to the last element in the container. For a JSON
14574 container `c`, the expression `c.back()` is equivalent to
14575 @code {.cpp}
14576 auto tmp = c.end();
14577 --tmp;
14578 return *tmp;
14579 @endcode
14580
14581 @return In case of a structured type (array or object), a reference to the
14582 last element is returned. In case of number, string, or boolean values, a
14583 reference to the value is returned.
14584
14585 @complexity Constant.
14586
14587 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
14588 or an empty array or object (undefined behavior, **guarded by
14589 assertions**).
14590 @post The JSON value remains unchanged.
14591
14592 @throw invalid_iterator.214 when called on a `null` value. See example
14593 below.
14594
14595 @liveexample{The following code shows an example for `back()`.,back}
14596
14597 @sa @ref front() -- access the first element
14598
14599 @since version 1.0.0
14600 */
14601reference back()
14602{
14603auto tmp = end();
14604--tmp;
14605return *tmp;
14606}
14607
14608/*!
14609 @copydoc basic_json::back()
14610 */
14611const_reference back() const
14612{
14613auto tmp = cend();
14614--tmp;
14615return *tmp;
14616}
14617
14618/*!
14619 @brief remove element given an iterator
14620
14621 Removes the element specified by iterator @a pos. The iterator @a pos must
14622 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
14623 but is not dereferenceable) cannot be used as a value for @a pos.
14624
14625 If called on a primitive type other than `null`, the resulting JSON value
14626 will be `null`.
14627
14628 @param[in] pos iterator to the element to remove
14629 @return Iterator following the last removed element. If the iterator @a
14630 pos refers to the last element, the `end()` iterator is returned.
14631
14632 @tparam IteratorType an @ref iterator or @ref const_iterator
14633
14634 @post Invalidates iterators and references at or after the point of the
14635 erase, including the `end()` iterator.
14636
14637 @throw type_error.307 if called on a `null` value; example: `"cannot use
14638 erase() with null"`
14639 @throw invalid_iterator.202 if called on an iterator which does not belong
14640 to the current JSON value; example: `"iterator does not fit current
14641 value"`
14642 @throw invalid_iterator.205 if called on a primitive type with invalid
14643 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
14644 out of range"`
14645
14646 @complexity The complexity depends on the type:
14647 - objects: amortized constant
14648 - arrays: linear in distance between @a pos and the end of the container
14649 - strings: linear in the length of the string
14650 - other types: constant
14651
14652 @liveexample{The example shows the result of `erase()` for different JSON
14653 types.,erase__IteratorType}
14654
14655 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14656 the given range
14657 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14658 from an object at the given key
14659 @sa @ref erase(const size_type) -- removes the element from an array at
14660 the given index
14661
14662 @since version 1.0.0
14663 */
14664template<class IteratorType, typename std::enable_if<
14665std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14666std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14667= 0>
14668IteratorType erase(IteratorType pos)
14669{
14670// make sure iterator fits the current value
14671if (JSON_UNLIKELY(this != pos.m_object))
14672{
14673JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14674}
14675
14676IteratorType result = end();
14677
14678switch (m_type)
14679{
14680case value_t::boolean:
14681case value_t::number_float:
14682case value_t::number_integer:
14683case value_t::number_unsigned:
14684case value_t::string:
14685{
14686if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
14687{
14688JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
14689}
14690
14691if (is_string())
14692{
14693AllocatorType<string_t> alloc;
14694std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14695std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14696m_value.string = nullptr;
14697}
14698
14699m_type = value_t::null;
14700assert_invariant();
14701break;
14702}
14703
14704case value_t::object:
14705{
14706result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
14707break;
14708}
14709
14710case value_t::array:
14711{
14712result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
14713break;
14714}
14715
14716default:
14717JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14718}
14719
14720return result;
14721}
14722
14723/*!
14724 @brief remove elements given an iterator range
14725
14726 Removes the element specified by the range `[first; last)`. The iterator
14727 @a first does not need to be dereferenceable if `first == last`: erasing
14728 an empty range is a no-op.
14729
14730 If called on a primitive type other than `null`, the resulting JSON value
14731 will be `null`.
14732
14733 @param[in] first iterator to the beginning of the range to remove
14734 @param[in] last iterator past the end of the range to remove
14735 @return Iterator following the last removed element. If the iterator @a
14736 second refers to the last element, the `end()` iterator is returned.
14737
14738 @tparam IteratorType an @ref iterator or @ref const_iterator
14739
14740 @post Invalidates iterators and references at or after the point of the
14741 erase, including the `end()` iterator.
14742
14743 @throw type_error.307 if called on a `null` value; example: `"cannot use
14744 erase() with null"`
14745 @throw invalid_iterator.203 if called on iterators which does not belong
14746 to the current JSON value; example: `"iterators do not fit current value"`
14747 @throw invalid_iterator.204 if called on a primitive type with invalid
14748 iterators (i.e., if `first != begin()` and `last != end()`); example:
14749 `"iterators out of range"`
14750
14751 @complexity The complexity depends on the type:
14752 - objects: `log(size()) + std::distance(first, last)`
14753 - arrays: linear in the distance between @a first and @a last, plus linear
14754 in the distance between @a last and end of the container
14755 - strings: linear in the length of the string
14756 - other types: constant
14757
14758 @liveexample{The example shows the result of `erase()` for different JSON
14759 types.,erase__IteratorType_IteratorType}
14760
14761 @sa @ref erase(IteratorType) -- removes the element at a given position
14762 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14763 from an object at the given key
14764 @sa @ref erase(const size_type) -- removes the element from an array at
14765 the given index
14766
14767 @since version 1.0.0
14768 */
14769template<class IteratorType, typename std::enable_if<
14770std::is_same<IteratorType, typename basic_json_t::iterator>::value or
14771std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
14772= 0>
14773IteratorType erase(IteratorType first, IteratorType last)
14774{
14775// make sure iterator fits the current value
14776if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
14777{
14778JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
14779}
14780
14781IteratorType result = end();
14782
14783switch (m_type)
14784{
14785case value_t::boolean:
14786case value_t::number_float:
14787case value_t::number_integer:
14788case value_t::number_unsigned:
14789case value_t::string:
14790{
14791if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
14792or not last.m_it.primitive_iterator.is_end()))
14793{
14794JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14795}
14796
14797if (is_string())
14798{
14799AllocatorType<string_t> alloc;
14800std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
14801std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
14802m_value.string = nullptr;
14803}
14804
14805m_type = value_t::null;
14806assert_invariant();
14807break;
14808}
14809
14810case value_t::object:
14811{
14812result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
14813last.m_it.object_iterator);
14814break;
14815}
14816
14817case value_t::array:
14818{
14819result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
14820last.m_it.array_iterator);
14821break;
14822}
14823
14824default:
14825JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14826}
14827
14828return result;
14829}
14830
14831/*!
14832 @brief remove element from a JSON object given a key
14833
14834 Removes elements from a JSON object with the key value @a key.
14835
14836 @param[in] key value of the elements to remove
14837
14838 @return Number of elements removed. If @a ObjectType is the default
14839 `std::map` type, the return value will always be `0` (@a key was not
14840 found) or `1` (@a key was found).
14841
14842 @post References and iterators to the erased elements are invalidated.
14843 Other references and iterators are not affected.
14844
14845 @throw type_error.307 when called on a type other than JSON object;
14846 example: `"cannot use erase() with null"`
14847
14848 @complexity `log(size()) + count(key)`
14849
14850 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
14851
14852 @sa @ref erase(IteratorType) -- removes the element at a given position
14853 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14854 the given range
14855 @sa @ref erase(const size_type) -- removes the element from an array at
14856 the given index
14857
14858 @since version 1.0.0
14859 */
14860size_type erase(const typename object_t::key_type& key)
14861{
14862// this erase only works for objects
14863if (JSON_LIKELY(is_object()))
14864{
14865return m_value.object->erase(key);
14866}
14867
14868JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14869}
14870
14871/*!
14872 @brief remove element from a JSON array given an index
14873
14874 Removes element from a JSON array at the index @a idx.
14875
14876 @param[in] idx index of the element to remove
14877
14878 @throw type_error.307 when called on a type other than JSON object;
14879 example: `"cannot use erase() with null"`
14880 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
14881 is out of range"`
14882
14883 @complexity Linear in distance between @a idx and the end of the container.
14884
14885 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
14886
14887 @sa @ref erase(IteratorType) -- removes the element at a given position
14888 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
14889 the given range
14890 @sa @ref erase(const typename object_t::key_type&) -- removes the element
14891 from an object at the given key
14892
14893 @since version 1.0.0
14894 */
14895void erase(const size_type idx)
14896{
14897// this erase only works for arrays
14898if (JSON_LIKELY(is_array()))
14899{
14900if (JSON_UNLIKELY(idx >= size()))
14901{
14902JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14903}
14904
14905m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
14906}
14907else
14908{
14909JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
14910}
14911}
14912
14913/// @}
14914
14915
14916////////////
14917// lookup //
14918////////////
14919
14920/// @name lookup
14921/// @{
14922
14923/*!
14924 @brief find an element in a JSON object
14925
14926 Finds an element in a JSON object with key equivalent to @a key. If the
14927 element is not found or the JSON value is not an object, end() is
14928 returned.
14929
14930 @note This method always returns @ref end() when executed on a JSON type
14931 that is not an object.
14932
14933 @param[in] key key value of the element to search for.
14934
14935 @return Iterator to an element with key equivalent to @a key. If no such
14936 element is found or the JSON value is not an object, past-the-end (see
14937 @ref end()) iterator is returned.
14938
14939 @complexity Logarithmic in the size of the JSON object.
14940
14941 @liveexample{The example shows how `find()` is used.,find__key_type}
14942
14943 @since version 1.0.0
14944 */
14945template<typename KeyT>
14946iterator find(KeyT&& key)
14947{
14948auto result = end();
14949
14950if (is_object())
14951{
14952result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
14953}
14954
14955return result;
14956}
14957
14958/*!
14959 @brief find an element in a JSON object
14960 @copydoc find(KeyT&&)
14961 */
14962template<typename KeyT>
14963const_iterator find(KeyT&& key) const
14964{
14965auto result = cend();
14966
14967if (is_object())
14968{
14969result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
14970}
14971
14972return result;
14973}
14974
14975/*!
14976 @brief returns the number of occurrences of a key in a JSON object
14977
14978 Returns the number of elements with key @a key. If ObjectType is the
14979 default `std::map` type, the return value will always be `0` (@a key was
14980 not found) or `1` (@a key was found).
14981
14982 @note This method always returns `0` when executed on a JSON type that is
14983 not an object.
14984
14985 @param[in] key key value of the element to count
14986
14987 @return Number of elements with key @a key. If the JSON value is not an
14988 object, the return value will be `0`.
14989
14990 @complexity Logarithmic in the size of the JSON object.
14991
14992 @liveexample{The example shows how `count()` is used.,count}
14993
14994 @since version 1.0.0
14995 */
14996template<typename KeyT>
14997size_type count(KeyT&& key) const
14998{
14999// return 0 for all nonobject types
15000return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
15001}
15002
15003/// @}
15004
15005
15006///////////////
15007// iterators //
15008///////////////
15009
15010/// @name iterators
15011/// @{
15012
15013/*!
15014 @brief returns an iterator to the first element
15015
15016 Returns an iterator to the first element.
15017
15018 @image html range-begin-end.svg "Illustration from cppreference.com"
15019
15020 @return iterator to the first element
15021
15022 @complexity Constant.
15023
15024 @requirement This function helps `basic_json` satisfying the
15025 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15026 requirements:
15027 - The complexity is constant.
15028
15029 @liveexample{The following code shows an example for `begin()`.,begin}
15030
15031 @sa @ref cbegin() -- returns a const iterator to the beginning
15032 @sa @ref end() -- returns an iterator to the end
15033 @sa @ref cend() -- returns a const iterator to the end
15034
15035 @since version 1.0.0
15036 */
15037iterator begin() noexcept
15038{
15039iterator result(this);
15040result.set_begin();
15041return result;
15042}
15043
15044/*!
15045 @copydoc basic_json::cbegin()
15046 */
15047const_iterator begin() const noexcept
15048{
15049return cbegin();
15050}
15051
15052/*!
15053 @brief returns a const iterator to the first element
15054
15055 Returns a const iterator to the first element.
15056
15057 @image html range-begin-end.svg "Illustration from cppreference.com"
15058
15059 @return const iterator to the first element
15060
15061 @complexity Constant.
15062
15063 @requirement This function helps `basic_json` satisfying the
15064 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15065 requirements:
15066 - The complexity is constant.
15067 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
15068
15069 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
15070
15071 @sa @ref begin() -- returns an 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 */
15077const_iterator cbegin() const noexcept
15078{
15079const_iterator result(this);
15080result.set_begin();
15081return result;
15082}
15083
15084/*!
15085 @brief returns an iterator to one past the last element
15086
15087 Returns an iterator to one past the last element.
15088
15089 @image html range-begin-end.svg "Illustration from cppreference.com"
15090
15091 @return iterator one past the last element
15092
15093 @complexity Constant.
15094
15095 @requirement This function helps `basic_json` satisfying the
15096 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15097 requirements:
15098 - The complexity is constant.
15099
15100 @liveexample{The following code shows an example for `end()`.,end}
15101
15102 @sa @ref cend() -- returns a const iterator to the end
15103 @sa @ref begin() -- returns an iterator to the beginning
15104 @sa @ref cbegin() -- returns a const iterator to the beginning
15105
15106 @since version 1.0.0
15107 */
15108iterator end() noexcept
15109{
15110iterator result(this);
15111result.set_end();
15112return result;
15113}
15114
15115/*!
15116 @copydoc basic_json::cend()
15117 */
15118const_iterator end() const noexcept
15119{
15120return cend();
15121}
15122
15123/*!
15124 @brief returns a const iterator to one past the last element
15125
15126 Returns a const iterator to one past the last element.
15127
15128 @image html range-begin-end.svg "Illustration from cppreference.com"
15129
15130 @return const iterator one past the last element
15131
15132 @complexity Constant.
15133
15134 @requirement This function helps `basic_json` satisfying the
15135 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15136 requirements:
15137 - The complexity is constant.
15138 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
15139
15140 @liveexample{The following code shows an example for `cend()`.,cend}
15141
15142 @sa @ref end() -- returns an 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 */
15148const_iterator cend() const noexcept
15149{
15150const_iterator result(this);
15151result.set_end();
15152return result;
15153}
15154
15155/*!
15156 @brief returns an iterator to the reverse-beginning
15157
15158 Returns an iterator to the reverse-beginning; that is, the last element.
15159
15160 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15161
15162 @complexity Constant.
15163
15164 @requirement This function helps `basic_json` satisfying the
15165 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15166 requirements:
15167 - The complexity is constant.
15168 - Has the semantics of `reverse_iterator(end())`.
15169
15170 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
15171
15172 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15173 @sa @ref rend() -- returns a reverse iterator to the end
15174 @sa @ref crend() -- returns a const reverse iterator to the end
15175
15176 @since version 1.0.0
15177 */
15178reverse_iterator rbegin() noexcept
15179{
15180return reverse_iterator(end());
15181}
15182
15183/*!
15184 @copydoc basic_json::crbegin()
15185 */
15186const_reverse_iterator rbegin() const noexcept
15187{
15188return crbegin();
15189}
15190
15191/*!
15192 @brief returns an iterator to the reverse-end
15193
15194 Returns an iterator to the reverse-end; that is, one before the first
15195 element.
15196
15197 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15198
15199 @complexity Constant.
15200
15201 @requirement This function helps `basic_json` satisfying the
15202 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15203 requirements:
15204 - The complexity is constant.
15205 - Has the semantics of `reverse_iterator(begin())`.
15206
15207 @liveexample{The following code shows an example for `rend()`.,rend}
15208
15209 @sa @ref crend() -- returns a const reverse iterator to the end
15210 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15211 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15212
15213 @since version 1.0.0
15214 */
15215reverse_iterator rend() noexcept
15216{
15217return reverse_iterator(begin());
15218}
15219
15220/*!
15221 @copydoc basic_json::crend()
15222 */
15223const_reverse_iterator rend() const noexcept
15224{
15225return crend();
15226}
15227
15228/*!
15229 @brief returns a const reverse iterator to the last element
15230
15231 Returns a const iterator to the reverse-beginning; that is, the last
15232 element.
15233
15234 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15235
15236 @complexity Constant.
15237
15238 @requirement This function helps `basic_json` satisfying the
15239 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15240 requirements:
15241 - The complexity is constant.
15242 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
15243
15244 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
15245
15246 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15247 @sa @ref rend() -- returns a reverse iterator to the end
15248 @sa @ref crend() -- returns a const reverse iterator to the end
15249
15250 @since version 1.0.0
15251 */
15252const_reverse_iterator crbegin() const noexcept
15253{
15254return const_reverse_iterator(cend());
15255}
15256
15257/*!
15258 @brief returns a const reverse iterator to one before the first
15259
15260 Returns a const reverse iterator to the reverse-end; that is, one before
15261 the first element.
15262
15263 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
15264
15265 @complexity Constant.
15266
15267 @requirement This function helps `basic_json` satisfying the
15268 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
15269 requirements:
15270 - The complexity is constant.
15271 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
15272
15273 @liveexample{The following code shows an example for `crend()`.,crend}
15274
15275 @sa @ref rend() -- returns a reverse iterator to the end
15276 @sa @ref rbegin() -- returns a reverse iterator to the beginning
15277 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
15278
15279 @since version 1.0.0
15280 */
15281const_reverse_iterator crend() const noexcept
15282{
15283return const_reverse_iterator(cbegin());
15284}
15285
15286public:
15287/*!
15288 @brief wrapper to access iterator member functions in range-based for
15289
15290 This function allows to access @ref iterator::key() and @ref
15291 iterator::value() during range-based for loops. In these loops, a
15292 reference to the JSON values is returned, so there is no access to the
15293 underlying iterator.
15294
15295 For loop without iterator_wrapper:
15296
15297 @code{cpp}
15298 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15299 {
15300 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15301 }
15302 @endcode
15303
15304 Range-based for loop without iterator proxy:
15305
15306 @code{cpp}
15307 for (auto it : j_object)
15308 {
15309 // "it" is of type json::reference and has no key() member
15310 std::cout << "value: " << it << '\n';
15311 }
15312 @endcode
15313
15314 Range-based for loop with iterator proxy:
15315
15316 @code{cpp}
15317 for (auto it : json::iterator_wrapper(j_object))
15318 {
15319 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15320 }
15321 @endcode
15322
15323 @note When iterating over an array, `key()` will return the index of the
15324 element as string (see example).
15325
15326 @param[in] ref reference to a JSON value
15327 @return iteration proxy object wrapping @a ref with an interface to use in
15328 range-based for loops
15329
15330 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
15331
15332 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15333 changes in the JSON value.
15334
15335 @complexity Constant.
15336
15337 @note The name of this function is not yet final and may change in the
15338 future.
15339
15340 @deprecated This stream operator is deprecated and will be removed in
15341 future 4.0.0 of the library. Please use @ref items() instead;
15342 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
15343 */
15344JSON_DEPRECATED
15345static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
15346{
15347return ref.items();
15348}
15349
15350/*!
15351 @copydoc iterator_wrapper(reference)
15352 */
15353JSON_DEPRECATED
15354static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
15355{
15356return ref.items();
15357}
15358
15359/*!
15360 @brief helper to access iterator member functions in range-based for
15361
15362 This function allows to access @ref iterator::key() and @ref
15363 iterator::value() during range-based for loops. In these loops, a
15364 reference to the JSON values is returned, so there is no access to the
15365 underlying iterator.
15366
15367 For loop without `items()` function:
15368
15369 @code{cpp}
15370 for (auto it = j_object.begin(); it != j_object.end(); ++it)
15371 {
15372 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15373 }
15374 @endcode
15375
15376 Range-based for loop without `items()` function:
15377
15378 @code{cpp}
15379 for (auto it : j_object)
15380 {
15381 // "it" is of type json::reference and has no key() member
15382 std::cout << "value: " << it << '\n';
15383 }
15384 @endcode
15385
15386 Range-based for loop with `items()` function:
15387
15388 @code{cpp}
15389 for (auto it : j_object.items())
15390 {
15391 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
15392 }
15393 @endcode
15394
15395 @note When iterating over an array, `key()` will return the index of the
15396 element as string (see example). For primitive types (e.g., numbers),
15397 `key()` returns an empty string.
15398
15399 @return iteration proxy object wrapping @a ref with an interface to use in
15400 range-based for loops
15401
15402 @liveexample{The following code shows how the function is used.,items}
15403
15404 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15405 changes in the JSON value.
15406
15407 @complexity Constant.
15408
15409 @since version 3.1.0.
15410 */
15411iteration_proxy<iterator> items() noexcept
15412{
15413return iteration_proxy<iterator>(*this);
15414}
15415
15416/*!
15417 @copydoc items()
15418 */
15419iteration_proxy<const_iterator> items() const noexcept
15420{
15421return iteration_proxy<const_iterator>(*this);
15422}
15423
15424/// @}
15425
15426
15427//////////////
15428// capacity //
15429//////////////
15430
15431/// @name capacity
15432/// @{
15433
15434/*!
15435 @brief checks whether the container is empty.
15436
15437 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
15438
15439 @return The return value depends on the different types and is
15440 defined as follows:
15441 Value type | return value
15442 ----------- | -------------
15443 null | `true`
15444 boolean | `false`
15445 string | `false`
15446 number | `false`
15447 object | result of function `object_t::empty()`
15448 array | result of function `array_t::empty()`
15449
15450 @liveexample{The following code uses `empty()` to check if a JSON
15451 object contains any elements.,empty}
15452
15453 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15454 the Container concept; that is, their `empty()` functions have constant
15455 complexity.
15456
15457 @iterators No changes.
15458
15459 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15460
15461 @note This function does not return whether a string stored as JSON value
15462 is empty - it returns whether the JSON container itself is empty which is
15463 false in the case of a string.
15464
15465 @requirement This function helps `basic_json` satisfying the
15466 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15467 requirements:
15468 - The complexity is constant.
15469 - Has the semantics of `begin() == end()`.
15470
15471 @sa @ref size() -- returns the number of elements
15472
15473 @since version 1.0.0
15474 */
15475bool empty() const noexcept
15476{
15477switch (m_type)
15478{
15479case value_t::null:
15480{
15481// null values are empty
15482return true;
15483}
15484
15485case value_t::array:
15486{
15487// delegate call to array_t::empty()
15488return m_value.array->empty();
15489}
15490
15491case value_t::object:
15492{
15493// delegate call to object_t::empty()
15494return m_value.object->empty();
15495}
15496
15497default:
15498{
15499// all other types are nonempty
15500return false;
15501}
15502}
15503}
15504
15505/*!
15506 @brief returns the number of elements
15507
15508 Returns the number of elements in a JSON value.
15509
15510 @return The return value depends on the different types and is
15511 defined as follows:
15512 Value type | return value
15513 ----------- | -------------
15514 null | `0`
15515 boolean | `1`
15516 string | `1`
15517 number | `1`
15518 object | result of function object_t::size()
15519 array | result of function array_t::size()
15520
15521 @liveexample{The following code calls `size()` on the different value
15522 types.,size}
15523
15524 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15525 the Container concept; that is, their size() functions have constant
15526 complexity.
15527
15528 @iterators No changes.
15529
15530 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15531
15532 @note This function does not return the length of a string stored as JSON
15533 value - it returns the number of elements in the JSON value which is 1 in
15534 the case of a string.
15535
15536 @requirement This function helps `basic_json` satisfying the
15537 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15538 requirements:
15539 - The complexity is constant.
15540 - Has the semantics of `std::distance(begin(), end())`.
15541
15542 @sa @ref empty() -- checks whether the container is empty
15543 @sa @ref max_size() -- returns the maximal number of elements
15544
15545 @since version 1.0.0
15546 */
15547size_type size() const noexcept
15548{
15549switch (m_type)
15550{
15551case value_t::null:
15552{
15553// null values are empty
15554return 0;
15555}
15556
15557case value_t::array:
15558{
15559// delegate call to array_t::size()
15560return m_value.array->size();
15561}
15562
15563case value_t::object:
15564{
15565// delegate call to object_t::size()
15566return m_value.object->size();
15567}
15568
15569default:
15570{
15571// all other types have size 1
15572return 1;
15573}
15574}
15575}
15576
15577/*!
15578 @brief returns the maximum possible number of elements
15579
15580 Returns the maximum number of elements a JSON value is able to hold due to
15581 system or library implementation limitations, i.e. `std::distance(begin(),
15582 end())` for the JSON value.
15583
15584 @return The return value depends on the different types and is
15585 defined as follows:
15586 Value type | return value
15587 ----------- | -------------
15588 null | `0` (same as `size()`)
15589 boolean | `1` (same as `size()`)
15590 string | `1` (same as `size()`)
15591 number | `1` (same as `size()`)
15592 object | result of function `object_t::max_size()`
15593 array | result of function `array_t::max_size()`
15594
15595 @liveexample{The following code calls `max_size()` on the different value
15596 types. Note the output is implementation specific.,max_size}
15597
15598 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
15599 the Container concept; that is, their `max_size()` functions have constant
15600 complexity.
15601
15602 @iterators No changes.
15603
15604 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15605
15606 @requirement This function helps `basic_json` satisfying the
15607 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
15608 requirements:
15609 - The complexity is constant.
15610 - Has the semantics of returning `b.size()` where `b` is the largest
15611 possible JSON value.
15612
15613 @sa @ref size() -- returns the number of elements
15614
15615 @since version 1.0.0
15616 */
15617size_type max_size() const noexcept
15618{
15619switch (m_type)
15620{
15621case value_t::array:
15622{
15623// delegate call to array_t::max_size()
15624return m_value.array->max_size();
15625}
15626
15627case value_t::object:
15628{
15629// delegate call to object_t::max_size()
15630return m_value.object->max_size();
15631}
15632
15633default:
15634{
15635// all other types have max_size() == size()
15636return size();
15637}
15638}
15639}
15640
15641/// @}
15642
15643
15644///////////////
15645// modifiers //
15646///////////////
15647
15648/// @name modifiers
15649/// @{
15650
15651/*!
15652 @brief clears the contents
15653
15654 Clears the content of a JSON value and resets it to the default value as
15655 if @ref basic_json(value_t) would have been called with the current value
15656 type from @ref type():
15657
15658 Value type | initial value
15659 ----------- | -------------
15660 null | `null`
15661 boolean | `false`
15662 string | `""`
15663 number | `0`
15664 object | `{}`
15665 array | `[]`
15666
15667 @post Has the same effect as calling
15668 @code {.cpp}
15669 *this = basic_json(type());
15670 @endcode
15671
15672 @liveexample{The example below shows the effect of `clear()` to different
15673 JSON types.,clear}
15674
15675 @complexity Linear in the size of the JSON value.
15676
15677 @iterators All iterators, pointers and references related to this container
15678 are invalidated.
15679
15680 @exceptionsafety No-throw guarantee: this function never throws exceptions.
15681
15682 @sa @ref basic_json(value_t) -- constructor that creates an object with the
15683 same value than calling `clear()`
15684
15685 @since version 1.0.0
15686 */
15687void clear() noexcept
15688{
15689switch (m_type)
15690{
15691case value_t::number_integer:
15692{
15693m_value.number_integer = 0;
15694break;
15695}
15696
15697case value_t::number_unsigned:
15698{
15699m_value.number_unsigned = 0;
15700break;
15701}
15702
15703case value_t::number_float:
15704{
15705m_value.number_float = 0.0;
15706break;
15707}
15708
15709case value_t::boolean:
15710{
15711m_value.boolean = false;
15712break;
15713}
15714
15715case value_t::string:
15716{
15717m_value.string->clear();
15718break;
15719}
15720
15721case value_t::array:
15722{
15723m_value.array->clear();
15724break;
15725}
15726
15727case value_t::object:
15728{
15729m_value.object->clear();
15730break;
15731}
15732
15733default:
15734break;
15735}
15736}
15737
15738/*!
15739 @brief add an object to an array
15740
15741 Appends the given element @a val to the end of the JSON value. If the
15742 function is called on a JSON null value, an empty array is created before
15743 appending @a val.
15744
15745 @param[in] val the value to add to the JSON array
15746
15747 @throw type_error.308 when called on a type other than JSON array or
15748 null; example: `"cannot use push_back() with number"`
15749
15750 @complexity Amortized constant.
15751
15752 @liveexample{The example shows how `push_back()` and `+=` can be used to
15753 add elements to a JSON array. Note how the `null` value was silently
15754 converted to a JSON array.,push_back}
15755
15756 @since version 1.0.0
15757 */
15758void push_back(basic_json&& val)
15759{
15760// push_back only works for null objects or arrays
15761if (JSON_UNLIKELY(not(is_null() or is_array())))
15762{
15763JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15764}
15765
15766// transform null object into an array
15767if (is_null())
15768{
15769m_type = value_t::array;
15770m_value = value_t::array;
15771assert_invariant();
15772}
15773
15774// add element to array (move semantics)
15775m_value.array->push_back(std::move(val));
15776// invalidate object
15777val.m_type = value_t::null;
15778}
15779
15780/*!
15781 @brief add an object to an array
15782 @copydoc push_back(basic_json&&)
15783 */
15784reference operator+=(basic_json&& val)
15785{
15786push_back(std::move(val));
15787return *this;
15788}
15789
15790/*!
15791 @brief add an object to an array
15792 @copydoc push_back(basic_json&&)
15793 */
15794void push_back(const basic_json& val)
15795{
15796// push_back only works for null objects or arrays
15797if (JSON_UNLIKELY(not(is_null() or is_array())))
15798{
15799JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15800}
15801
15802// transform null object into an array
15803if (is_null())
15804{
15805m_type = value_t::array;
15806m_value = value_t::array;
15807assert_invariant();
15808}
15809
15810// add element to array
15811m_value.array->push_back(val);
15812}
15813
15814/*!
15815 @brief add an object to an array
15816 @copydoc push_back(basic_json&&)
15817 */
15818reference operator+=(const basic_json& val)
15819{
15820push_back(val);
15821return *this;
15822}
15823
15824/*!
15825 @brief add an object to an object
15826
15827 Inserts the given element @a val to the JSON object. If the function is
15828 called on a JSON null value, an empty object is created before inserting
15829 @a val.
15830
15831 @param[in] val the value to add to the JSON object
15832
15833 @throw type_error.308 when called on a type other than JSON object or
15834 null; example: `"cannot use push_back() with number"`
15835
15836 @complexity Logarithmic in the size of the container, O(log(`size()`)).
15837
15838 @liveexample{The example shows how `push_back()` and `+=` can be used to
15839 add elements to a JSON object. Note how the `null` value was silently
15840 converted to a JSON object.,push_back__object_t__value}
15841
15842 @since version 1.0.0
15843 */
15844void push_back(const typename object_t::value_type& val)
15845{
15846// push_back only works for null objects or objects
15847if (JSON_UNLIKELY(not(is_null() or is_object())))
15848{
15849JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
15850}
15851
15852// transform null object into an object
15853if (is_null())
15854{
15855m_type = value_t::object;
15856m_value = value_t::object;
15857assert_invariant();
15858}
15859
15860// add element to array
15861m_value.object->insert(val);
15862}
15863
15864/*!
15865 @brief add an object to an object
15866 @copydoc push_back(const typename object_t::value_type&)
15867 */
15868reference operator+=(const typename object_t::value_type& val)
15869{
15870push_back(val);
15871return *this;
15872}
15873
15874/*!
15875 @brief add an object to an object
15876
15877 This function allows to use `push_back` with an initializer list. In case
15878
15879 1. the current value is an object,
15880 2. the initializer list @a init contains only two elements, and
15881 3. the first element of @a init is a string,
15882
15883 @a init is converted into an object element and added using
15884 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
15885 is converted to a JSON value and added using @ref push_back(basic_json&&).
15886
15887 @param[in] init an initializer list
15888
15889 @complexity Linear in the size of the initializer list @a init.
15890
15891 @note This function is required to resolve an ambiguous overload error,
15892 because pairs like `{"key", "value"}` can be both interpreted as
15893 `object_t::value_type` or `std::initializer_list<basic_json>`, see
15894 https://github.com/nlohmann/json/issues/235 for more information.
15895
15896 @liveexample{The example shows how initializer lists are treated as
15897 objects when possible.,push_back__initializer_list}
15898 */
15899void push_back(initializer_list_t init)
15900{
15901if (is_object() and init.size() == 2 and (*init.begin())->is_string())
15902{
15903basic_json&& key = init.begin()->moved_or_copied();
15904push_back(typename object_t::value_type(
15905std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
15906}
15907else
15908{
15909push_back(basic_json(init));
15910}
15911}
15912
15913/*!
15914 @brief add an object to an object
15915 @copydoc push_back(initializer_list_t)
15916 */
15917reference operator+=(initializer_list_t init)
15918{
15919push_back(init);
15920return *this;
15921}
15922
15923/*!
15924 @brief add an object to an array
15925
15926 Creates a JSON value from the passed parameters @a args to the end of the
15927 JSON value. If the function is called on a JSON null value, an empty array
15928 is created before appending the value created from @a args.
15929
15930 @param[in] args arguments to forward to a constructor of @ref basic_json
15931 @tparam Args compatible types to create a @ref basic_json object
15932
15933 @throw type_error.311 when called on a type other than JSON array or
15934 null; example: `"cannot use emplace_back() with number"`
15935
15936 @complexity Amortized constant.
15937
15938 @liveexample{The example shows how `push_back()` can be used to add
15939 elements to a JSON array. Note how the `null` value was silently converted
15940 to a JSON array.,emplace_back}
15941
15942 @since version 2.0.8
15943 */
15944template<class... Args>
15945void emplace_back(Args&& ... args)
15946{
15947// emplace_back only works for null objects or arrays
15948if (JSON_UNLIKELY(not(is_null() or is_array())))
15949{
15950JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
15951}
15952
15953// transform null object into an array
15954if (is_null())
15955{
15956m_type = value_t::array;
15957m_value = value_t::array;
15958assert_invariant();
15959}
15960
15961// add element to array (perfect forwarding)
15962m_value.array->emplace_back(std::forward<Args>(args)...);
15963}
15964
15965/*!
15966 @brief add an object to an object if key does not exist
15967
15968 Inserts a new element into a JSON object constructed in-place with the
15969 given @a args if there is no element with the key in the container. If the
15970 function is called on a JSON null value, an empty object is created before
15971 appending the value created from @a args.
15972
15973 @param[in] args arguments to forward to a constructor of @ref basic_json
15974 @tparam Args compatible types to create a @ref basic_json object
15975
15976 @return a pair consisting of an iterator to the inserted element, or the
15977 already-existing element if no insertion happened, and a bool
15978 denoting whether the insertion took place.
15979
15980 @throw type_error.311 when called on a type other than JSON object or
15981 null; example: `"cannot use emplace() with number"`
15982
15983 @complexity Logarithmic in the size of the container, O(log(`size()`)).
15984
15985 @liveexample{The example shows how `emplace()` can be used to add elements
15986 to a JSON object. Note how the `null` value was silently converted to a
15987 JSON object. Further note how no value is added if there was already one
15988 value stored with the same key.,emplace}
15989
15990 @since version 2.0.8
15991 */
15992template<class... Args>
15993std::pair<iterator, bool> emplace(Args&& ... args)
15994{
15995// emplace only works for null objects or arrays
15996if (JSON_UNLIKELY(not(is_null() or is_object())))
15997{
15998JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
15999}
16000
16001// transform null object into an object
16002if (is_null())
16003{
16004m_type = value_t::object;
16005m_value = value_t::object;
16006assert_invariant();
16007}
16008
16009// add element to array (perfect forwarding)
16010auto res = m_value.object->emplace(std::forward<Args>(args)...);
16011// create result iterator and set iterator to the result of emplace
16012auto it = begin();
16013it.m_it.object_iterator = res.first;
16014
16015// return pair of iterator and boolean
16016return {it, res.second};
16017}
16018
16019/*!
16020 @brief inserts element
16021
16022 Inserts element @a val before iterator @a pos.
16023
16024 @param[in] pos iterator before which the content will be inserted; may be
16025 the end() iterator
16026 @param[in] val element to insert
16027 @return iterator pointing to the inserted @a val.
16028
16029 @throw type_error.309 if called on JSON values other than arrays;
16030 example: `"cannot use insert() with string"`
16031 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16032 example: `"iterator does not fit current value"`
16033
16034 @complexity Constant plus linear in the distance between @a pos and end of
16035 the container.
16036
16037 @liveexample{The example shows how `insert()` is used.,insert}
16038
16039 @since version 1.0.0
16040 */
16041iterator insert(const_iterator pos, const basic_json& val)
16042{
16043// insert only works for arrays
16044if (JSON_LIKELY(is_array()))
16045{
16046// check if iterator pos fits to this JSON value
16047if (JSON_UNLIKELY(pos.m_object != this))
16048{
16049JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16050}
16051
16052// insert to array and return iterator
16053iterator result(this);
16054result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
16055return result;
16056}
16057
16058JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16059}
16060
16061/*!
16062 @brief inserts element
16063 @copydoc insert(const_iterator, const basic_json&)
16064 */
16065iterator insert(const_iterator pos, basic_json&& val)
16066{
16067return insert(pos, val);
16068}
16069
16070/*!
16071 @brief inserts elements
16072
16073 Inserts @a cnt copies of @a val before iterator @a pos.
16074
16075 @param[in] pos iterator before which the content will be inserted; may be
16076 the end() iterator
16077 @param[in] cnt number of copies of @a val to insert
16078 @param[in] val element to insert
16079 @return iterator pointing to the first element inserted, or @a pos if
16080 `cnt==0`
16081
16082 @throw type_error.309 if called on JSON values other than arrays; example:
16083 `"cannot use insert() with string"`
16084 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16085 example: `"iterator does not fit current value"`
16086
16087 @complexity Linear in @a cnt plus linear in the distance between @a pos
16088 and end of the container.
16089
16090 @liveexample{The example shows how `insert()` is used.,insert__count}
16091
16092 @since version 1.0.0
16093 */
16094iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
16095{
16096// insert only works for arrays
16097if (JSON_LIKELY(is_array()))
16098{
16099// check if iterator pos fits to this JSON value
16100if (JSON_UNLIKELY(pos.m_object != this))
16101{
16102JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16103}
16104
16105// insert to array and return iterator
16106iterator result(this);
16107result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
16108return result;
16109}
16110
16111JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16112}
16113
16114/*!
16115 @brief inserts elements
16116
16117 Inserts elements from range `[first, last)` before iterator @a pos.
16118
16119 @param[in] pos iterator before which the content will be inserted; may be
16120 the end() iterator
16121 @param[in] first begin of the range of elements to insert
16122 @param[in] last end of the range of elements to insert
16123
16124 @throw type_error.309 if called on JSON values other than arrays; example:
16125 `"cannot use insert() with string"`
16126 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16127 example: `"iterator does not fit current value"`
16128 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16129 same JSON value; example: `"iterators do not fit"`
16130 @throw invalid_iterator.211 if @a first or @a last are iterators into
16131 container for which insert is called; example: `"passed iterators may not
16132 belong to container"`
16133
16134 @return iterator pointing to the first element inserted, or @a pos if
16135 `first==last`
16136
16137 @complexity Linear in `std::distance(first, last)` plus linear in the
16138 distance between @a pos and end of the container.
16139
16140 @liveexample{The example shows how `insert()` is used.,insert__range}
16141
16142 @since version 1.0.0
16143 */
16144iterator insert(const_iterator pos, const_iterator first, const_iterator last)
16145{
16146// insert only works for arrays
16147if (JSON_UNLIKELY(not is_array()))
16148{
16149JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16150}
16151
16152// check if iterator pos fits to this JSON value
16153if (JSON_UNLIKELY(pos.m_object != this))
16154{
16155JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16156}
16157
16158// check if range iterators belong to the same JSON object
16159if (JSON_UNLIKELY(first.m_object != last.m_object))
16160{
16161JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16162}
16163
16164if (JSON_UNLIKELY(first.m_object == this))
16165{
16166JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
16167}
16168
16169// insert to array and return iterator
16170iterator result(this);
16171result.m_it.array_iterator = m_value.array->insert(
16172pos.m_it.array_iterator,
16173first.m_it.array_iterator,
16174last.m_it.array_iterator);
16175return result;
16176}
16177
16178/*!
16179 @brief inserts elements
16180
16181 Inserts elements from initializer list @a ilist before iterator @a pos.
16182
16183 @param[in] pos iterator before which the content will be inserted; may be
16184 the end() iterator
16185 @param[in] ilist initializer list to insert the values from
16186
16187 @throw type_error.309 if called on JSON values other than arrays; example:
16188 `"cannot use insert() with string"`
16189 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
16190 example: `"iterator does not fit current value"`
16191
16192 @return iterator pointing to the first element inserted, or @a pos if
16193 `ilist` is empty
16194
16195 @complexity Linear in `ilist.size()` plus linear in the distance between
16196 @a pos and end of the container.
16197
16198 @liveexample{The example shows how `insert()` is used.,insert__ilist}
16199
16200 @since version 1.0.0
16201 */
16202iterator insert(const_iterator pos, initializer_list_t ilist)
16203{
16204// insert only works for arrays
16205if (JSON_UNLIKELY(not is_array()))
16206{
16207JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16208}
16209
16210// check if iterator pos fits to this JSON value
16211if (JSON_UNLIKELY(pos.m_object != this))
16212{
16213JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16214}
16215
16216// insert to array and return iterator
16217iterator result(this);
16218result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
16219return result;
16220}
16221
16222/*!
16223 @brief inserts elements
16224
16225 Inserts elements from range `[first, last)`.
16226
16227 @param[in] first begin of the range of elements to insert
16228 @param[in] last end of the range of elements to insert
16229
16230 @throw type_error.309 if called on JSON values other than objects; example:
16231 `"cannot use insert() with string"`
16232 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16233 point to an object; example: `"iterators first and last must point to
16234 objects"`
16235 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16236 same JSON value; example: `"iterators do not fit"`
16237
16238 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
16239 of elements to insert.
16240
16241 @liveexample{The example shows how `insert()` is used.,insert__range_object}
16242
16243 @since version 3.0.0
16244 */
16245void insert(const_iterator first, const_iterator last)
16246{
16247// insert only works for objects
16248if (JSON_UNLIKELY(not is_object()))
16249{
16250JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
16251}
16252
16253// check if range iterators belong to the same JSON object
16254if (JSON_UNLIKELY(first.m_object != last.m_object))
16255{
16256JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16257}
16258
16259// passed iterators must belong to objects
16260if (JSON_UNLIKELY(not first.m_object->is_object()))
16261{
16262JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16263}
16264
16265m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
16266}
16267
16268/*!
16269 @brief updates a JSON object from another object, overwriting existing keys
16270
16271 Inserts all values from JSON object @a j and overwrites existing keys.
16272
16273 @param[in] j JSON object to read values from
16274
16275 @throw type_error.312 if called on JSON values other than objects; example:
16276 `"cannot use update() with string"`
16277
16278 @complexity O(N*log(size() + N)), where N is the number of elements to
16279 insert.
16280
16281 @liveexample{The example shows how `update()` is used.,update}
16282
16283 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16284
16285 @since version 3.0.0
16286 */
16287void update(const_reference j)
16288{
16289// implicitly convert null value to an empty object
16290if (is_null())
16291{
16292m_type = value_t::object;
16293m_value.object = create<object_t>();
16294assert_invariant();
16295}
16296
16297if (JSON_UNLIKELY(not is_object()))
16298{
16299JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16300}
16301if (JSON_UNLIKELY(not j.is_object()))
16302{
16303JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
16304}
16305
16306for (auto it = j.cbegin(); it != j.cend(); ++it)
16307{
16308m_value.object->operator[](it.key()) = it.value();
16309}
16310}
16311
16312/*!
16313 @brief updates a JSON object from another object, overwriting existing keys
16314
16315 Inserts all values from from range `[first, last)` and overwrites existing
16316 keys.
16317
16318 @param[in] first begin of the range of elements to insert
16319 @param[in] last end of the range of elements to insert
16320
16321 @throw type_error.312 if called on JSON values other than objects; example:
16322 `"cannot use update() with string"`
16323 @throw invalid_iterator.202 if iterator @a first or @a last does does not
16324 point to an object; example: `"iterators first and last must point to
16325 objects"`
16326 @throw invalid_iterator.210 if @a first and @a last do not belong to the
16327 same JSON value; example: `"iterators do not fit"`
16328
16329 @complexity O(N*log(size() + N)), where N is the number of elements to
16330 insert.
16331
16332 @liveexample{The example shows how `update()` is used__range.,update}
16333
16334 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
16335
16336 @since version 3.0.0
16337 */
16338void update(const_iterator first, const_iterator last)
16339{
16340// implicitly convert null value to an empty object
16341if (is_null())
16342{
16343m_type = value_t::object;
16344m_value.object = create<object_t>();
16345assert_invariant();
16346}
16347
16348if (JSON_UNLIKELY(not is_object()))
16349{
16350JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
16351}
16352
16353// check if range iterators belong to the same JSON object
16354if (JSON_UNLIKELY(first.m_object != last.m_object))
16355{
16356JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
16357}
16358
16359// passed iterators must belong to objects
16360if (JSON_UNLIKELY(not first.m_object->is_object()
16361or not last.m_object->is_object()))
16362{
16363JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
16364}
16365
16366for (auto it = first; it != last; ++it)
16367{
16368m_value.object->operator[](it.key()) = it.value();
16369}
16370}
16371
16372/*!
16373 @brief exchanges the values
16374
16375 Exchanges the contents of the JSON value with those of @a other. Does not
16376 invoke any move, copy, or swap operations on individual elements. All
16377 iterators and references remain valid. The past-the-end iterator is
16378 invalidated.
16379
16380 @param[in,out] other JSON value to exchange the contents with
16381
16382 @complexity Constant.
16383
16384 @liveexample{The example below shows how JSON values can be swapped with
16385 `swap()`.,swap__reference}
16386
16387 @since version 1.0.0
16388 */
16389void swap(reference other) noexcept (
16390std::is_nothrow_move_constructible<value_t>::value and
16391std::is_nothrow_move_assignable<value_t>::value and
16392std::is_nothrow_move_constructible<json_value>::value and
16393std::is_nothrow_move_assignable<json_value>::value
16394)
16395{
16396std::swap(m_type, other.m_type);
16397std::swap(m_value, other.m_value);
16398assert_invariant();
16399}
16400
16401/*!
16402 @brief exchanges the values
16403
16404 Exchanges the contents of a JSON array with those of @a other. Does not
16405 invoke any move, copy, or swap operations on individual elements. All
16406 iterators and references remain valid. The past-the-end iterator is
16407 invalidated.
16408
16409 @param[in,out] other array to exchange the contents with
16410
16411 @throw type_error.310 when JSON value is not an array; example: `"cannot
16412 use swap() with string"`
16413
16414 @complexity Constant.
16415
16416 @liveexample{The example below shows how arrays can be swapped with
16417 `swap()`.,swap__array_t}
16418
16419 @since version 1.0.0
16420 */
16421void swap(array_t& other)
16422{
16423// swap only works for arrays
16424if (JSON_LIKELY(is_array()))
16425{
16426std::swap(*(m_value.array), other);
16427}
16428else
16429{
16430JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16431}
16432}
16433
16434/*!
16435 @brief exchanges the values
16436
16437 Exchanges the contents of a JSON object with those of @a other. Does not
16438 invoke any move, copy, or swap operations on individual elements. All
16439 iterators and references remain valid. The past-the-end iterator is
16440 invalidated.
16441
16442 @param[in,out] other object to exchange the contents with
16443
16444 @throw type_error.310 when JSON value is not an object; example:
16445 `"cannot use swap() with string"`
16446
16447 @complexity Constant.
16448
16449 @liveexample{The example below shows how objects can be swapped with
16450 `swap()`.,swap__object_t}
16451
16452 @since version 1.0.0
16453 */
16454void swap(object_t& other)
16455{
16456// swap only works for objects
16457if (JSON_LIKELY(is_object()))
16458{
16459std::swap(*(m_value.object), other);
16460}
16461else
16462{
16463JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16464}
16465}
16466
16467/*!
16468 @brief exchanges the values
16469
16470 Exchanges the contents of a JSON string with those of @a other. Does not
16471 invoke any move, copy, or swap operations on individual elements. All
16472 iterators and references remain valid. The past-the-end iterator is
16473 invalidated.
16474
16475 @param[in,out] other string to exchange the contents with
16476
16477 @throw type_error.310 when JSON value is not a string; example: `"cannot
16478 use swap() with boolean"`
16479
16480 @complexity Constant.
16481
16482 @liveexample{The example below shows how strings can be swapped with
16483 `swap()`.,swap__string_t}
16484
16485 @since version 1.0.0
16486 */
16487void swap(string_t& other)
16488{
16489// swap only works for strings
16490if (JSON_LIKELY(is_string()))
16491{
16492std::swap(*(m_value.string), other);
16493}
16494else
16495{
16496JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
16497}
16498}
16499
16500/// @}
16501
16502public:
16503//////////////////////////////////////////
16504// lexicographical comparison operators //
16505//////////////////////////////////////////
16506
16507/// @name lexicographical comparison operators
16508/// @{
16509
16510/*!
16511 @brief comparison: equal
16512
16513 Compares two JSON values for equality according to the following rules:
16514 - Two JSON values are equal if (1) they are from the same type and (2)
16515 their stored values are the same according to their respective
16516 `operator==`.
16517 - Integer and floating-point numbers are automatically converted before
16518 comparison. Note than two NaN values are always treated as unequal.
16519 - Two JSON null values are equal.
16520
16521 @note Floating-point inside JSON values numbers are compared with
16522 `json::number_float_t::operator==` which is `double::operator==` by
16523 default. To compare floating-point while respecting an epsilon, an alternative
16524 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
16525 could be used, for instance
16526 @code {.cpp}
16527 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
16528 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
16529 {
16530 return std::abs(a - b) <= epsilon;
16531 }
16532 @endcode
16533
16534 @note NaN values never compare equal to themselves or to other NaN values.
16535
16536 @param[in] lhs first JSON value to consider
16537 @param[in] rhs second JSON value to consider
16538 @return whether the values @a lhs and @a rhs are equal
16539
16540 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16541
16542 @complexity Linear.
16543
16544 @liveexample{The example demonstrates comparing several JSON
16545 types.,operator__equal}
16546
16547 @since version 1.0.0
16548 */
16549friend bool operator==(const_reference lhs, const_reference rhs) noexcept
16550{
16551const auto lhs_type = lhs.type();
16552const auto rhs_type = rhs.type();
16553
16554if (lhs_type == rhs_type)
16555{
16556switch (lhs_type)
16557{
16558case value_t::array:
16559return (*lhs.m_value.array == *rhs.m_value.array);
16560
16561case value_t::object:
16562return (*lhs.m_value.object == *rhs.m_value.object);
16563
16564case value_t::null:
16565return true;
16566
16567case value_t::string:
16568return (*lhs.m_value.string == *rhs.m_value.string);
16569
16570case value_t::boolean:
16571return (lhs.m_value.boolean == rhs.m_value.boolean);
16572
16573case value_t::number_integer:
16574return (lhs.m_value.number_integer == rhs.m_value.number_integer);
16575
16576case value_t::number_unsigned:
16577return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
16578
16579case value_t::number_float:
16580return (lhs.m_value.number_float == rhs.m_value.number_float);
16581
16582default:
16583return false;
16584}
16585}
16586else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16587{
16588return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
16589}
16590else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16591{
16592return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
16593}
16594else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16595{
16596return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
16597}
16598else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16599{
16600return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
16601}
16602else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16603{
16604return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
16605}
16606else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16607{
16608return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
16609}
16610
16611return false;
16612}
16613
16614/*!
16615 @brief comparison: equal
16616 @copydoc operator==(const_reference, const_reference)
16617 */
16618template<typename ScalarType, typename std::enable_if<
16619std::is_scalar<ScalarType>::value, int>::type = 0>
16620friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
16621{
16622return (lhs == basic_json(rhs));
16623}
16624
16625/*!
16626 @brief comparison: equal
16627 @copydoc operator==(const_reference, const_reference)
16628 */
16629template<typename ScalarType, typename std::enable_if<
16630std::is_scalar<ScalarType>::value, int>::type = 0>
16631friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
16632{
16633return (basic_json(lhs) == rhs);
16634}
16635
16636/*!
16637 @brief comparison: not equal
16638
16639 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
16640
16641 @param[in] lhs first JSON value to consider
16642 @param[in] rhs second JSON value to consider
16643 @return whether the values @a lhs and @a rhs are not equal
16644
16645 @complexity Linear.
16646
16647 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16648
16649 @liveexample{The example demonstrates comparing several JSON
16650 types.,operator__notequal}
16651
16652 @since version 1.0.0
16653 */
16654friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
16655{
16656return not (lhs == rhs);
16657}
16658
16659/*!
16660 @brief comparison: not equal
16661 @copydoc operator!=(const_reference, const_reference)
16662 */
16663template<typename ScalarType, typename std::enable_if<
16664std::is_scalar<ScalarType>::value, int>::type = 0>
16665friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
16666{
16667return (lhs != basic_json(rhs));
16668}
16669
16670/*!
16671 @brief comparison: not equal
16672 @copydoc operator!=(const_reference, const_reference)
16673 */
16674template<typename ScalarType, typename std::enable_if<
16675std::is_scalar<ScalarType>::value, int>::type = 0>
16676friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
16677{
16678return (basic_json(lhs) != rhs);
16679}
16680
16681/*!
16682 @brief comparison: less than
16683
16684 Compares whether one JSON value @a lhs is less than another JSON value @a
16685 rhs according to the following rules:
16686 - If @a lhs and @a rhs have the same type, the values are compared using
16687 the default `<` operator.
16688 - Integer and floating-point numbers are automatically converted before
16689 comparison
16690 - In case @a lhs and @a rhs have different types, the values are ignored
16691 and the order of the types is considered, see
16692 @ref operator<(const value_t, const value_t).
16693
16694 @param[in] lhs first JSON value to consider
16695 @param[in] rhs second JSON value to consider
16696 @return whether @a lhs is less than @a rhs
16697
16698 @complexity Linear.
16699
16700 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16701
16702 @liveexample{The example demonstrates comparing several JSON
16703 types.,operator__less}
16704
16705 @since version 1.0.0
16706 */
16707friend bool operator<(const_reference lhs, const_reference rhs) noexcept
16708{
16709const auto lhs_type = lhs.type();
16710const auto rhs_type = rhs.type();
16711
16712if (lhs_type == rhs_type)
16713{
16714switch (lhs_type)
16715{
16716case value_t::array:
16717return (*lhs.m_value.array) < (*rhs.m_value.array);
16718
16719case value_t::object:
16720return *lhs.m_value.object < *rhs.m_value.object;
16721
16722case value_t::null:
16723return false;
16724
16725case value_t::string:
16726return *lhs.m_value.string < *rhs.m_value.string;
16727
16728case value_t::boolean:
16729return lhs.m_value.boolean < rhs.m_value.boolean;
16730
16731case value_t::number_integer:
16732return lhs.m_value.number_integer < rhs.m_value.number_integer;
16733
16734case value_t::number_unsigned:
16735return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
16736
16737case value_t::number_float:
16738return lhs.m_value.number_float < rhs.m_value.number_float;
16739
16740default:
16741return false;
16742}
16743}
16744else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
16745{
16746return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
16747}
16748else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
16749{
16750return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
16751}
16752else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
16753{
16754return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
16755}
16756else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
16757{
16758return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
16759}
16760else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
16761{
16762return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
16763}
16764else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
16765{
16766return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
16767}
16768
16769// We only reach this line if we cannot compare values. In that case,
16770// we compare types. Note we have to call the operator explicitly,
16771// because MSVC has problems otherwise.
16772return operator<(lhs_type, rhs_type);
16773}
16774
16775/*!
16776 @brief comparison: less than
16777 @copydoc operator<(const_reference, const_reference)
16778 */
16779template<typename ScalarType, typename std::enable_if<
16780std::is_scalar<ScalarType>::value, int>::type = 0>
16781friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
16782{
16783return (lhs < basic_json(rhs));
16784}
16785
16786/*!
16787 @brief comparison: less than
16788 @copydoc operator<(const_reference, const_reference)
16789 */
16790template<typename ScalarType, typename std::enable_if<
16791std::is_scalar<ScalarType>::value, int>::type = 0>
16792friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
16793{
16794return (basic_json(lhs) < rhs);
16795}
16796
16797/*!
16798 @brief comparison: less than or equal
16799
16800 Compares whether one JSON value @a lhs is less than or equal to another
16801 JSON value by calculating `not (rhs < lhs)`.
16802
16803 @param[in] lhs first JSON value to consider
16804 @param[in] rhs second JSON value to consider
16805 @return whether @a lhs is less than or equal to @a rhs
16806
16807 @complexity Linear.
16808
16809 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16810
16811 @liveexample{The example demonstrates comparing several JSON
16812 types.,operator__greater}
16813
16814 @since version 1.0.0
16815 */
16816friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
16817{
16818return not (rhs < lhs);
16819}
16820
16821/*!
16822 @brief comparison: less than or equal
16823 @copydoc operator<=(const_reference, const_reference)
16824 */
16825template<typename ScalarType, typename std::enable_if<
16826std::is_scalar<ScalarType>::value, int>::type = 0>
16827friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
16828{
16829return (lhs <= basic_json(rhs));
16830}
16831
16832/*!
16833 @brief comparison: less than or equal
16834 @copydoc operator<=(const_reference, const_reference)
16835 */
16836template<typename ScalarType, typename std::enable_if<
16837std::is_scalar<ScalarType>::value, int>::type = 0>
16838friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
16839{
16840return (basic_json(lhs) <= rhs);
16841}
16842
16843/*!
16844 @brief comparison: greater than
16845
16846 Compares whether one JSON value @a lhs is greater than another
16847 JSON value by calculating `not (lhs <= rhs)`.
16848
16849 @param[in] lhs first JSON value to consider
16850 @param[in] rhs second JSON value to consider
16851 @return whether @a lhs is greater than to @a rhs
16852
16853 @complexity Linear.
16854
16855 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16856
16857 @liveexample{The example demonstrates comparing several JSON
16858 types.,operator__lessequal}
16859
16860 @since version 1.0.0
16861 */
16862friend bool operator>(const_reference lhs, const_reference rhs) noexcept
16863{
16864return not (lhs <= rhs);
16865}
16866
16867/*!
16868 @brief comparison: greater than
16869 @copydoc operator>(const_reference, const_reference)
16870 */
16871template<typename ScalarType, typename std::enable_if<
16872std::is_scalar<ScalarType>::value, int>::type = 0>
16873friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
16874{
16875return (lhs > basic_json(rhs));
16876}
16877
16878/*!
16879 @brief comparison: greater than
16880 @copydoc operator>(const_reference, const_reference)
16881 */
16882template<typename ScalarType, typename std::enable_if<
16883std::is_scalar<ScalarType>::value, int>::type = 0>
16884friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
16885{
16886return (basic_json(lhs) > rhs);
16887}
16888
16889/*!
16890 @brief comparison: greater than or equal
16891
16892 Compares whether one JSON value @a lhs is greater than or equal to another
16893 JSON value by calculating `not (lhs < rhs)`.
16894
16895 @param[in] lhs first JSON value to consider
16896 @param[in] rhs second JSON value to consider
16897 @return whether @a lhs is greater than or equal to @a rhs
16898
16899 @complexity Linear.
16900
16901 @exceptionsafety No-throw guarantee: this function never throws exceptions.
16902
16903 @liveexample{The example demonstrates comparing several JSON
16904 types.,operator__greaterequal}
16905
16906 @since version 1.0.0
16907 */
16908friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
16909{
16910return not (lhs < rhs);
16911}
16912
16913/*!
16914 @brief comparison: greater than or equal
16915 @copydoc operator>=(const_reference, const_reference)
16916 */
16917template<typename ScalarType, typename std::enable_if<
16918std::is_scalar<ScalarType>::value, int>::type = 0>
16919friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
16920{
16921return (lhs >= basic_json(rhs));
16922}
16923
16924/*!
16925 @brief comparison: greater than or equal
16926 @copydoc operator>=(const_reference, const_reference)
16927 */
16928template<typename ScalarType, typename std::enable_if<
16929std::is_scalar<ScalarType>::value, int>::type = 0>
16930friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
16931{
16932return (basic_json(lhs) >= rhs);
16933}
16934
16935/// @}
16936
16937///////////////////
16938// serialization //
16939///////////////////
16940
16941/// @name serialization
16942/// @{
16943
16944/*!
16945 @brief serialize to stream
16946
16947 Serialize the given JSON value @a j to the output stream @a o. The JSON
16948 value will be serialized using the @ref dump member function.
16949
16950 - The indentation of the output can be controlled with the member variable
16951 `width` of the output stream @a o. For instance, using the manipulator
16952 `std::setw(4)` on @a o sets the indentation level to `4` and the
16953 serialization result is the same as calling `dump(4)`.
16954
16955 - The indentation character can be controlled with the member variable
16956 `fill` of the output stream @a o. For instance, the manipulator
16957 `std::setfill('\\t')` sets indentation to use a tab character rather than
16958 the default space character.
16959
16960 @param[in,out] o stream to serialize to
16961 @param[in] j JSON value to serialize
16962
16963 @return the stream @a o
16964
16965 @throw type_error.316 if a string stored inside the JSON value is not
16966 UTF-8 encoded
16967
16968 @complexity Linear.
16969
16970 @liveexample{The example below shows the serialization with different
16971 parameters to `width` to adjust the indentation level.,operator_serialize}
16972
16973 @since version 1.0.0; indentation character added in version 3.0.0
16974 */
16975friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
16976{
16977// read width member and use it as indentation parameter if nonzero
16978const bool pretty_print = (o.width() > 0);
16979const auto indentation = (pretty_print ? o.width() : 0);
16980
16981// reset width to 0 for subsequent calls to this stream
16982o.width(0);
16983
16984// do the actual serialization
16985serializer s(detail::output_adapter<char>(o), o.fill());
16986s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
16987return o;
16988}
16989
16990/*!
16991 @brief serialize to stream
16992 @deprecated This stream operator is deprecated and will be removed in
16993 future 4.0.0 of the library. Please use
16994 @ref operator<<(std::ostream&, const basic_json&)
16995 instead; that is, replace calls like `j >> o;` with `o << j;`.
16996 @since version 1.0.0; deprecated since version 3.0.0
16997 */
16998JSON_DEPRECATED
16999friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
17000{
17001return o << j;
17002}
17003
17004/// @}
17005
17006
17007/////////////////////
17008// deserialization //
17009/////////////////////
17010
17011/// @name deserialization
17012/// @{
17013
17014/*!
17015 @brief deserialize from a compatible input
17016
17017 This function reads from a compatible input. Examples are:
17018 - an array of 1-byte values
17019 - strings with character/literal type with size of 1 byte
17020 - input streams
17021 - container with contiguous storage of 1-byte values. Compatible container
17022 types include `std::vector`, `std::string`, `std::array`,
17023 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17024 arrays can be used with `std::begin()`/`std::end()`. User-defined
17025 containers can be used as long as they implement random-access iterators
17026 and a contiguous storage.
17027
17028 @pre Each element of the container has a size of 1 byte. Violating this
17029 precondition yields undefined behavior. **This precondition is enforced
17030 with a static assertion.**
17031
17032 @pre The container storage is contiguous. Violating this precondition
17033 yields undefined behavior. **This precondition is enforced with an
17034 assertion.**
17035 @pre Each element of the container has a size of 1 byte. Violating this
17036 precondition yields undefined behavior. **This precondition is enforced
17037 with a static assertion.**
17038
17039 @warning There is no way to enforce all preconditions at compile-time. If
17040 the function is called with a noncompliant container and with
17041 assertions switched off, the behavior is undefined and will most
17042 likely yield segmentation violation.
17043
17044 @param[in] i input to read from
17045 @param[in] cb a parser callback function of type @ref parser_callback_t
17046 which is used to control the deserialization by filtering unwanted values
17047 (optional)
17048
17049 @return result of the deserialization
17050
17051 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17052 of input; expected string literal""`
17053 @throw parse_error.102 if to_unicode fails or surrogate error
17054 @throw parse_error.103 if to_unicode fails
17055
17056 @complexity Linear in the length of the input. The parser is a predictive
17057 LL(1) parser. The complexity can be higher if the parser callback function
17058 @a cb has a super-linear complexity.
17059
17060 @note A UTF-8 byte order mark is silently ignored.
17061
17062 @liveexample{The example below demonstrates the `parse()` function reading
17063 from an array.,parse__array__parser_callback_t}
17064
17065 @liveexample{The example below demonstrates the `parse()` function with
17066 and without callback function.,parse__string__parser_callback_t}
17067
17068 @liveexample{The example below demonstrates the `parse()` function with
17069 and without callback function.,parse__istream__parser_callback_t}
17070
17071 @liveexample{The example below demonstrates the `parse()` function reading
17072 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
17073
17074 @since version 2.0.3 (contiguous containers)
17075 */
17076static basic_json parse(detail::input_adapter&& i,
17077const parser_callback_t cb = nullptr,
17078const bool allow_exceptions = true)
17079{
17080basic_json result;
17081parser(i, cb, allow_exceptions).parse(true, result);
17082return result;
17083}
17084
17085static bool accept(detail::input_adapter&& i)
17086{
17087return parser(i).accept(true);
17088}
17089
17090/*!
17091 @brief generate SAX events
17092
17093 The SAX event lister must follow the interface of @ref json_sax.
17094
17095 This function reads from a compatible input. Examples are:
17096 - an array of 1-byte values
17097 - strings with character/literal type with size of 1 byte
17098 - input streams
17099 - container with contiguous storage of 1-byte values. Compatible container
17100 types include `std::vector`, `std::string`, `std::array`,
17101 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
17102 arrays can be used with `std::begin()`/`std::end()`. User-defined
17103 containers can be used as long as they implement random-access iterators
17104 and a contiguous storage.
17105
17106 @pre Each element of the container has a size of 1 byte. Violating this
17107 precondition yields undefined behavior. **This precondition is enforced
17108 with a static assertion.**
17109
17110 @pre The container storage is contiguous. Violating this precondition
17111 yields undefined behavior. **This precondition is enforced with an
17112 assertion.**
17113 @pre Each element of the container has a size of 1 byte. Violating this
17114 precondition yields undefined behavior. **This precondition is enforced
17115 with a static assertion.**
17116
17117 @warning There is no way to enforce all preconditions at compile-time. If
17118 the function is called with a noncompliant container and with
17119 assertions switched off, the behavior is undefined and will most
17120 likely yield segmentation violation.
17121
17122 @param[in] i input to read from
17123 @param[in,out] sax SAX event listener
17124 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
17125 @param[in] strict whether the input has to be consumed completely
17126
17127 @return return value of the last processed SAX event
17128
17129 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
17130 of input; expected string literal""`
17131 @throw parse_error.102 if to_unicode fails or surrogate error
17132 @throw parse_error.103 if to_unicode fails
17133
17134 @complexity Linear in the length of the input. The parser is a predictive
17135 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
17136 a super-linear complexity.
17137
17138 @note A UTF-8 byte order mark is silently ignored.
17139
17140 @liveexample{The example below demonstrates the `sax_parse()` function
17141 reading from string and processing the events with a user-defined SAX
17142 event consumer.,sax_parse}
17143
17144 @since version 3.2.0
17145 */
17146template <typename SAX>
17147static bool sax_parse(detail::input_adapter&& i, SAX* sax,
17148input_format_t format = input_format_t::json,
17149const bool strict = true)
17150{
17151assert(sax);
17152switch (format)
17153{
17154case input_format_t::json:
17155return parser(std::move(i)).sax_parse(sax, strict);
17156default:
17157return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
17158}
17159}
17160
17161/*!
17162 @brief deserialize from an iterator range with contiguous storage
17163
17164 This function reads from an iterator range of a container with contiguous
17165 storage of 1-byte values. Compatible container types include
17166 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
17167 `std::initializer_list`. Furthermore, C-style arrays can be used with
17168 `std::begin()`/`std::end()`. User-defined containers can be used as long
17169 as they implement random-access iterators and a contiguous storage.
17170
17171 @pre The iterator range is contiguous. Violating this precondition yields
17172 undefined behavior. **This precondition is enforced with an assertion.**
17173 @pre Each element in the range has a size of 1 byte. Violating this
17174 precondition yields undefined behavior. **This precondition is enforced
17175 with a static assertion.**
17176
17177 @warning There is no way to enforce all preconditions at compile-time. If
17178 the function is called with noncompliant iterators and with
17179 assertions switched off, the behavior is undefined and will most
17180 likely yield segmentation violation.
17181
17182 @tparam IteratorType iterator of container with contiguous storage
17183 @param[in] first begin of the range to parse (included)
17184 @param[in] last end of the range to parse (excluded)
17185 @param[in] cb a parser callback function of type @ref parser_callback_t
17186 which is used to control the deserialization by filtering unwanted values
17187 (optional)
17188 @param[in] allow_exceptions whether to throw exceptions in case of a
17189 parse error (optional, true by default)
17190
17191 @return result of the deserialization
17192
17193 @throw parse_error.101 in case of an unexpected token
17194 @throw parse_error.102 if to_unicode fails or surrogate error
17195 @throw parse_error.103 if to_unicode fails
17196
17197 @complexity Linear in the length of the input. The parser is a predictive
17198 LL(1) parser. The complexity can be higher if the parser callback function
17199 @a cb has a super-linear complexity.
17200
17201 @note A UTF-8 byte order mark is silently ignored.
17202
17203 @liveexample{The example below demonstrates the `parse()` function reading
17204 from an iterator range.,parse__iteratortype__parser_callback_t}
17205
17206 @since version 2.0.3
17207 */
17208template<class IteratorType, typename std::enable_if<
17209std::is_base_of<
17210std::random_access_iterator_tag,
17211typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
17212static basic_json parse(IteratorType first, IteratorType last,
17213const parser_callback_t cb = nullptr,
17214const bool allow_exceptions = true)
17215{
17216basic_json result;
17217parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
17218return result;
17219}
17220
17221template<class IteratorType, typename std::enable_if<
17222std::is_base_of<
17223std::random_access_iterator_tag,
17224typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
17225static bool accept(IteratorType first, IteratorType last)
17226{
17227return parser(detail::input_adapter(first, last)).accept(true);
17228}
17229
17230template<class IteratorType, class SAX, typename std::enable_if<
17231std::is_base_of<
17232std::random_access_iterator_tag,
17233typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
17234static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
17235{
17236return parser(detail::input_adapter(first, last)).sax_parse(sax);
17237}
17238
17239/*!
17240 @brief deserialize from stream
17241 @deprecated This stream operator is deprecated and will be removed in
17242 version 4.0.0 of the library. Please use
17243 @ref operator>>(std::istream&, basic_json&)
17244 instead; that is, replace calls like `j << i;` with `i >> j;`.
17245 @since version 1.0.0; deprecated since version 3.0.0
17246 */
17247JSON_DEPRECATED
17248friend std::istream& operator<<(basic_json& j, std::istream& i)
17249{
17250return operator>>(i, j);
17251}
17252
17253/*!
17254 @brief deserialize from stream
17255
17256 Deserializes an input stream to a JSON value.
17257
17258 @param[in,out] i input stream to read a serialized JSON value from
17259 @param[in,out] j JSON value to write the deserialized input to
17260
17261 @throw parse_error.101 in case of an unexpected token
17262 @throw parse_error.102 if to_unicode fails or surrogate error
17263 @throw parse_error.103 if to_unicode fails
17264
17265 @complexity Linear in the length of the input. The parser is a predictive
17266 LL(1) parser.
17267
17268 @note A UTF-8 byte order mark is silently ignored.
17269
17270 @liveexample{The example below shows how a JSON value is constructed by
17271 reading a serialization from a stream.,operator_deserialize}
17272
17273 @sa parse(std::istream&, const parser_callback_t) for a variant with a
17274 parser callback function to filter values while parsing
17275
17276 @since version 1.0.0
17277 */
17278friend std::istream& operator>>(std::istream& i, basic_json& j)
17279{
17280parser(detail::input_adapter(i)).parse(false, j);
17281return i;
17282}
17283
17284/// @}
17285
17286///////////////////////////
17287// convenience functions //
17288///////////////////////////
17289
17290/*!
17291 @brief return the type as string
17292
17293 Returns the type name as string to be used in error messages - usually to
17294 indicate that a function was called on a wrong JSON type.
17295
17296 @return a string representation of a the @a m_type member:
17297 Value type | return value
17298 ----------- | -------------
17299 null | `"null"`
17300 boolean | `"boolean"`
17301 string | `"string"`
17302 number | `"number"` (for all number types)
17303 object | `"object"`
17304 array | `"array"`
17305 discarded | `"discarded"`
17306
17307 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17308
17309 @complexity Constant.
17310
17311 @liveexample{The following code exemplifies `type_name()` for all JSON
17312 types.,type_name}
17313
17314 @sa @ref type() -- return the type of the JSON value
17315 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
17316
17317 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
17318 since 3.0.0
17319 */
17320const char* type_name() const noexcept
17321{
17322{
17323switch (m_type)
17324{
17325case value_t::null:
17326return "null";
17327case value_t::object:
17328return "object";
17329case value_t::array:
17330return "array";
17331case value_t::string:
17332return "string";
17333case value_t::boolean:
17334return "boolean";
17335case value_t::discarded:
17336return "discarded";
17337default:
17338return "number";
17339}
17340}
17341}
17342
17343
17344private:
17345//////////////////////
17346// member variables //
17347//////////////////////
17348
17349/// the type of the current element
17350value_t m_type = value_t::null;
17351
17352/// the value of the current element
17353json_value m_value = {};
17354
17355//////////////////////////////////////////
17356// binary serialization/deserialization //
17357//////////////////////////////////////////
17358
17359/// @name binary serialization/deserialization support
17360/// @{
17361
17362public:
17363/*!
17364 @brief create a CBOR serialization of a given JSON value
17365
17366 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
17367 Binary Object Representation) serialization format. CBOR is a binary
17368 serialization format which aims to be more compact than JSON itself, yet
17369 more efficient to parse.
17370
17371 The library uses the following mapping from JSON values types to
17372 CBOR types according to the CBOR specification (RFC 7049):
17373
17374 JSON value type | value/range | CBOR type | first byte
17375 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
17376 null | `null` | Null | 0xF6
17377 boolean | `true` | True | 0xF5
17378 boolean | `false` | False | 0xF4
17379 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
17380 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
17381 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
17382 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
17383 number_integer | -24..-1 | Negative integer | 0x20..0x37
17384 number_integer | 0..23 | Integer | 0x00..0x17
17385 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
17386 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17387 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17388 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17389 number_unsigned | 0..23 | Integer | 0x00..0x17
17390 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
17391 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
17392 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
17393 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
17394 number_float | *any value* | Double-Precision Float | 0xFB
17395 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
17396 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
17397 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
17398 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
17399 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
17400 array | *size*: 0..23 | array | 0x80..0x97
17401 array | *size*: 23..255 | array (1 byte follow) | 0x98
17402 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
17403 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
17404 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
17405 object | *size*: 0..23 | map | 0xA0..0xB7
17406 object | *size*: 23..255 | map (1 byte follow) | 0xB8
17407 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
17408 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
17409 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
17410
17411 @note The mapping is **complete** in the sense that any JSON value type
17412 can be converted to a CBOR value.
17413
17414 @note If NaN or Infinity are stored inside a JSON number, they are
17415 serialized properly. This behavior differs from the @ref dump()
17416 function which serializes NaN or Infinity to `null`.
17417
17418 @note The following CBOR types are not used in the conversion:
17419 - byte strings (0x40..0x5F)
17420 - UTF-8 strings terminated by "break" (0x7F)
17421 - arrays terminated by "break" (0x9F)
17422 - maps terminated by "break" (0xBF)
17423 - date/time (0xC0..0xC1)
17424 - bignum (0xC2..0xC3)
17425 - decimal fraction (0xC4)
17426 - bigfloat (0xC5)
17427 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17428 - expected conversions (0xD5..0xD7)
17429 - simple values (0xE0..0xF3, 0xF8)
17430 - undefined (0xF7)
17431 - half and single-precision floats (0xF9-0xFA)
17432 - break (0xFF)
17433
17434 @param[in] j JSON value to serialize
17435 @return MessagePack serialization as byte vector
17436
17437 @complexity Linear in the size of the JSON value @a j.
17438
17439 @liveexample{The example shows the serialization of a JSON value to a byte
17440 vector in CBOR format.,to_cbor}
17441
17442 @sa http://cbor.io
17443 @sa @ref from_cbor(detail::input_adapter, const bool strict) for the
17444 analogous deserialization
17445 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17446 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17447 related UBJSON format
17448
17449 @since version 2.0.9
17450 */
17451static std::vector<uint8_t> to_cbor(const basic_json& j)
17452{
17453std::vector<uint8_t> result;
17454to_cbor(j, result);
17455return result;
17456}
17457
17458static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
17459{
17460binary_writer<uint8_t>(o).write_cbor(j);
17461}
17462
17463static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
17464{
17465binary_writer<char>(o).write_cbor(j);
17466}
17467
17468/*!
17469 @brief create a MessagePack serialization of a given JSON value
17470
17471 Serializes a given JSON value @a j to a byte vector using the MessagePack
17472 serialization format. MessagePack is a binary serialization format which
17473 aims to be more compact than JSON itself, yet more efficient to parse.
17474
17475 The library uses the following mapping from JSON values types to
17476 MessagePack types according to the MessagePack specification:
17477
17478 JSON value type | value/range | MessagePack type | first byte
17479 --------------- | --------------------------------- | ---------------- | ----------
17480 null | `null` | nil | 0xC0
17481 boolean | `true` | true | 0xC3
17482 boolean | `false` | false | 0xC2
17483 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
17484 number_integer | -2147483648..-32769 | int32 | 0xD2
17485 number_integer | -32768..-129 | int16 | 0xD1
17486 number_integer | -128..-33 | int8 | 0xD0
17487 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
17488 number_integer | 0..127 | positive fixint | 0x00..0x7F
17489 number_integer | 128..255 | uint 8 | 0xCC
17490 number_integer | 256..65535 | uint 16 | 0xCD
17491 number_integer | 65536..4294967295 | uint 32 | 0xCE
17492 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
17493 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
17494 number_unsigned | 128..255 | uint 8 | 0xCC
17495 number_unsigned | 256..65535 | uint 16 | 0xCD
17496 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
17497 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
17498 number_float | *any value* | float 64 | 0xCB
17499 string | *length*: 0..31 | fixstr | 0xA0..0xBF
17500 string | *length*: 32..255 | str 8 | 0xD9
17501 string | *length*: 256..65535 | str 16 | 0xDA
17502 string | *length*: 65536..4294967295 | str 32 | 0xDB
17503 array | *size*: 0..15 | fixarray | 0x90..0x9F
17504 array | *size*: 16..65535 | array 16 | 0xDC
17505 array | *size*: 65536..4294967295 | array 32 | 0xDD
17506 object | *size*: 0..15 | fix map | 0x80..0x8F
17507 object | *size*: 16..65535 | map 16 | 0xDE
17508 object | *size*: 65536..4294967295 | map 32 | 0xDF
17509
17510 @note The mapping is **complete** in the sense that any JSON value type
17511 can be converted to a MessagePack value.
17512
17513 @note The following values can **not** be converted to a MessagePack value:
17514 - strings with more than 4294967295 bytes
17515 - arrays with more than 4294967295 elements
17516 - objects with more than 4294967295 elements
17517
17518 @note The following MessagePack types are not used in the conversion:
17519 - bin 8 - bin 32 (0xC4..0xC6)
17520 - ext 8 - ext 32 (0xC7..0xC9)
17521 - float 32 (0xCA)
17522 - fixext 1 - fixext 16 (0xD4..0xD8)
17523
17524 @note Any MessagePack output created @ref to_msgpack can be successfully
17525 parsed by @ref from_msgpack.
17526
17527 @note If NaN or Infinity are stored inside a JSON number, they are
17528 serialized properly. This behavior differs from the @ref dump()
17529 function which serializes NaN or Infinity to `null`.
17530
17531 @param[in] j JSON value to serialize
17532 @return MessagePack serialization as byte vector
17533
17534 @complexity Linear in the size of the JSON value @a j.
17535
17536 @liveexample{The example shows the serialization of a JSON value to a byte
17537 vector in MessagePack format.,to_msgpack}
17538
17539 @sa http://msgpack.org
17540 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
17541 analogous deserialization
17542 @sa @ref to_cbor(const basic_json& for the related CBOR format
17543 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17544 related UBJSON format
17545
17546 @since version 2.0.9
17547 */
17548static std::vector<uint8_t> to_msgpack(const basic_json& j)
17549{
17550std::vector<uint8_t> result;
17551to_msgpack(j, result);
17552return result;
17553}
17554
17555static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
17556{
17557binary_writer<uint8_t>(o).write_msgpack(j);
17558}
17559
17560static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
17561{
17562binary_writer<char>(o).write_msgpack(j);
17563}
17564
17565/*!
17566 @brief create a UBJSON serialization of a given JSON value
17567
17568 Serializes a given JSON value @a j to a byte vector using the UBJSON
17569 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
17570 than JSON itself, yet more efficient to parse.
17571
17572 The library uses the following mapping from JSON values types to
17573 UBJSON types according to the UBJSON specification:
17574
17575 JSON value type | value/range | UBJSON type | marker
17576 --------------- | --------------------------------- | ----------- | ------
17577 null | `null` | null | `Z`
17578 boolean | `true` | true | `T`
17579 boolean | `false` | false | `F`
17580 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
17581 number_integer | -2147483648..-32769 | int32 | `l`
17582 number_integer | -32768..-129 | int16 | `I`
17583 number_integer | -128..127 | int8 | `i`
17584 number_integer | 128..255 | uint8 | `U`
17585 number_integer | 256..32767 | int16 | `I`
17586 number_integer | 32768..2147483647 | int32 | `l`
17587 number_integer | 2147483648..9223372036854775807 | int64 | `L`
17588 number_unsigned | 0..127 | int8 | `i`
17589 number_unsigned | 128..255 | uint8 | `U`
17590 number_unsigned | 256..32767 | int16 | `I`
17591 number_unsigned | 32768..2147483647 | int32 | `l`
17592 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
17593 number_float | *any value* | float64 | `D`
17594 string | *with shortest length indicator* | string | `S`
17595 array | *see notes on optimized format* | array | `[`
17596 object | *see notes on optimized format* | map | `{`
17597
17598 @note The mapping is **complete** in the sense that any JSON value type
17599 can be converted to a UBJSON value.
17600
17601 @note The following values can **not** be converted to a UBJSON value:
17602 - strings with more than 9223372036854775807 bytes (theoretical)
17603 - unsigned integer numbers above 9223372036854775807
17604
17605 @note The following markers are not used in the conversion:
17606 - `Z`: no-op values are not created.
17607 - `C`: single-byte strings are serialized with `S` markers.
17608
17609 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
17610 by @ref from_ubjson.
17611
17612 @note If NaN or Infinity are stored inside a JSON number, they are
17613 serialized properly. This behavior differs from the @ref dump()
17614 function which serializes NaN or Infinity to `null`.
17615
17616 @note The optimized formats for containers are supported: Parameter
17617 @a use_size adds size information to the beginning of a container and
17618 removes the closing marker. Parameter @a use_type further checks
17619 whether all elements of a container have the same type and adds the
17620 type marker to the beginning of the container. The @a use_type
17621 parameter must only be used together with @a use_size = true. Note
17622 that @a use_size = true alone may result in larger representations -
17623 the benefit of this parameter is that the receiving side is
17624 immediately informed on the number of elements of the container.
17625
17626 @param[in] j JSON value to serialize
17627 @param[in] use_size whether to add size annotations to container types
17628 @param[in] use_type whether to add type annotations to container types
17629 (must be combined with @a use_size = true)
17630 @return UBJSON serialization as byte vector
17631
17632 @complexity Linear in the size of the JSON value @a j.
17633
17634 @liveexample{The example shows the serialization of a JSON value to a byte
17635 vector in UBJSON format.,to_ubjson}
17636
17637 @sa http://ubjson.org
17638 @sa @ref from_ubjson(detail::input_adapter, const bool strict) for the
17639 analogous deserialization
17640 @sa @ref to_cbor(const basic_json& for the related CBOR format
17641 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
17642
17643 @since version 3.1.0
17644 */
17645static std::vector<uint8_t> to_ubjson(const basic_json& j,
17646const bool use_size = false,
17647const bool use_type = false)
17648{
17649std::vector<uint8_t> result;
17650to_ubjson(j, result, use_size, use_type);
17651return result;
17652}
17653
17654static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
17655const bool use_size = false, const bool use_type = false)
17656{
17657binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
17658}
17659
17660static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
17661const bool use_size = false, const bool use_type = false)
17662{
17663binary_writer<char>(o).write_ubjson(j, use_size, use_type);
17664}
17665
17666/*!
17667 @brief create a JSON value from an input in CBOR format
17668
17669 Deserializes a given input @a i to a JSON value using the CBOR (Concise
17670 Binary Object Representation) serialization format.
17671
17672 The library maps CBOR types to JSON value types as follows:
17673
17674 CBOR type | JSON value type | first byte
17675 ---------------------- | --------------- | ----------
17676 Integer | number_unsigned | 0x00..0x17
17677 Unsigned integer | number_unsigned | 0x18
17678 Unsigned integer | number_unsigned | 0x19
17679 Unsigned integer | number_unsigned | 0x1A
17680 Unsigned integer | number_unsigned | 0x1B
17681 Negative integer | number_integer | 0x20..0x37
17682 Negative integer | number_integer | 0x38
17683 Negative integer | number_integer | 0x39
17684 Negative integer | number_integer | 0x3A
17685 Negative integer | number_integer | 0x3B
17686 Negative integer | number_integer | 0x40..0x57
17687 UTF-8 string | string | 0x60..0x77
17688 UTF-8 string | string | 0x78
17689 UTF-8 string | string | 0x79
17690 UTF-8 string | string | 0x7A
17691 UTF-8 string | string | 0x7B
17692 UTF-8 string | string | 0x7F
17693 array | array | 0x80..0x97
17694 array | array | 0x98
17695 array | array | 0x99
17696 array | array | 0x9A
17697 array | array | 0x9B
17698 array | array | 0x9F
17699 map | object | 0xA0..0xB7
17700 map | object | 0xB8
17701 map | object | 0xB9
17702 map | object | 0xBA
17703 map | object | 0xBB
17704 map | object | 0xBF
17705 False | `false` | 0xF4
17706 True | `true` | 0xF5
17707 Nill | `null` | 0xF6
17708 Half-Precision Float | number_float | 0xF9
17709 Single-Precision Float | number_float | 0xFA
17710 Double-Precision Float | number_float | 0xFB
17711
17712 @warning The mapping is **incomplete** in the sense that not all CBOR
17713 types can be converted to a JSON value. The following CBOR types
17714 are not supported and will yield parse errors (parse_error.112):
17715 - byte strings (0x40..0x5F)
17716 - date/time (0xC0..0xC1)
17717 - bignum (0xC2..0xC3)
17718 - decimal fraction (0xC4)
17719 - bigfloat (0xC5)
17720 - tagged items (0xC6..0xD4, 0xD8..0xDB)
17721 - expected conversions (0xD5..0xD7)
17722 - simple values (0xE0..0xF3, 0xF8)
17723 - undefined (0xF7)
17724
17725 @warning CBOR allows map keys of any type, whereas JSON only allows
17726 strings as keys in object values. Therefore, CBOR maps with keys
17727 other than UTF-8 strings are rejected (parse_error.113).
17728
17729 @note Any CBOR output created @ref to_cbor can be successfully parsed by
17730 @ref from_cbor.
17731
17732 @param[in] i an input in CBOR format convertible to an input adapter
17733 @param[in] strict whether to expect the input to be consumed until EOF
17734 (true by default)
17735 @param[in] allow_exceptions whether to throw exceptions in case of a
17736 parse error (optional, true by default)
17737
17738 @return deserialized JSON value
17739
17740 @throw parse_error.110 if the given input ends prematurely or the end of
17741 file was not reached when @a strict was set to true
17742 @throw parse_error.112 if unsupported features from CBOR were
17743 used in the given input @a v or if the input is not valid CBOR
17744 @throw parse_error.113 if a string was expected as map key, but not found
17745
17746 @complexity Linear in the size of the input @a i.
17747
17748 @liveexample{The example shows the deserialization of a byte vector in CBOR
17749 format to a JSON value.,from_cbor}
17750
17751 @sa http://cbor.io
17752 @sa @ref to_cbor(const basic_json&) for the analogous serialization
17753 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for the
17754 related MessagePack format
17755 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for the
17756 related UBJSON format
17757
17758 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17759 consume input adapters, removed start_index parameter, and added
17760 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17761 since 3.2.0
17762 */
17763static basic_json from_cbor(detail::input_adapter&& i,
17764const bool strict = true,
17765const bool allow_exceptions = true)
17766{
17767basic_json result;
17768detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17769const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
17770return res ? result : basic_json(value_t::discarded);
17771}
17772
17773/*!
17774 @copydoc from_cbor(detail::input_adapter, const bool, const bool)
17775 */
17776template<typename A1, typename A2,
17777detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
17778static basic_json from_cbor(A1 && a1, A2 && a2,
17779const bool strict = true,
17780const bool allow_exceptions = true)
17781{
17782basic_json result;
17783detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17784const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
17785return res ? result : basic_json(value_t::discarded);
17786}
17787
17788/*!
17789 @brief create a JSON value from an input in MessagePack format
17790
17791 Deserializes a given input @a i to a JSON value using the MessagePack
17792 serialization format.
17793
17794 The library maps MessagePack types to JSON value types as follows:
17795
17796 MessagePack type | JSON value type | first byte
17797 ---------------- | --------------- | ----------
17798 positive fixint | number_unsigned | 0x00..0x7F
17799 fixmap | object | 0x80..0x8F
17800 fixarray | array | 0x90..0x9F
17801 fixstr | string | 0xA0..0xBF
17802 nil | `null` | 0xC0
17803 false | `false` | 0xC2
17804 true | `true` | 0xC3
17805 float 32 | number_float | 0xCA
17806 float 64 | number_float | 0xCB
17807 uint 8 | number_unsigned | 0xCC
17808 uint 16 | number_unsigned | 0xCD
17809 uint 32 | number_unsigned | 0xCE
17810 uint 64 | number_unsigned | 0xCF
17811 int 8 | number_integer | 0xD0
17812 int 16 | number_integer | 0xD1
17813 int 32 | number_integer | 0xD2
17814 int 64 | number_integer | 0xD3
17815 str 8 | string | 0xD9
17816 str 16 | string | 0xDA
17817 str 32 | string | 0xDB
17818 array 16 | array | 0xDC
17819 array 32 | array | 0xDD
17820 map 16 | object | 0xDE
17821 map 32 | object | 0xDF
17822 negative fixint | number_integer | 0xE0-0xFF
17823
17824 @warning The mapping is **incomplete** in the sense that not all
17825 MessagePack types can be converted to a JSON value. The following
17826 MessagePack types are not supported and will yield parse errors:
17827 - bin 8 - bin 32 (0xC4..0xC6)
17828 - ext 8 - ext 32 (0xC7..0xC9)
17829 - fixext 1 - fixext 16 (0xD4..0xD8)
17830
17831 @note Any MessagePack output created @ref to_msgpack can be successfully
17832 parsed by @ref from_msgpack.
17833
17834 @param[in] i an input in MessagePack format convertible to an input
17835 adapter
17836 @param[in] strict whether to expect the input to be consumed until EOF
17837 (true by default)
17838 @param[in] allow_exceptions whether to throw exceptions in case of a
17839 parse error (optional, true by default)
17840
17841 @return deserialized JSON value
17842
17843 @throw parse_error.110 if the given input ends prematurely or the end of
17844 file was not reached when @a strict was set to true
17845 @throw parse_error.112 if unsupported features from MessagePack were
17846 used in the given input @a i or if the input is not valid MessagePack
17847 @throw parse_error.113 if a string was expected as map key, but not found
17848
17849 @complexity Linear in the size of the input @a i.
17850
17851 @liveexample{The example shows the deserialization of a byte vector in
17852 MessagePack format to a JSON value.,from_msgpack}
17853
17854 @sa http://msgpack.org
17855 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
17856 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17857 related CBOR format
17858 @sa @ref from_ubjson(detail::input_adapter, const bool, const bool) for
17859 the related UBJSON format
17860
17861 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
17862 consume input adapters, removed start_index parameter, and added
17863 @a strict parameter since 3.0.0; added @allow_exceptions parameter
17864 since 3.2.0
17865 */
17866static basic_json from_msgpack(detail::input_adapter&& i,
17867const bool strict = true,
17868const bool allow_exceptions = true)
17869{
17870basic_json result;
17871detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17872const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
17873return res ? result : basic_json(value_t::discarded);
17874}
17875
17876/*!
17877 @copydoc from_msgpack(detail::input_adapter, const bool, const bool)
17878 */
17879template<typename A1, typename A2,
17880detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
17881static basic_json from_msgpack(A1 && a1, A2 && a2,
17882const bool strict = true,
17883const bool allow_exceptions = true)
17884{
17885basic_json result;
17886detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17887const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
17888return res ? result : basic_json(value_t::discarded);
17889}
17890
17891/*!
17892 @brief create a JSON value from an input in UBJSON format
17893
17894 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
17895 Binary JSON) serialization format.
17896
17897 The library maps UBJSON types to JSON value types as follows:
17898
17899 UBJSON type | JSON value type | marker
17900 ----------- | --------------------------------------- | ------
17901 no-op | *no value, next value is read* | `N`
17902 null | `null` | `Z`
17903 false | `false` | `F`
17904 true | `true` | `T`
17905 float32 | number_float | `d`
17906 float64 | number_float | `D`
17907 uint8 | number_unsigned | `U`
17908 int8 | number_integer | `i`
17909 int16 | number_integer | `I`
17910 int32 | number_integer | `l`
17911 int64 | number_integer | `L`
17912 string | string | `S`
17913 char | string | `C`
17914 array | array (optimized values are supported) | `[`
17915 object | object (optimized values are supported) | `{`
17916
17917 @note The mapping is **complete** in the sense that any UBJSON value can
17918 be converted to a JSON value.
17919
17920 @param[in] i an input in UBJSON format convertible to an input adapter
17921 @param[in] strict whether to expect the input to be consumed until EOF
17922 (true by default)
17923 @param[in] allow_exceptions whether to throw exceptions in case of a
17924 parse error (optional, true by default)
17925
17926 @return deserialized JSON value
17927
17928 @throw parse_error.110 if the given input ends prematurely or the end of
17929 file was not reached when @a strict was set to true
17930 @throw parse_error.112 if a parse error occurs
17931 @throw parse_error.113 if a string could not be parsed successfully
17932
17933 @complexity Linear in the size of the input @a i.
17934
17935 @liveexample{The example shows the deserialization of a byte vector in
17936 UBJSON format to a JSON value.,from_ubjson}
17937
17938 @sa http://ubjson.org
17939 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
17940 analogous serialization
17941 @sa @ref from_cbor(detail::input_adapter, const bool, const bool) for the
17942 related CBOR format
17943 @sa @ref from_msgpack(detail::input_adapter, const bool, const bool) for
17944 the related MessagePack format
17945
17946 @since version 3.1.0; added @allow_exceptions parameter since 3.2.0
17947 */
17948static basic_json from_ubjson(detail::input_adapter&& i,
17949const bool strict = true,
17950const bool allow_exceptions = true)
17951{
17952basic_json result;
17953detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17954const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
17955return res ? result : basic_json(value_t::discarded);
17956}
17957
17958/*!
17959 @copydoc from_ubjson(detail::input_adapter, const bool, const bool)
17960 */
17961template<typename A1, typename A2,
17962detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
17963static basic_json from_ubjson(A1 && a1, A2 && a2,
17964const bool strict = true,
17965const bool allow_exceptions = true)
17966{
17967basic_json result;
17968detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
17969const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
17970return res ? result : basic_json(value_t::discarded);
17971}
17972
17973/// @}
17974
17975//////////////////////////
17976// JSON Pointer support //
17977//////////////////////////
17978
17979/// @name JSON Pointer functions
17980/// @{
17981
17982/*!
17983 @brief access specified element via JSON Pointer
17984
17985 Uses a JSON pointer to retrieve a reference to the respective JSON value.
17986 No bound checking is performed. Similar to @ref operator[](const typename
17987 object_t::key_type&), `null` values are created in arrays and objects if
17988 necessary.
17989
17990 In particular:
17991 - If the JSON pointer points to an object key that does not exist, it
17992 is created an filled with a `null` value before a reference to it
17993 is returned.
17994 - If the JSON pointer points to an array index that does not exist, it
17995 is created an filled with a `null` value before a reference to it
17996 is returned. All indices between the current maximum and the given
17997 index are also filled with `null`.
17998 - The special value `-` is treated as a synonym for the index past the
17999 end.
18000
18001 @param[in] ptr a JSON pointer
18002
18003 @return reference to the element pointed to by @a ptr
18004
18005 @complexity Constant.
18006
18007 @throw parse_error.106 if an array index begins with '0'
18008 @throw parse_error.109 if an array index was not a number
18009 @throw out_of_range.404 if the JSON pointer can not be resolved
18010
18011 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
18012
18013 @since version 2.0.0
18014 */
18015reference operator[](const json_pointer& ptr)
18016{
18017return ptr.get_unchecked(this);
18018}
18019
18020/*!
18021 @brief access specified element via JSON Pointer
18022
18023 Uses a JSON pointer to retrieve a reference to the respective JSON value.
18024 No bound checking is performed. The function does not change the JSON
18025 value; no `null` values are created. In particular, the the special value
18026 `-` yields an exception.
18027
18028 @param[in] ptr JSON pointer to the desired element
18029
18030 @return const reference to the element pointed to by @a ptr
18031
18032 @complexity Constant.
18033
18034 @throw parse_error.106 if an array index begins with '0'
18035 @throw parse_error.109 if an array index was not a number
18036 @throw out_of_range.402 if the array index '-' is used
18037 @throw out_of_range.404 if the JSON pointer can not be resolved
18038
18039 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
18040
18041 @since version 2.0.0
18042 */
18043const_reference operator[](const json_pointer& ptr) const
18044{
18045return ptr.get_unchecked(this);
18046}
18047
18048/*!
18049 @brief access specified element via JSON Pointer
18050
18051 Returns a reference to the element at with specified JSON pointer @a ptr,
18052 with bounds checking.
18053
18054 @param[in] ptr JSON pointer to the desired element
18055
18056 @return reference to the element pointed to by @a ptr
18057
18058 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18059 begins with '0'. See example below.
18060
18061 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18062 is not a number. See example below.
18063
18064 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18065 is out of range. See example below.
18066
18067 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18068 pointer @a ptr. As `at` provides checked access (and no elements are
18069 implicitly inserted), the index '-' is always invalid. See example below.
18070
18071 @throw out_of_range.403 if the JSON pointer describes a key of an object
18072 which cannot be found. See example below.
18073
18074 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18075 See example below.
18076
18077 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18078 changes in the JSON value.
18079
18080 @complexity Constant.
18081
18082 @since version 2.0.0
18083
18084 @liveexample{The behavior is shown in the example.,at_json_pointer}
18085 */
18086reference at(const json_pointer& ptr)
18087{
18088return ptr.get_checked(this);
18089}
18090
18091/*!
18092 @brief access specified element via JSON Pointer
18093
18094 Returns a const reference to the element at with specified JSON pointer @a
18095 ptr, with bounds checking.
18096
18097 @param[in] ptr JSON pointer to the desired element
18098
18099 @return reference to the element pointed to by @a ptr
18100
18101 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
18102 begins with '0'. See example below.
18103
18104 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
18105 is not a number. See example below.
18106
18107 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
18108 is out of range. See example below.
18109
18110 @throw out_of_range.402 if the array index '-' is used in the passed JSON
18111 pointer @a ptr. As `at` provides checked access (and no elements are
18112 implicitly inserted), the index '-' is always invalid. See example below.
18113
18114 @throw out_of_range.403 if the JSON pointer describes a key of an object
18115 which cannot be found. See example below.
18116
18117 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
18118 See example below.
18119
18120 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18121 changes in the JSON value.
18122
18123 @complexity Constant.
18124
18125 @since version 2.0.0
18126
18127 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
18128 */
18129const_reference at(const json_pointer& ptr) const
18130{
18131return ptr.get_checked(this);
18132}
18133
18134/*!
18135 @brief return flattened JSON value
18136
18137 The function creates a JSON object whose keys are JSON pointers (see [RFC
18138 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
18139 primitive. The original JSON value can be restored using the @ref
18140 unflatten() function.
18141
18142 @return an object that maps JSON pointers to primitive values
18143
18144 @note Empty objects and arrays are flattened to `null` and will not be
18145 reconstructed correctly by the @ref unflatten() function.
18146
18147 @complexity Linear in the size the JSON value.
18148
18149 @liveexample{The following code shows how a JSON object is flattened to an
18150 object whose keys consist of JSON pointers.,flatten}
18151
18152 @sa @ref unflatten() for the reverse function
18153
18154 @since version 2.0.0
18155 */
18156basic_json flatten() const
18157{
18158basic_json result(value_t::object);
18159json_pointer::flatten("", *this, result);
18160return result;
18161}
18162
18163/*!
18164 @brief unflatten a previously flattened JSON value
18165
18166 The function restores the arbitrary nesting of a JSON value that has been
18167 flattened before using the @ref flatten() function. The JSON value must
18168 meet certain constraints:
18169 1. The value must be an object.
18170 2. The keys must be JSON pointers (see
18171 [RFC 6901](https://tools.ietf.org/html/rfc6901))
18172 3. The mapped values must be primitive JSON types.
18173
18174 @return the original JSON from a flattened version
18175
18176 @note Empty objects and arrays are flattened by @ref flatten() to `null`
18177 values and can not unflattened to their original type. Apart from
18178 this example, for a JSON value `j`, the following is always true:
18179 `j == j.flatten().unflatten()`.
18180
18181 @complexity Linear in the size the JSON value.
18182
18183 @throw type_error.314 if value is not an object
18184 @throw type_error.315 if object values are not primitive
18185
18186 @liveexample{The following code shows how a flattened JSON object is
18187 unflattened into the original nested JSON object.,unflatten}
18188
18189 @sa @ref flatten() for the reverse function
18190
18191 @since version 2.0.0
18192 */
18193basic_json unflatten() const
18194{
18195return json_pointer::unflatten(*this);
18196}
18197
18198/// @}
18199
18200//////////////////////////
18201// JSON Patch functions //
18202//////////////////////////
18203
18204/// @name JSON Patch functions
18205/// @{
18206
18207/*!
18208 @brief applies a JSON patch
18209
18210 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
18211 expressing a sequence of operations to apply to a JSON) document. With
18212 this function, a JSON Patch is applied to the current JSON value by
18213 executing all operations from the patch.
18214
18215 @param[in] json_patch JSON patch document
18216 @return patched document
18217
18218 @note The application of a patch is atomic: Either all operations succeed
18219 and the patched document is returned or an exception is thrown. In
18220 any case, the original value is not changed: the patch is applied
18221 to a copy of the value.
18222
18223 @throw parse_error.104 if the JSON patch does not consist of an array of
18224 objects
18225
18226 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
18227 attributes are missing); example: `"operation add must have member path"`
18228
18229 @throw out_of_range.401 if an array index is out of range.
18230
18231 @throw out_of_range.403 if a JSON pointer inside the patch could not be
18232 resolved successfully in the current JSON value; example: `"key baz not
18233 found"`
18234
18235 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
18236 "move")
18237
18238 @throw other_error.501 if "test" operation was unsuccessful
18239
18240 @complexity Linear in the size of the JSON value and the length of the
18241 JSON patch. As usually only a fraction of the JSON value is affected by
18242 the patch, the complexity can usually be neglected.
18243
18244 @liveexample{The following code shows how a JSON patch is applied to a
18245 value.,patch}
18246
18247 @sa @ref diff -- create a JSON patch by comparing two JSON values
18248
18249 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18250 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
18251
18252 @since version 2.0.0
18253 */
18254basic_json patch(const basic_json& json_patch) const
18255{
18256// make a working copy to apply the patch to
18257basic_json result = *this;
18258
18259// the valid JSON Patch operations
18260enum class patch_operations {add, remove, replace, move, copy, test, invalid};
18261
18262const auto get_op = [](const std::string & op)
18263{
18264if (op == "add")
18265{
18266return patch_operations::add;
18267}
18268if (op == "remove")
18269{
18270return patch_operations::remove;
18271}
18272if (op == "replace")
18273{
18274return patch_operations::replace;
18275}
18276if (op == "move")
18277{
18278return patch_operations::move;
18279}
18280if (op == "copy")
18281{
18282return patch_operations::copy;
18283}
18284if (op == "test")
18285{
18286return patch_operations::test;
18287}
18288
18289return patch_operations::invalid;
18290};
18291
18292// wrapper for "add" operation; add value at ptr
18293const auto operation_add = [&result](json_pointer & ptr, basic_json val)
18294{
18295// adding to the root of the target document means replacing it
18296if (ptr.is_root())
18297{
18298result = val;
18299}
18300else
18301{
18302// make sure the top element of the pointer exists
18303json_pointer top_pointer = ptr.top();
18304if (top_pointer != ptr)
18305{
18306result.at(top_pointer);
18307}
18308
18309// get reference to parent of JSON pointer ptr
18310const auto last_path = ptr.pop_back();
18311basic_json& parent = result[ptr];
18312
18313switch (parent.m_type)
18314{
18315case value_t::null:
18316case value_t::object:
18317{
18318// use operator[] to add value
18319parent[last_path] = val;
18320break;
18321}
18322
18323case value_t::array:
18324{
18325if (last_path == "-")
18326{
18327// special case: append to back
18328parent.push_back(val);
18329}
18330else
18331{
18332const auto idx = json_pointer::array_index(last_path);
18333if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
18334{
18335// avoid undefined behavior
18336JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
18337}
18338else
18339{
18340// default case: insert add offset
18341parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
18342}
18343}
18344break;
18345}
18346
18347// LCOV_EXCL_START
18348default:
18349{
18350// if there exists a parent it cannot be primitive
18351assert(false);
18352}
18353// LCOV_EXCL_STOP
18354}
18355}
18356};
18357
18358// wrapper for "remove" operation; remove value at ptr
18359const auto operation_remove = [&result](json_pointer & ptr)
18360{
18361// get reference to parent of JSON pointer ptr
18362const auto last_path = ptr.pop_back();
18363basic_json& parent = result.at(ptr);
18364
18365// remove child
18366if (parent.is_object())
18367{
18368// perform range check
18369auto it = parent.find(last_path);
18370if (JSON_LIKELY(it != parent.end()))
18371{
18372parent.erase(it);
18373}
18374else
18375{
18376JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
18377}
18378}
18379else if (parent.is_array())
18380{
18381// note erase performs range check
18382parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
18383}
18384};
18385
18386// type check: top level value must be an array
18387if (JSON_UNLIKELY(not json_patch.is_array()))
18388{
18389JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18390}
18391
18392// iterate and apply the operations
18393for (const auto& val : json_patch)
18394{
18395// wrapper to get a value for an operation
18396const auto get_value = [&val](const std::string & op,
18397const std::string & member,
18398bool string_type) -> basic_json &
18399{
18400// find value
18401auto it = val.m_value.object->find(member);
18402
18403// context-sensitive error message
18404const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
18405
18406// check if desired value is present
18407if (JSON_UNLIKELY(it == val.m_value.object->end()))
18408{
18409JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
18410}
18411
18412// check if result is of type string
18413if (JSON_UNLIKELY(string_type and not it->second.is_string()))
18414{
18415JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
18416}
18417
18418// no error: return value
18419return it->second;
18420};
18421
18422// type check: every element of the array must be an object
18423if (JSON_UNLIKELY(not val.is_object()))
18424{
18425JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
18426}
18427
18428// collect mandatory members
18429const std::string op = get_value("op", "op", true);
18430const std::string path = get_value(op, "path", true);
18431json_pointer ptr(path);
18432
18433switch (get_op(op))
18434{
18435case patch_operations::add:
18436{
18437operation_add(ptr, get_value("add", "value", false));
18438break;
18439}
18440
18441case patch_operations::remove:
18442{
18443operation_remove(ptr);
18444break;
18445}
18446
18447case patch_operations::replace:
18448{
18449// the "path" location must exist - use at()
18450result.at(ptr) = get_value("replace", "value", false);
18451break;
18452}
18453
18454case patch_operations::move:
18455{
18456const std::string from_path = get_value("move", "from", true);
18457json_pointer from_ptr(from_path);
18458
18459// the "from" location must exist - use at()
18460basic_json v = result.at(from_ptr);
18461
18462// The move operation is functionally identical to a
18463// "remove" operation on the "from" location, followed
18464// immediately by an "add" operation at the target
18465// location with the value that was just removed.
18466operation_remove(from_ptr);
18467operation_add(ptr, v);
18468break;
18469}
18470
18471case patch_operations::copy:
18472{
18473const std::string from_path = get_value("copy", "from", true);
18474const json_pointer from_ptr(from_path);
18475
18476// the "from" location must exist - use at()
18477basic_json v = result.at(from_ptr);
18478
18479// The copy is functionally identical to an "add"
18480// operation at the target location using the value
18481// specified in the "from" member.
18482operation_add(ptr, v);
18483break;
18484}
18485
18486case patch_operations::test:
18487{
18488bool success = false;
18489JSON_TRY
18490{
18491// check if "value" matches the one at "path"
18492// the "path" location must exist - use at()
18493success = (result.at(ptr) == get_value("test", "value", false));
18494}
18495JSON_INTERNAL_CATCH (out_of_range&)
18496{
18497// ignore out of range errors: success remains false
18498}
18499
18500// throw an exception if test fails
18501if (JSON_UNLIKELY(not success))
18502{
18503JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
18504}
18505
18506break;
18507}
18508
18509case patch_operations::invalid:
18510{
18511// op must be "add", "remove", "replace", "move", "copy", or
18512// "test"
18513JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
18514}
18515}
18516}
18517
18518return result;
18519}
18520
18521/*!
18522 @brief creates a diff as a JSON patch
18523
18524 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
18525 be changed into the value @a target by calling @ref patch function.
18526
18527 @invariant For two JSON values @a source and @a target, the following code
18528 yields always `true`:
18529 @code {.cpp}
18530 source.patch(diff(source, target)) == target;
18531 @endcode
18532
18533 @note Currently, only `remove`, `add`, and `replace` operations are
18534 generated.
18535
18536 @param[in] source JSON value to compare from
18537 @param[in] target JSON value to compare against
18538 @param[in] path helper value to create JSON pointers
18539
18540 @return a JSON patch to convert the @a source to @a target
18541
18542 @complexity Linear in the lengths of @a source and @a target.
18543
18544 @liveexample{The following code shows how a JSON patch is created as a
18545 diff for two JSON values.,diff}
18546
18547 @sa @ref patch -- apply a JSON patch
18548 @sa @ref merge_patch -- apply a JSON Merge Patch
18549
18550 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
18551
18552 @since version 2.0.0
18553 */
18554static basic_json diff(const basic_json& source, const basic_json& target,
18555const std::string& path = "")
18556{
18557// the patch
18558basic_json result(value_t::array);
18559
18560// if the values are the same, return empty patch
18561if (source == target)
18562{
18563return result;
18564}
18565
18566if (source.type() != target.type())
18567{
18568// different types: replace value
18569result.push_back(
18570{
18571{"op", "replace"}, {"path", path}, {"value", target}
18572});
18573}
18574else
18575{
18576switch (source.type())
18577{
18578case value_t::array:
18579{
18580// first pass: traverse common elements
18581std::size_t i = 0;
18582while (i < source.size() and i < target.size())
18583{
18584// recursive call to compare array values at index i
18585auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
18586result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18587++i;
18588}
18589
18590// i now reached the end of at least one array
18591// in a second pass, traverse the remaining elements
18592
18593// remove my remaining elements
18594const auto end_index = static_cast<difference_type>(result.size());
18595while (i < source.size())
18596{
18597// add operations in reverse order to avoid invalid
18598// indices
18599result.insert(result.begin() + end_index, object(
18600{
18601{"op", "remove"},
18602{"path", path + "/" + std::to_string(i)}
18603}));
18604++i;
18605}
18606
18607// add other remaining elements
18608while (i < target.size())
18609{
18610result.push_back(
18611{
18612{"op", "add"},
18613{"path", path + "/" + std::to_string(i)},
18614{"value", target[i]}
18615});
18616++i;
18617}
18618
18619break;
18620}
18621
18622case value_t::object:
18623{
18624// first pass: traverse this object's elements
18625for (auto it = source.cbegin(); it != source.cend(); ++it)
18626{
18627// escape the key name to be used in a JSON patch
18628const auto key = json_pointer::escape(it.key());
18629
18630if (target.find(it.key()) != target.end())
18631{
18632// recursive call to compare object values at key it
18633auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
18634result.insert(result.end(), temp_diff.begin(), temp_diff.end());
18635}
18636else
18637{
18638// found a key that is not in o -> remove it
18639result.push_back(object(
18640{
18641{"op", "remove"}, {"path", path + "/" + key}
18642}));
18643}
18644}
18645
18646// second pass: traverse other object's elements
18647for (auto it = target.cbegin(); it != target.cend(); ++it)
18648{
18649if (source.find(it.key()) == source.end())
18650{
18651// found a key that is not in this -> add it
18652const auto key = json_pointer::escape(it.key());
18653result.push_back(
18654{
18655{"op", "add"}, {"path", path + "/" + key},
18656{"value", it.value()}
18657});
18658}
18659}
18660
18661break;
18662}
18663
18664default:
18665{
18666// both primitive type: replace value
18667result.push_back(
18668{
18669{"op", "replace"}, {"path", path}, {"value", target}
18670});
18671break;
18672}
18673}
18674}
18675
18676return result;
18677}
18678
18679/// @}
18680
18681////////////////////////////////
18682// JSON Merge Patch functions //
18683////////////////////////////////
18684
18685/// @name JSON Merge Patch functions
18686/// @{
18687
18688/*!
18689 @brief applies a JSON Merge Patch
18690
18691 The merge patch format is primarily intended for use with the HTTP PATCH
18692 method as a means of describing a set of modifications to a target
18693 resource's content. This function applies a merge patch to the current
18694 JSON value.
18695
18696 The function implements the following algorithm from Section 2 of
18697 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
18698
18699 ```
18700 define MergePatch(Target, Patch):
18701 if Patch is an Object:
18702 if Target is not an Object:
18703 Target = {} // Ignore the contents and set it to an empty Object
18704 for each Name/Value pair in Patch:
18705 if Value is null:
18706 if Name exists in Target:
18707 remove the Name/Value pair from Target
18708 else:
18709 Target[Name] = MergePatch(Target[Name], Value)
18710 return Target
18711 else:
18712 return Patch
18713 ```
18714
18715 Thereby, `Target` is the current object; that is, the patch is applied to
18716 the current value.
18717
18718 @param[in] patch the patch to apply
18719
18720 @complexity Linear in the lengths of @a patch.
18721
18722 @liveexample{The following code shows how a JSON Merge Patch is applied to
18723 a JSON document.,merge_patch}
18724
18725 @sa @ref patch -- apply a JSON patch
18726 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
18727
18728 @since version 3.0.0
18729 */
18730void merge_patch(const basic_json& patch)
18731{
18732if (patch.is_object())
18733{
18734if (not is_object())
18735{
18736*this = object();
18737}
18738for (auto it = patch.begin(); it != patch.end(); ++it)
18739{
18740if (it.value().is_null())
18741{
18742erase(it.key());
18743}
18744else
18745{
18746operator[](it.key()).merge_patch(it.value());
18747}
18748}
18749}
18750else
18751{
18752*this = patch;
18753}
18754}
18755
18756/// @}
18757};
18758} // namespace nlohmann
18759
18760///////////////////////
18761// nonmember support //
18762///////////////////////
18763
18764// specialization of std::swap, and std::hash
18765namespace std
18766{
18767
18768/// hash value for JSON objects
18769template<>
18770struct hash<nlohmann::json>
18771{
18772/*!
18773 @brief return a hash value for a JSON object
18774
18775 @since version 1.0.0
18776 */
18777std::size_t operator()(const nlohmann::json& j) const
18778{
18779// a naive hashing via the string representation
18780const auto& h = hash<nlohmann::json::string_t>();
18781return h(j.dump());
18782}
18783};
18784
18785/// specialization for std::less<value_t>
18786/// @note: do not remove the space after '<',
18787/// see https://github.com/nlohmann/json/pull/679
18788template<>
18789struct less< ::nlohmann::detail::value_t>
18790{
18791/*!
18792 @brief compare two value_t enum values
18793 @since version 3.0.0
18794 */
18795bool operator()(nlohmann::detail::value_t lhs,
18796nlohmann::detail::value_t rhs) const noexcept
18797{
18798return nlohmann::detail::operator<(lhs, rhs);
18799}
18800};
18801
18802/*!
18803@brief exchanges the values of two JSON objects
18804
18805@since version 1.0.0
18806*/
18807template<>
18808inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
18809is_nothrow_move_constructible<nlohmann::json>::value and
18810is_nothrow_move_assignable<nlohmann::json>::value
18811)
18812{
18813j1.swap(j2);
18814}
18815
18816} // namespace std
18817
18818/*!
18819@brief user-defined string literal for JSON values
18820
18821This operator implements a user-defined string literal for JSON objects. It
18822can be used by adding `"_json"` to a string literal and returns a JSON object
18823if no parse error occurred.
18824
18825@param[in] s a string representation of a JSON object
18826@param[in] n the length of string @a s
18827@return a JSON object
18828
18829@since version 1.0.0
18830*/
18831inline nlohmann::json operator "" _json(const char* s, std::size_t n)
18832{
18833return nlohmann::json::parse(s, s + n);
18834}
18835
18836/*!
18837@brief user-defined string literal for JSON pointer
18838
18839This operator implements a user-defined string literal for JSON Pointers. It
18840can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
18841object if no parse error occurred.
18842
18843@param[in] s a string representation of a JSON Pointer
18844@param[in] n the length of string @a s
18845@return a JSON pointer object
18846
18847@since version 2.0.0
18848*/
18849inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
18850{
18851return nlohmann::json::json_pointer(std::string(s, n));
18852}
18853
18854// #include <nlohmann/detail/macro_unscope.hpp>
18855
18856
18857// restore GCC/clang diagnostic settings
18858#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
18859#pragma GCC diagnostic pop
18860#endif
18861#if defined(__clang__)
18862#pragma GCC diagnostic pop
18863#endif
18864
18865// clean up
18866#undef JSON_INTERNAL_CATCH
18867#undef JSON_CATCH
18868#undef JSON_THROW
18869#undef JSON_TRY
18870#undef JSON_LIKELY
18871#undef JSON_UNLIKELY
18872#undef JSON_DEPRECATED
18873#undef JSON_HAS_CPP_14
18874#undef JSON_HAS_CPP_17
18875#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
18876#undef NLOHMANN_BASIC_JSON_TPL
18877
18878
18879#endif
18880