Project
Loading...
Searching...
No Matches
json.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12/*
13 __ _____ _____ _____
14 __| | __| | | | JSON for Modern C++
15| | |__ | | | | | | version 3.1.2
16|_____|_____|_____|_|___| https://github.com/nlohmann/json
17
18Licensed under the MIT License <http://opensource.org/licenses/MIT>.
19Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
20
21Permission is hereby granted, free of charge, to any person obtaining a copy
22of this software and associated documentation files (the "Software"), to deal
23in the Software without restriction, including without limitation the rights
24to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25copies of the Software, and to permit persons to whom the Software is
26furnished to do so, subject to the following conditions:
27
28The above copyright notice and this permission notice shall be included in all
29copies or substantial portions of the Software.
30
31THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37SOFTWARE.
38*/
39
40#ifndef NLOHMANN_JSON_HPP
41#define NLOHMANN_JSON_HPP
42
43#define NLOHMANN_JSON_VERSION_MAJOR 3
44#define NLOHMANN_JSON_VERSION_MINOR 1
45#define NLOHMANN_JSON_VERSION_PATCH 2
46
47#include <algorithm> // all_of, find, for_each
48#include <cassert> // assert
49#include <ciso646> // and, not, or
50#include <cstddef> // nullptr_t, ptrdiff_t, size_t
51#include <functional> // hash, less
52#include <initializer_list> // initializer_list
53#include <iosfwd> // istream, ostream
54#include <iterator> // iterator_traits, random_access_iterator_tag
55#include <numeric> // accumulate
56#include <string> // string, stoi, to_string
57#include <utility> // declval, forward, move, pair, swap
58
59// #include <nlohmann/json_fwd.hpp>
60#ifndef NLOHMANN_JSON_FWD_HPP
61#define NLOHMANN_JSON_FWD_HPP
62
63#include <cstdint> // int64_t, uint64_t
64#include <map> // map
65#include <memory> // allocator
66#include <string> // string
67#include <vector> // vector
68
74namespace nlohmann
75{
83template <typename = void, typename = void>
85
86template <template <typename U, typename V, typename... Args> class ObjectType =
87 std::map,
88 template <typename U, typename... Args> class ArrayType = std::vector,
89 class StringType = std::string, class BooleanType = bool,
90 class NumberIntegerType = std::int64_t,
91 class NumberUnsignedType = std::uint64_t,
92 class NumberFloatType = double,
93 template <typename U> class AllocatorType = std::allocator,
94 template <typename T, typename SFINAE = void> class JSONSerializer =
97
109template <typename BasicJsonType>
111
121} // namespace nlohmann
122
123#endif
124
125// #include <nlohmann/detail/macro_scope.hpp>
126
127// This file contains all internal macro definitions
128// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
129
130// exclude unsupported compilers
131#if defined(__clang__)
132#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
133#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
134#endif
135#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
136#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
137#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
138#endif
139#endif
140
141// disable float-equal warnings on GCC/clang
142#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
143#pragma GCC diagnostic push
144#pragma GCC diagnostic ignored "-Wfloat-equal"
145#endif
146
147// disable documentation warnings on clang
148#if defined(__clang__)
149#pragma GCC diagnostic push
150#pragma GCC diagnostic ignored "-Wdocumentation"
151#endif
152
153// allow for portable deprecation warnings
154#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
155#define JSON_DEPRECATED __attribute__((deprecated))
156#elif defined(_MSC_VER)
157#define JSON_DEPRECATED __declspec(deprecated)
158#else
159#define JSON_DEPRECATED
160#endif
161
162// allow to disable exceptions
163#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
164#define JSON_THROW(exception) throw exception
165#define JSON_TRY try
166#define JSON_CATCH(exception) catch (exception)
167#else
168#define JSON_THROW(exception) std::abort()
169#define JSON_TRY if (true)
170#define JSON_CATCH(exception) if (false)
171#endif
172
173// override exception macros
174#if defined(JSON_THROW_USER)
175#undef JSON_THROW
176#define JSON_THROW JSON_THROW_USER
177#endif
178#if defined(JSON_TRY_USER)
179#undef JSON_TRY
180#define JSON_TRY JSON_TRY_USER
181#endif
182#if defined(JSON_CATCH_USER)
183#undef JSON_CATCH
184#define JSON_CATCH JSON_CATCH_USER
185#endif
186
187// manual branch prediction
188#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
189#define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
190#define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
191#else
192#define JSON_LIKELY(x) x
193#define JSON_UNLIKELY(x) x
194#endif
195
196// C++ language standard detection
197#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
198#define JSON_HAS_CPP_17
199#define JSON_HAS_CPP_14
200#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
201#define JSON_HAS_CPP_14
202#endif
203
204// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
205// may be removed in the future once the class is split.
206
207#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
208 template <template <typename, typename, typename...> class ObjectType, \
209 template <typename, typename...> class ArrayType, \
210 class StringType, class BooleanType, class NumberIntegerType, \
211 class NumberUnsignedType, class NumberFloatType, \
212 template <typename> class AllocatorType, \
213 template <typename, typename = void> class JSONSerializer>
214
215#define NLOHMANN_BASIC_JSON_TPL \
216 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
217 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
218 AllocatorType, JSONSerializer>
219
230#define NLOHMANN_JSON_HAS_HELPER(type) \
231 template <typename T> \
232 struct has_##type { \
233 private: \
234 template <typename U, typename = typename U::type> \
235 static int detect(U&&); \
236 static void detect(...); \
237 \
238 public: \
239 static constexpr bool value = \
240 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
241 }
242
243// #include <nlohmann/detail/meta.hpp>
244
245#include <ciso646> // not
246#include <cstddef> // size_t
247#include <limits> // numeric_limits
248#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
249#include <utility> // declval
250
251// #include <nlohmann/json_fwd.hpp>
252
253// #include <nlohmann/detail/macro_scope.hpp>
254
255namespace nlohmann
256{
265namespace detail
266{
268// helpers //
270
271template <typename>
272struct is_basic_json : std::false_type {
273};
274
276struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {
277};
278
279// alias templates to reduce boilerplate
280template <bool B, typename T = void>
281using enable_if_t = typename std::enable_if<B, T>::type;
282
283template <typename T>
284using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
285
286// implementation of C++14 index_sequence and affiliates
287// source: https://stackoverflow.com/a/32223343
288template <std::size_t... Ints>
291 using value_type = std::size_t;
292 static constexpr std::size_t size() noexcept
293 {
294 return sizeof...(Ints);
295 }
296};
297
298template <class Sequence1, class Sequence2>
300
301template <std::size_t... I1, std::size_t... I2>
303 : index_sequence<I1..., (sizeof...(I1) + I2)...> {
304};
305
306template <std::size_t N>
308 : merge_and_renumber<typename make_index_sequence<N / 2>::type,
309 typename make_index_sequence<N - N / 2>::type> {
310};
311
312template <>
315template <>
317};
318
319template <typename... Ts>
321
322/*
323Implementation of two C++17 constructs: conjunction, negation. This is needed
324to avoid evaluating all the traits in a condition
325
326For example: not std::is_same<void, T>::value and has_value_type<T>::value
327will not compile when T = void (on MSVC at least). Whereas
328conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
329stop evaluating if negation<...>::value == false
330
331Please note that those constructs must be used with caution, since symbols can
332become very long quickly (which can slow down compilation and cause MSVC
333internal compiler errors). Only use it when you have to (see example ahead).
334*/
335template <class...>
336struct conjunction : std::true_type {
337};
338template <class B1>
340};
341template <class B1, class... Bn>
342struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {
343};
344
345template <class B>
346struct negation : std::integral_constant<bool, not B::value> {
347};
348
349// dispatch utility (taken from ranges-v3)
350template <unsigned N>
351struct priority_tag : priority_tag<N - 1> {
352};
353template <>
354struct priority_tag<0> {
355};
356
358// has_/is_ functions //
360
361// source: https://stackoverflow.com/a/37193089/4116453
362
363template <typename T, typename = void>
364struct is_complete_type : std::false_type {
365};
366
367template <typename T>
368struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {
369};
370
375
376template <bool B, class RealType, class CompatibleObjectType>
377struct is_compatible_object_type_impl : std::false_type {
378};
379
380template <class RealType, class CompatibleObjectType>
381struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType> {
382 static constexpr auto value =
383 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
384 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
385};
386
387template <class BasicJsonType, class CompatibleObjectType>
389 static auto constexpr value = is_compatible_object_type_impl<
391 has_mapped_type<CompatibleObjectType>,
392 has_key_type<CompatibleObjectType>>::value,
393 typename BasicJsonType::object_t, CompatibleObjectType>::value;
394};
395
396template <typename BasicJsonType, typename T>
398 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
399 std::is_same<T, typename BasicJsonType::const_iterator>::value or
400 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
401 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
402};
403
404template <class BasicJsonType, class CompatibleArrayType>
406 static auto constexpr value =
409 BasicJsonType, CompatibleArrayType>>,
410 negation<std::is_constructible<typename BasicJsonType::string_t,
411 CompatibleArrayType>>,
413 has_value_type<CompatibleArrayType>,
414 has_iterator<CompatibleArrayType>>::value;
415};
416
417template <bool, typename, typename>
418struct is_compatible_integer_type_impl : std::false_type {
419};
420
421template <typename RealIntegerType, typename CompatibleNumberIntegerType>
422struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType> {
423 // is there an assert somewhere on overflows?
424 using RealLimits = std::numeric_limits<RealIntegerType>;
425 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
426
427 static constexpr auto value =
428 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
429 CompatibleLimits::is_integer and
430 RealLimits::is_signed == CompatibleLimits::is_signed;
431};
432
433template <typename RealIntegerType, typename CompatibleNumberIntegerType>
435 static constexpr auto value =
437 std::is_integral<CompatibleNumberIntegerType>::value and
438 not std::is_same<bool, CompatibleNumberIntegerType>::value,
439 RealIntegerType, CompatibleNumberIntegerType > ::value;
440};
441
442// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
443template <typename BasicJsonType, typename T>
445 private:
446 // also check the return type of from_json
447 template <typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
448 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
449 static int detect(U&&);
450 static void detect(...);
451
452 public:
453 static constexpr bool value = std::is_integral<decltype(
454 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
455};
456
457// This trait checks if JSONSerializer<T>::from_json(json const&) exists
458// this overload is used for non-default-constructible user-defined-types
459template <typename BasicJsonType, typename T>
461 private:
462 template <
463 typename U,
464 typename = enable_if_t<std::is_same<
465 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value>>
466 static int detect(U&&);
467 static void detect(...);
468
469 public:
470 static constexpr bool value = std::is_integral<decltype(detect(
471 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
472};
473
474// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
475template <typename BasicJsonType, typename T>
477 private:
478 template <typename U, typename = decltype(uncvref_t<U>::to_json(
479 std::declval<BasicJsonType&>(), std::declval<T>()))>
480 static int detect(U&&);
481 static void detect(...);
482
483 public:
484 static constexpr bool value = std::is_integral<decltype(detect(
485 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
486};
487
488template <typename BasicJsonType, typename CompatibleCompleteType>
490 static constexpr bool value =
491 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
495};
496
497template <typename BasicJsonType, typename CompatibleType>
502
503// taken from ranges-v3
504template <typename T>
506 static constexpr T value{};
507};
508
509template <typename T>
510constexpr T static_const<T>::value;
511} // namespace detail
512} // namespace nlohmann
513
514// #include <nlohmann/detail/exceptions.hpp>
515
516#include <exception> // exception
517#include <stdexcept> // runtime_error
518#include <string> // to_string
519
520namespace nlohmann
521{
522namespace detail
523{
525// exceptions //
527
556class exception : public std::exception
557{
558 public:
560 const char* what() const noexcept override
561 {
562 return m.what();
563 }
564
566 const int id;
567
568 protected:
569 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
570
571 static std::string name(const std::string& ename, int id_)
572 {
573 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
574 }
575
576 private:
578 std::runtime_error m;
579};
580
624class parse_error : public exception
625{
626 public:
635 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
636 {
637 std::string w = exception::name("parse_error", id_) + "parse error" +
638 (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
639 ": " + what_arg;
640 return parse_error(id_, byte_, w.c_str());
641 }
642
652 const std::size_t byte;
653
654 private:
655 parse_error(int id_, std::size_t byte_, const char* what_arg)
656 : exception(id_, what_arg), byte(byte_) {}
657};
658
697{
698 public:
699 static invalid_iterator create(int id_, const std::string& what_arg)
700 {
701 std::string w = exception::name("invalid_iterator", id_) + what_arg;
702 return invalid_iterator(id_, w.c_str());
703 }
704
705 private:
706 invalid_iterator(int id_, const char* what_arg)
707 : exception(id_, what_arg) {}
708};
709
748class type_error : public exception
749{
750 public:
751 static type_error create(int id_, const std::string& what_arg)
752 {
753 std::string w = exception::name("type_error", id_) + what_arg;
754 return type_error(id_, w.c_str());
755 }
756
757 private:
758 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
759};
760
794{
795 public:
796 static out_of_range create(int id_, const std::string& what_arg)
797 {
798 std::string w = exception::name("out_of_range", id_) + what_arg;
799 return out_of_range(id_, w.c_str());
800 }
801
802 private:
803 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
804};
805
830class other_error : public exception
831{
832 public:
833 static other_error create(int id_, const std::string& what_arg)
834 {
835 std::string w = exception::name("other_error", id_) + what_arg;
836 return other_error(id_, w.c_str());
837 }
838
839 private:
840 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
841};
842} // namespace detail
843} // namespace nlohmann
844
845// #include <nlohmann/detail/value_t.hpp>
846
847#include <array> // array
848#include <ciso646> // and
849#include <cstddef> // size_t
850#include <cstdint> // uint8_t
851
852namespace nlohmann
853{
854namespace detail
855{
857// JSON type enumeration //
859
884enum class value_t : std::uint8_t {
885 null,
886 object,
887 array,
888 string,
889 boolean,
890 number_integer,
891 number_unsigned,
892 number_float,
893 discarded
894};
895
906inline bool operator<(const value_t lhs, const value_t rhs) noexcept
907{
908 static constexpr std::array<std::uint8_t, 8> order = {{
909 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
910 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
911 }};
912
913 const auto l_index = static_cast<std::size_t>(lhs);
914 const auto r_index = static_cast<std::size_t>(rhs);
915 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
916}
917} // namespace detail
918} // namespace nlohmann
919
920// #include <nlohmann/detail/conversions/from_json.hpp>
921
922#include <algorithm> // transform
923#include <array> // array
924#include <ciso646> // and, not
925#include <forward_list> // forward_list
926#include <iterator> // inserter, front_inserter, end
927#include <string> // string
928#include <tuple> // tuple, make_tuple
929#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
930#include <utility> // pair, declval
931#include <valarray> // valarray
932
933// #include <nlohmann/detail/exceptions.hpp>
934
935// #include <nlohmann/detail/macro_scope.hpp>
936
937// #include <nlohmann/detail/meta.hpp>
938
939// #include <nlohmann/detail/value_t.hpp>
940
941namespace nlohmann
942{
943namespace detail
944{
945// overloads for basic_json template parameters
946template <typename BasicJsonType, typename ArithmeticType,
947 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
948 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
949 int> = 0>
950void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
951{
952 switch (static_cast<value_t>(j)) {
953 case value_t::number_unsigned: {
954 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
955 break;
956 }
957 case value_t::number_integer: {
958 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
959 break;
960 }
961 case value_t::number_float: {
962 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
963 break;
964 }
965
966 default:
967 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
968 }
969}
970
971template <typename BasicJsonType>
972void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
973{
974 if (JSON_UNLIKELY(not j.is_boolean())) {
975 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
976 }
977 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
978}
979
980template <typename BasicJsonType>
981void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
982{
983 if (JSON_UNLIKELY(not j.is_string())) {
984 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
985 }
986 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
987}
988
989template <typename BasicJsonType>
990void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
991{
992 get_arithmetic_value(j, val);
993}
994
995template <typename BasicJsonType>
996void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
997{
998 get_arithmetic_value(j, val);
999}
1000
1001template <typename BasicJsonType>
1002void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1003{
1004 get_arithmetic_value(j, val);
1005}
1006
1007template <typename BasicJsonType, typename EnumType,
1008 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1009void from_json(const BasicJsonType& j, EnumType& e)
1010{
1011 typename std::underlying_type<EnumType>::type val;
1012 get_arithmetic_value(j, val);
1013 e = static_cast<EnumType>(val);
1014}
1015
1016template <typename BasicJsonType>
1017void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1018{
1019 if (JSON_UNLIKELY(not j.is_array())) {
1020 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1021 }
1022 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1023}
1024
1025// forward_list doesn't have an insert method
1026template <typename BasicJsonType, typename T, typename Allocator,
1027 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1028void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1029{
1030 if (JSON_UNLIKELY(not j.is_array())) {
1031 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1032 }
1033 std::transform(j.rbegin(), j.rend(),
1034 std::front_inserter(l), [](const BasicJsonType& i) {
1035 return i.template get<T>();
1036 });
1037}
1038
1039// valarray doesn't have an insert method
1040template <typename BasicJsonType, typename T,
1041 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1042void from_json(const BasicJsonType& j, std::valarray<T>& l)
1043{
1044 if (JSON_UNLIKELY(not j.is_array())) {
1045 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1046 }
1047 l.resize(j.size());
1048 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1049}
1050
1051template <typename BasicJsonType, typename CompatibleArrayType>
1052void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1053{
1054 using std::end;
1055
1056 std::transform(j.begin(), j.end(),
1057 std::inserter(arr, end(arr)), [](const BasicJsonType& i) {
1058 // get<BasicJsonType>() returns *this, this won't call a from_json
1059 // method when value_type is BasicJsonType
1060 return i.template get<typename CompatibleArrayType::value_type>();
1061 });
1062}
1063
1064template <typename BasicJsonType, typename CompatibleArrayType>
1065auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1066 -> decltype(
1067 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1068 void())
1069{
1070 using std::end;
1071
1072 arr.reserve(j.size());
1073 std::transform(j.begin(), j.end(),
1074 std::inserter(arr, end(arr)), [](const BasicJsonType& i) {
1075 // get<BasicJsonType>() returns *this, this won't call a from_json
1076 // method when value_type is BasicJsonType
1077 return i.template get<typename CompatibleArrayType::value_type>();
1078 });
1079}
1080
1081template <typename BasicJsonType, typename T, std::size_t N>
1082void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1083{
1084 for (std::size_t i = 0; i < N; ++i) {
1085 arr[i] = j.at(i).template get<T>();
1086 }
1087}
1088
1089template <
1090 typename BasicJsonType, typename CompatibleArrayType,
1093 not std::is_same<typename BasicJsonType::array_t,
1094 CompatibleArrayType>::value and
1095 std::is_constructible<
1096 BasicJsonType, typename CompatibleArrayType::value_type>::value,
1097 int> = 0>
1098void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1099{
1100 if (JSON_UNLIKELY(not j.is_array())) {
1101 JSON_THROW(type_error::create(302, "type must be array, but is " +
1102 std::string(j.type_name())));
1103 }
1104
1105 from_json_array_impl(j, arr, priority_tag<2>{});
1106}
1107
1108template <typename BasicJsonType, typename CompatibleObjectType,
1109 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1110void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1111{
1112 if (JSON_UNLIKELY(not j.is_object())) {
1113 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1114 }
1115
1116 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1117 using value_type = typename CompatibleObjectType::value_type;
1118 std::transform(
1119 inner_object->begin(), inner_object->end(),
1120 std::inserter(obj, obj.begin()),
1121 [](typename BasicJsonType::object_t::value_type const& p) {
1122 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1123 });
1124}
1125
1126// overload for arithmetic types, not chosen for basic_json template arguments
1127// (BooleanType, etc..); note: Is it really necessary to provide explicit
1128// overloads for boolean_t etc. in case of a custom BooleanType which is not
1129// an arithmetic type?
1130template <typename BasicJsonType, typename ArithmeticType,
1132 std::is_arithmetic<ArithmeticType>::value and
1133 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1134 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1135 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1136 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1137 int> = 0>
1138void from_json(const BasicJsonType& j, ArithmeticType& val)
1139{
1140 switch (static_cast<value_t>(j)) {
1141 case value_t::number_unsigned: {
1142 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1143 break;
1144 }
1145 case value_t::number_integer: {
1146 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1147 break;
1148 }
1149 case value_t::number_float: {
1150 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1151 break;
1152 }
1153 case value_t::boolean: {
1154 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1155 break;
1156 }
1157
1158 default:
1159 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1160 }
1161}
1162
1163template <typename BasicJsonType, typename A1, typename A2>
1164void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1165{
1166 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1167}
1168
1169template <typename BasicJsonType, typename Tuple, std::size_t... Idx>
1170void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1171{
1172 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1173}
1174
1175template <typename BasicJsonType, typename... Args>
1176void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1177{
1178 from_json_tuple_impl(j, t, index_sequence_for<Args...>{});
1179}
1180
1181struct from_json_fn {
1182 private:
1183 template <typename BasicJsonType, typename T>
1184 auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1185 noexcept(noexcept(from_json(j, val)))
1186 -> decltype(from_json(j, val), void())
1187 {
1188 return from_json(j, val);
1189 }
1190
1191 template <typename BasicJsonType, typename T>
1192 void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1193 {
1194 static_assert(sizeof(BasicJsonType) == 0,
1195 "could not find from_json() method in T's namespace");
1196#ifdef _MSC_VER
1197 // MSVC does not show a stacktrace for the above assert
1198 using decayed = uncvref_t<T>;
1199 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1200 "forcing MSVC stacktrace to show which T we're talking about.");
1201#endif
1202 }
1203
1204 public:
1205 template <typename BasicJsonType, typename T>
1206 void operator()(const BasicJsonType& j, T& val) const
1207 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1>{})))
1208 {
1209 return call(j, val, priority_tag<1>{});
1210 }
1211};
1212} // namespace detail
1213
1217namespace
1218{
1219constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1220}
1221} // namespace nlohmann
1222
1223// #include <nlohmann/detail/conversions/to_json.hpp>
1224
1225#include <ciso646> // or, and, not
1226#include <iterator> // begin, end
1227#include <tuple> // tuple, get
1228#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1229#include <utility> // move, forward, declval, pair
1230#include <valarray> // valarray
1231#include <vector> // vector
1232
1233// #include <nlohmann/detail/meta.hpp>
1234
1235// #include <nlohmann/detail/value_t.hpp>
1236
1237namespace nlohmann
1238{
1239namespace detail
1240{
1242// constructors //
1244
1245template <value_t>
1246struct external_constructor;
1247
1248template <>
1249struct external_constructor<value_t::boolean> {
1250 template <typename BasicJsonType>
1251 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1252 {
1253 j.m_type = value_t::boolean;
1254 j.m_value = b;
1255 j.assert_invariant();
1256 }
1257};
1258
1259template <>
1260struct external_constructor<value_t::string> {
1261 template <typename BasicJsonType>
1262 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1263 {
1264 j.m_type = value_t::string;
1265 j.m_value = s;
1266 j.assert_invariant();
1267 }
1268
1269 template <typename BasicJsonType>
1270 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1271 {
1272 j.m_type = value_t::string;
1273 j.m_value = std::move(s);
1274 j.assert_invariant();
1275 }
1276};
1277
1278template <>
1279struct external_constructor<value_t::number_float> {
1280 template <typename BasicJsonType>
1281 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1282 {
1283 j.m_type = value_t::number_float;
1284 j.m_value = val;
1285 j.assert_invariant();
1286 }
1287};
1288
1289template <>
1290struct external_constructor<value_t::number_unsigned> {
1291 template <typename BasicJsonType>
1292 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1293 {
1294 j.m_type = value_t::number_unsigned;
1295 j.m_value = val;
1296 j.assert_invariant();
1297 }
1298};
1299
1300template <>
1301struct external_constructor<value_t::number_integer> {
1302 template <typename BasicJsonType>
1303 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1304 {
1305 j.m_type = value_t::number_integer;
1306 j.m_value = val;
1307 j.assert_invariant();
1308 }
1309};
1310
1311template <>
1312struct external_constructor<value_t::array> {
1313 template <typename BasicJsonType>
1314 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1315 {
1316 j.m_type = value_t::array;
1317 j.m_value = arr;
1318 j.assert_invariant();
1319 }
1320
1321 template <typename BasicJsonType>
1322 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1323 {
1324 j.m_type = value_t::array;
1325 j.m_value = std::move(arr);
1326 j.assert_invariant();
1327 }
1328
1329 template <typename BasicJsonType, typename CompatibleArrayType,
1330 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1331 int> = 0>
1332 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1333 {
1334 using std::begin;
1335 using std::end;
1336 j.m_type = value_t::array;
1337 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1338 j.assert_invariant();
1339 }
1340
1341 template <typename BasicJsonType>
1342 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1343 {
1344 j.m_type = value_t::array;
1345 j.m_value = value_t::array;
1346 j.m_value.array->reserve(arr.size());
1347 for (const bool x : arr) {
1348 j.m_value.array->push_back(x);
1349 }
1350 j.assert_invariant();
1351 }
1352
1353 template <typename BasicJsonType, typename T,
1354 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1355 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1356 {
1357 j.m_type = value_t::array;
1358 j.m_value = value_t::array;
1359 j.m_value.array->resize(arr.size());
1360 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1361 j.assert_invariant();
1362 }
1363};
1364
1365template <>
1366struct external_constructor<value_t::object> {
1367 template <typename BasicJsonType>
1368 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1369 {
1370 j.m_type = value_t::object;
1371 j.m_value = obj;
1372 j.assert_invariant();
1373 }
1374
1375 template <typename BasicJsonType>
1376 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1377 {
1378 j.m_type = value_t::object;
1379 j.m_value = std::move(obj);
1380 j.assert_invariant();
1381 }
1382
1383 template <typename BasicJsonType, typename CompatibleObjectType,
1384 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
1385 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1386 {
1387 using std::begin;
1388 using std::end;
1389
1390 j.m_type = value_t::object;
1391 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1392 j.assert_invariant();
1393 }
1394};
1395
1397// to_json //
1399
1400template <typename BasicJsonType, typename T,
1401 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
1402void to_json(BasicJsonType& j, T b) noexcept
1403{
1404 external_constructor<value_t::boolean>::construct(j, b);
1405}
1406
1407template <typename BasicJsonType, typename CompatibleString,
1408 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
1409void to_json(BasicJsonType& j, const CompatibleString& s)
1410{
1411 external_constructor<value_t::string>::construct(j, s);
1412}
1413
1414template <typename BasicJsonType>
1415void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1416{
1417 external_constructor<value_t::string>::construct(j, std::move(s));
1418}
1419
1420template <typename BasicJsonType, typename FloatType,
1421 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
1422void to_json(BasicJsonType& j, FloatType val) noexcept
1423{
1424 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1425}
1426
1427template <typename BasicJsonType, typename CompatibleNumberUnsignedType,
1428 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
1429void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1430{
1431 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1432}
1433
1434template <typename BasicJsonType, typename CompatibleNumberIntegerType,
1435 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
1436void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1437{
1438 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1439}
1440
1441template <typename BasicJsonType, typename EnumType,
1442 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1443void to_json(BasicJsonType& j, EnumType e) noexcept
1444{
1445 using underlying_type = typename std::underlying_type<EnumType>::type;
1446 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1447}
1448
1449template <typename BasicJsonType>
1450void to_json(BasicJsonType& j, const std::vector<bool>& e)
1451{
1452 external_constructor<value_t::array>::construct(j, e);
1453}
1454
1455template <typename BasicJsonType, typename CompatibleArrayType,
1456 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1457 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1458 int> = 0>
1459void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1460{
1461 external_constructor<value_t::array>::construct(j, arr);
1462}
1463
1464template <typename BasicJsonType, typename T,
1465 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1466void to_json(BasicJsonType& j, std::valarray<T> arr)
1467{
1468 external_constructor<value_t::array>::construct(j, std::move(arr));
1469}
1470
1471template <typename BasicJsonType>
1472void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1473{
1474 external_constructor<value_t::array>::construct(j, std::move(arr));
1475}
1476
1477template <typename BasicJsonType, typename CompatibleObjectType,
1478 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1479void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1480{
1481 external_constructor<value_t::object>::construct(j, obj);
1482}
1483
1484template <typename BasicJsonType>
1485void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1486{
1487 external_constructor<value_t::object>::construct(j, std::move(obj));
1488}
1489
1490template <typename BasicJsonType, typename T, std::size_t N,
1491 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T (&)[N]>::value, int> = 0>
1492void to_json(BasicJsonType& j, T (&arr)[N])
1493{
1494 external_constructor<value_t::array>::construct(j, arr);
1495}
1496
1497template <typename BasicJsonType, typename... Args>
1498void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1499{
1500 j = {p.first, p.second};
1501}
1502
1503template <typename BasicJsonType, typename Tuple, std::size_t... Idx>
1504void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1505{
1506 j = {std::get<Idx>(t)...};
1507}
1508
1509template <typename BasicJsonType, typename... Args>
1510void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1511{
1512 to_json_tuple_impl(j, t, index_sequence_for<Args...>{});
1513}
1514
1515struct to_json_fn {
1516 private:
1517 template <typename BasicJsonType, typename T>
1518 auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1519 -> decltype(to_json(j, std::forward<T>(val)), void())
1520 {
1521 return to_json(j, std::forward<T>(val));
1522 }
1523
1524 template <typename BasicJsonType, typename T>
1525 void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1526 {
1527 static_assert(sizeof(BasicJsonType) == 0,
1528 "could not find to_json() method in T's namespace");
1529
1530#ifdef _MSC_VER
1531 // MSVC does not show a stacktrace for the above assert
1532 using decayed = uncvref_t<T>;
1533 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1534 "forcing MSVC stacktrace to show which T we're talking about.");
1535#endif
1536 }
1537
1538 public:
1539 template <typename BasicJsonType, typename T>
1540 void operator()(BasicJsonType& j, T&& val) const
1541 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1>{})))
1542 {
1543 return call(j, std::forward<T>(val), priority_tag<1>{});
1544 }
1545};
1546} // namespace detail
1547
1549namespace
1550{
1551constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1552}
1553} // namespace nlohmann
1554
1555// #include <nlohmann/detail/input/input_adapters.hpp>
1556
1557#include <algorithm> // min
1558#include <array> // array
1559#include <cassert> // assert
1560#include <cstddef> // size_t
1561#include <cstring> // strlen
1562#include <ios> // streamsize, streamoff, streampos
1563#include <istream> // istream
1564#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1565#include <memory> // shared_ptr, make_shared, addressof
1566#include <numeric> // accumulate
1567#include <string> // string, char_traits
1568#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1569#include <utility> // pair, declval
1570
1571// #include <nlohmann/detail/macro_scope.hpp>
1572
1573namespace nlohmann
1574{
1575namespace detail
1576{
1578// input adapters //
1580
1592struct input_adapter_protocol {
1594 virtual std::char_traits<char>::int_type get_character() = 0;
1596 virtual void unget_character() = 0;
1597 virtual ~input_adapter_protocol() = default;
1598};
1599
1601using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1602
1612class input_stream_adapter : public input_adapter_protocol
1613{
1614 public:
1615 ~input_stream_adapter() override
1616 {
1617 // clear stream flags; we use underlying streambuf I/O, do not
1618 // maintain ifstream flags
1619 is.clear();
1620 }
1621
1622 explicit input_stream_adapter(std::istream& i)
1623 : is(i), sb(*i.rdbuf())
1624 {
1625 // skip byte order mark
1626 std::char_traits<char>::int_type c;
1627 if ((c = get_character()) == 0xEF) {
1628 if ((c = get_character()) == 0xBB) {
1629 if ((c = get_character()) == 0xBF) {
1630 return; // Ignore BOM
1631 } else if (c != std::char_traits<char>::eof()) {
1632 is.unget();
1633 }
1634 is.putback('\xBB');
1635 } else if (c != std::char_traits<char>::eof()) {
1636 is.unget();
1637 }
1638 is.putback('\xEF');
1639 } else if (c != std::char_traits<char>::eof()) {
1640 is.unget(); // no byte order mark; process as usual
1641 }
1642 }
1643
1644 // delete because of pointer members
1645 input_stream_adapter(const input_stream_adapter&) = delete;
1646 input_stream_adapter& operator=(input_stream_adapter&) = delete;
1647
1648 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1649 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
1650 // end up as the same value, eg. 0xFFFFFFFF.
1651 std::char_traits<char>::int_type get_character() override
1652 {
1653 return sb.sbumpc();
1654 }
1655
1656 void unget_character() override
1657 {
1658 sb.sungetc(); // is.unget() avoided for performance
1659 }
1660
1661 private:
1663 std::istream& is;
1664 std::streambuf& sb;
1665};
1666
1668class input_buffer_adapter : public input_adapter_protocol
1669{
1670 public:
1671 input_buffer_adapter(const char* b, const std::size_t l)
1672 : cursor(b), limit(b + l), start(b)
1673 {
1674 // skip byte order mark
1675 if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') {
1676 cursor += 3;
1677 }
1678 }
1679
1680 // delete because of pointer members
1681 input_buffer_adapter(const input_buffer_adapter&) = delete;
1682 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1683
1684 std::char_traits<char>::int_type get_character() noexcept override
1685 {
1686 if (JSON_LIKELY(cursor < limit)) {
1687 return std::char_traits<char>::to_int_type(*(cursor++));
1688 }
1689
1690 return std::char_traits<char>::eof();
1691 }
1692
1693 void unget_character() noexcept override
1694 {
1695 if (JSON_LIKELY(cursor > start)) {
1696 --cursor;
1697 }
1698 }
1699
1700 private:
1702 const char* cursor;
1704 const char* limit;
1706 const char* start;
1707};
1708
1709class input_adapter
1710{
1711 public:
1712 // native support
1713
1715 input_adapter(std::istream& i)
1716 : ia(std::make_shared<input_stream_adapter>(i)) {}
1717
1719 input_adapter(std::istream&& i)
1720 : ia(std::make_shared<input_stream_adapter>(i)) {}
1721
1723 template <typename CharT,
1724 typename std::enable_if<
1725 std::is_pointer<CharT>::value and
1726 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1727 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1728 int>::type = 0>
1729 input_adapter(CharT b, std::size_t l)
1730 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l))
1731 {
1732 }
1733
1734 // derived support
1735
1737 template <typename CharT,
1738 typename std::enable_if<
1739 std::is_pointer<CharT>::value and
1740 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1741 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1742 int>::type = 0>
1743 input_adapter(CharT b)
1744 : input_adapter(reinterpret_cast<const char*>(b),
1745 std::strlen(reinterpret_cast<const char*>(b)))
1746 {
1747 }
1748
1750 template <class IteratorType,
1751 typename std::enable_if<
1752 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1753 int>::type = 0>
1754 input_adapter(IteratorType first, IteratorType last)
1755 {
1756 // assertion to check that the iterator range is indeed contiguous,
1757 // see http://stackoverflow.com/a/35008842/266378 for more discussion
1758 assert(std::accumulate(
1759 first, last, std::pair<bool, int>(true, 0),
1760 [&first](std::pair<bool, int> res, decltype(*first) val) {
1761 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1762 return res;
1763 })
1764 .first);
1765
1766 // assertion to check that each element is 1 byte long
1767 static_assert(
1768 sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1769 "each element in the iterator range must have the size of 1 byte");
1770
1771 const auto len = static_cast<size_t>(std::distance(first, last));
1772 if (JSON_LIKELY(len > 0)) {
1773 // there is at least one element: use the address of first
1774 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
1775 } else {
1776 // the address of first cannot be used: use nullptr
1777 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1778 }
1779 }
1780
1782 template <class T, std::size_t N>
1783 input_adapter(T (&array)[N])
1784 : input_adapter(std::begin(array), std::end(array))
1785 {
1786 }
1787
1789 template <class ContiguousContainer, typename std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1790 std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1791 int>::type = 0>
1792 input_adapter(const ContiguousContainer& c)
1793 : input_adapter(std::begin(c), std::end(c))
1794 {
1795 }
1796
1797 operator input_adapter_t()
1798 {
1799 return ia;
1800 }
1801
1802 private:
1804 input_adapter_t ia = nullptr;
1805};
1806} // namespace detail
1807} // namespace nlohmann
1808
1809// #include <nlohmann/detail/input/lexer.hpp>
1810
1811#include <clocale> // localeconv
1812#include <cstddef> // size_t
1813#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
1814#include <initializer_list> // initializer_list
1815#include <ios> // hex, uppercase
1816#include <iomanip> // setw, setfill
1817#include <sstream> // stringstream
1818#include <string> // char_traits, string
1819#include <vector> // vector
1820
1821// #include <nlohmann/detail/macro_scope.hpp>
1822
1823// #include <nlohmann/detail/input/input_adapters.hpp>
1824
1825namespace nlohmann
1826{
1827namespace detail
1828{
1830// lexer //
1832
1838template <typename BasicJsonType>
1839class lexer
1840{
1841 using number_integer_t = typename BasicJsonType::number_integer_t;
1842 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1843 using number_float_t = typename BasicJsonType::number_float_t;
1844 using string_t = typename BasicJsonType::string_t;
1845
1846 public:
1848 enum class token_type {
1849 uninitialized,
1850 literal_true,
1851 literal_false,
1852 literal_null,
1853 value_string,
1854 value_unsigned,
1855 value_integer,
1856 value_float,
1857 begin_array,
1858 begin_object,
1859 end_array,
1860 end_object,
1861 name_separator,
1862 value_separator,
1863 parse_error,
1864 end_of_input,
1865 literal_or_value
1866 };
1867
1869 static const char* token_type_name(const token_type t) noexcept
1870 {
1871 switch (t) {
1872 case token_type::uninitialized:
1873 return "<uninitialized>";
1874 case token_type::literal_true:
1875 return "true literal";
1876 case token_type::literal_false:
1877 return "false literal";
1878 case token_type::literal_null:
1879 return "null literal";
1880 case token_type::value_string:
1881 return "string literal";
1882 case lexer::token_type::value_unsigned:
1883 case lexer::token_type::value_integer:
1884 case lexer::token_type::value_float:
1885 return "number literal";
1886 case token_type::begin_array:
1887 return "'['";
1888 case token_type::begin_object:
1889 return "'{'";
1890 case token_type::end_array:
1891 return "']'";
1892 case token_type::end_object:
1893 return "'}'";
1894 case token_type::name_separator:
1895 return "':'";
1896 case token_type::value_separator:
1897 return "','";
1898 case token_type::parse_error:
1899 return "<parse error>";
1900 case token_type::end_of_input:
1901 return "end of input";
1902 case token_type::literal_or_value:
1903 return "'[', '{', or a literal";
1904 default: // catch non-enum values
1905 return "unknown token"; // LCOV_EXCL_LINE
1906 }
1907 }
1908
1909 explicit lexer(detail::input_adapter_t adapter)
1910 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1911
1912 // delete because of pointer members
1913 lexer(const lexer&) = delete;
1914 lexer& operator=(lexer&) = delete;
1915
1916 private:
1918 // locales
1920
1922 static char get_decimal_point() noexcept
1923 {
1924 const auto loc = localeconv();
1925 assert(loc != nullptr);
1926 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
1927 }
1928
1930 // scan functions
1932
1948 int get_codepoint()
1949 {
1950 // this function only makes sense after reading `\u`
1951 assert(current == 'u');
1952 int codepoint = 0;
1953
1954 const auto factors = {12, 8, 4, 0};
1955 for (const auto factor : factors) {
1956 get();
1957
1958 if (current >= '0' and current <= '9') {
1959 codepoint += ((current - 0x30) << factor);
1960 } else if (current >= 'A' and current <= 'F') {
1961 codepoint += ((current - 0x37) << factor);
1962 } else if (current >= 'a' and current <= 'f') {
1963 codepoint += ((current - 0x57) << factor);
1964 } else {
1965 return -1;
1966 }
1967 }
1968
1969 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
1970 return codepoint;
1971 }
1972
1988 bool next_byte_in_range(std::initializer_list<int> ranges)
1989 {
1990 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
1991 add(current);
1992
1993 for (auto range = ranges.begin(); range != ranges.end(); ++range) {
1994 get();
1995 if (JSON_LIKELY(*range <= current and current <= *(++range))) {
1996 add(current);
1997 } else {
1998 error_message = "invalid string: ill-formed UTF-8 byte";
1999 return false;
2000 }
2001 }
2002
2003 return true;
2004 }
2005
2021 token_type scan_string()
2022 {
2023 // reset token_buffer (ignore opening quote)
2024 reset();
2025
2026 // we entered the function by reading an open quote
2027 assert(current == '\"');
2028
2029 while (true) {
2030 // get next character
2031 switch (get()) {
2032 // end of file while parsing string
2033 case std::char_traits<char>::eof(): {
2034 error_message = "invalid string: missing closing quote";
2035 return token_type::parse_error;
2036 }
2037
2038 // closing quote
2039 case '\"': {
2040 return token_type::value_string;
2041 }
2042
2043 // escapes
2044 case '\\': {
2045 switch (get()) {
2046 // quotation mark
2047 case '\"':
2048 add('\"');
2049 break;
2050 // reverse solidus
2051 case '\\':
2052 add('\\');
2053 break;
2054 // solidus
2055 case '/':
2056 add('/');
2057 break;
2058 // backspace
2059 case 'b':
2060 add('\b');
2061 break;
2062 // form feed
2063 case 'f':
2064 add('\f');
2065 break;
2066 // line feed
2067 case 'n':
2068 add('\n');
2069 break;
2070 // carriage return
2071 case 'r':
2072 add('\r');
2073 break;
2074 // tab
2075 case 't':
2076 add('\t');
2077 break;
2078
2079 // unicode escapes
2080 case 'u': {
2081 const int codepoint1 = get_codepoint();
2082 int codepoint = codepoint1; // start with codepoint1
2083
2084 if (JSON_UNLIKELY(codepoint1 == -1)) {
2085 error_message = R"(invalid string: '\u' must be followed by 4 hex digits)";
2086 return token_type::parse_error;
2087 }
2088
2089 // check if code point is a high surrogate
2090 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
2091 // expect next \uxxxx entry
2092 if (JSON_LIKELY(get() == '\\' and get() == 'u')) {
2093 const int codepoint2 = get_codepoint();
2094
2095 if (JSON_UNLIKELY(codepoint2 == -1)) {
2096 error_message = R"(invalid string: '\u' must be followed by 4 hex digits)";
2097 return token_type::parse_error;
2098 }
2099
2100 // check if codepoint2 is a low surrogate
2101 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
2102 // overwrite codepoint
2103 codepoint =
2104 // high surrogate occupies the most significant 22 bits
2105 (codepoint1 << 10)
2106 // low surrogate occupies the least significant 15 bits
2107 + codepoint2
2108 // there is still the 0xD800, 0xDC00 and 0x10000 noise
2109 // in the result so we have to subtract with:
2110 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2111 - 0x35FDC00;
2112 } else {
2113 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2114 return token_type::parse_error;
2115 }
2116 } else {
2117 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2118 return token_type::parse_error;
2119 }
2120 } else {
2121 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
2122 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2123 return token_type::parse_error;
2124 }
2125 }
2126
2127 // result of the above calculation yields a proper codepoint
2128 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2129
2130 // translate codepoint into bytes
2131 if (codepoint < 0x80) {
2132 // 1-byte characters: 0xxxxxxx (ASCII)
2133 add(codepoint);
2134 } else if (codepoint <= 0x7FF) {
2135 // 2-byte characters: 110xxxxx 10xxxxxx
2136 add(0xC0 | (codepoint >> 6));
2137 add(0x80 | (codepoint & 0x3F));
2138 } else if (codepoint <= 0xFFFF) {
2139 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2140 add(0xE0 | (codepoint >> 12));
2141 add(0x80 | ((codepoint >> 6) & 0x3F));
2142 add(0x80 | (codepoint & 0x3F));
2143 } else {
2144 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2145 add(0xF0 | (codepoint >> 18));
2146 add(0x80 | ((codepoint >> 12) & 0x3F));
2147 add(0x80 | ((codepoint >> 6) & 0x3F));
2148 add(0x80 | (codepoint & 0x3F));
2149 }
2150
2151 break;
2152 }
2153
2154 // other characters after escape
2155 default:
2156 error_message = "invalid string: forbidden character after backslash";
2157 return token_type::parse_error;
2158 }
2159
2160 break;
2161 }
2162
2163 // invalid control characters
2164 case 0x00:
2165 case 0x01:
2166 case 0x02:
2167 case 0x03:
2168 case 0x04:
2169 case 0x05:
2170 case 0x06:
2171 case 0x07:
2172 case 0x08:
2173 case 0x09:
2174 case 0x0A:
2175 case 0x0B:
2176 case 0x0C:
2177 case 0x0D:
2178 case 0x0E:
2179 case 0x0F:
2180 case 0x10:
2181 case 0x11:
2182 case 0x12:
2183 case 0x13:
2184 case 0x14:
2185 case 0x15:
2186 case 0x16:
2187 case 0x17:
2188 case 0x18:
2189 case 0x19:
2190 case 0x1A:
2191 case 0x1B:
2192 case 0x1C:
2193 case 0x1D:
2194 case 0x1E:
2195 case 0x1F: {
2196 error_message = "invalid string: control character must be escaped";
2197 return token_type::parse_error;
2198 }
2199
2200 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2201 case 0x20:
2202 case 0x21:
2203 case 0x23:
2204 case 0x24:
2205 case 0x25:
2206 case 0x26:
2207 case 0x27:
2208 case 0x28:
2209 case 0x29:
2210 case 0x2A:
2211 case 0x2B:
2212 case 0x2C:
2213 case 0x2D:
2214 case 0x2E:
2215 case 0x2F:
2216 case 0x30:
2217 case 0x31:
2218 case 0x32:
2219 case 0x33:
2220 case 0x34:
2221 case 0x35:
2222 case 0x36:
2223 case 0x37:
2224 case 0x38:
2225 case 0x39:
2226 case 0x3A:
2227 case 0x3B:
2228 case 0x3C:
2229 case 0x3D:
2230 case 0x3E:
2231 case 0x3F:
2232 case 0x40:
2233 case 0x41:
2234 case 0x42:
2235 case 0x43:
2236 case 0x44:
2237 case 0x45:
2238 case 0x46:
2239 case 0x47:
2240 case 0x48:
2241 case 0x49:
2242 case 0x4A:
2243 case 0x4B:
2244 case 0x4C:
2245 case 0x4D:
2246 case 0x4E:
2247 case 0x4F:
2248 case 0x50:
2249 case 0x51:
2250 case 0x52:
2251 case 0x53:
2252 case 0x54:
2253 case 0x55:
2254 case 0x56:
2255 case 0x57:
2256 case 0x58:
2257 case 0x59:
2258 case 0x5A:
2259 case 0x5B:
2260 case 0x5D:
2261 case 0x5E:
2262 case 0x5F:
2263 case 0x60:
2264 case 0x61:
2265 case 0x62:
2266 case 0x63:
2267 case 0x64:
2268 case 0x65:
2269 case 0x66:
2270 case 0x67:
2271 case 0x68:
2272 case 0x69:
2273 case 0x6A:
2274 case 0x6B:
2275 case 0x6C:
2276 case 0x6D:
2277 case 0x6E:
2278 case 0x6F:
2279 case 0x70:
2280 case 0x71:
2281 case 0x72:
2282 case 0x73:
2283 case 0x74:
2284 case 0x75:
2285 case 0x76:
2286 case 0x77:
2287 case 0x78:
2288 case 0x79:
2289 case 0x7A:
2290 case 0x7B:
2291 case 0x7C:
2292 case 0x7D:
2293 case 0x7E:
2294 case 0x7F: {
2295 add(current);
2296 break;
2297 }
2298
2299 // U+0080..U+07FF: bytes C2..DF 80..BF
2300 case 0xC2:
2301 case 0xC3:
2302 case 0xC4:
2303 case 0xC5:
2304 case 0xC6:
2305 case 0xC7:
2306 case 0xC8:
2307 case 0xC9:
2308 case 0xCA:
2309 case 0xCB:
2310 case 0xCC:
2311 case 0xCD:
2312 case 0xCE:
2313 case 0xCF:
2314 case 0xD0:
2315 case 0xD1:
2316 case 0xD2:
2317 case 0xD3:
2318 case 0xD4:
2319 case 0xD5:
2320 case 0xD6:
2321 case 0xD7:
2322 case 0xD8:
2323 case 0xD9:
2324 case 0xDA:
2325 case 0xDB:
2326 case 0xDC:
2327 case 0xDD:
2328 case 0xDE:
2329 case 0xDF: {
2330 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) {
2331 return token_type::parse_error;
2332 }
2333 break;
2334 }
2335
2336 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2337 case 0xE0: {
2338 if (JSON_UNLIKELY(not(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) {
2339 return token_type::parse_error;
2340 }
2341 break;
2342 }
2343
2344 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2345 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2346 case 0xE1:
2347 case 0xE2:
2348 case 0xE3:
2349 case 0xE4:
2350 case 0xE5:
2351 case 0xE6:
2352 case 0xE7:
2353 case 0xE8:
2354 case 0xE9:
2355 case 0xEA:
2356 case 0xEB:
2357 case 0xEC:
2358 case 0xEE:
2359 case 0xEF: {
2360 if (JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) {
2361 return token_type::parse_error;
2362 }
2363 break;
2364 }
2365
2366 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2367 case 0xED: {
2368 if (JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) {
2369 return token_type::parse_error;
2370 }
2371 break;
2372 }
2373
2374 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2375 case 0xF0: {
2376 if (JSON_UNLIKELY(not(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
2377 return token_type::parse_error;
2378 }
2379 break;
2380 }
2381
2382 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2383 case 0xF1:
2384 case 0xF2:
2385 case 0xF3: {
2386 if (JSON_UNLIKELY(not(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) {
2387 return token_type::parse_error;
2388 }
2389 break;
2390 }
2391
2392 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2393 case 0xF4: {
2394 if (JSON_UNLIKELY(not(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) {
2395 return token_type::parse_error;
2396 }
2397 break;
2398 }
2399
2400 // remaining bytes (80..C1 and F5..FF) are ill-formed
2401 default: {
2402 error_message = "invalid string: ill-formed UTF-8 byte";
2403 return token_type::parse_error;
2404 }
2405 }
2406 }
2407 }
2408
2409 static void strtof(float& f, const char* str, char** endptr) noexcept
2410 {
2411 f = std::strtof(str, endptr);
2412 }
2413
2414 static void strtof(double& f, const char* str, char** endptr) noexcept
2415 {
2416 f = std::strtod(str, endptr);
2417 }
2418
2419 static void strtof(long double& f, const char* str, char** endptr) noexcept
2420 {
2421 f = std::strtold(str, endptr);
2422 }
2423
2464 token_type scan_number()
2465 {
2466 // reset token_buffer to store the number's bytes
2467 reset();
2468
2469 // the type of the parsed number; initially set to unsigned; will be
2470 // changed if minus sign, decimal point or exponent is read
2471 token_type number_type = token_type::value_unsigned;
2472
2473 // state (init): we just found out we need to scan a number
2474 switch (current) {
2475 case '-': {
2476 add(current);
2477 goto scan_number_minus;
2478 }
2479
2480 case '0': {
2481 add(current);
2482 goto scan_number_zero;
2483 }
2484
2485 case '1':
2486 case '2':
2487 case '3':
2488 case '4':
2489 case '5':
2490 case '6':
2491 case '7':
2492 case '8':
2493 case '9': {
2494 add(current);
2495 goto scan_number_any1;
2496 }
2497
2498 default: {
2499 // all other characters are rejected outside scan_number()
2500 assert(false); // LCOV_EXCL_LINE
2501 }
2502 }
2503
2504 scan_number_minus:
2505 // state: we just parsed a leading minus sign
2506 number_type = token_type::value_integer;
2507 switch (get()) {
2508 case '0': {
2509 add(current);
2510 goto scan_number_zero;
2511 }
2512
2513 case '1':
2514 case '2':
2515 case '3':
2516 case '4':
2517 case '5':
2518 case '6':
2519 case '7':
2520 case '8':
2521 case '9': {
2522 add(current);
2523 goto scan_number_any1;
2524 }
2525
2526 default: {
2527 error_message = "invalid number; expected digit after '-'";
2528 return token_type::parse_error;
2529 }
2530 }
2531
2532 scan_number_zero:
2533 // state: we just parse a zero (maybe with a leading minus sign)
2534 switch (get()) {
2535 case '.': {
2536 add(decimal_point_char);
2537 goto scan_number_decimal1;
2538 }
2539
2540 case 'e':
2541 case 'E': {
2542 add(current);
2543 goto scan_number_exponent;
2544 }
2545
2546 default:
2547 goto scan_number_done;
2548 }
2549
2550 scan_number_any1:
2551 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2552 switch (get()) {
2553 case '0':
2554 case '1':
2555 case '2':
2556 case '3':
2557 case '4':
2558 case '5':
2559 case '6':
2560 case '7':
2561 case '8':
2562 case '9': {
2563 add(current);
2564 goto scan_number_any1;
2565 }
2566
2567 case '.': {
2568 add(decimal_point_char);
2569 goto scan_number_decimal1;
2570 }
2571
2572 case 'e':
2573 case 'E': {
2574 add(current);
2575 goto scan_number_exponent;
2576 }
2577
2578 default:
2579 goto scan_number_done;
2580 }
2581
2582 scan_number_decimal1:
2583 // state: we just parsed a decimal point
2584 number_type = token_type::value_float;
2585 switch (get()) {
2586 case '0':
2587 case '1':
2588 case '2':
2589 case '3':
2590 case '4':
2591 case '5':
2592 case '6':
2593 case '7':
2594 case '8':
2595 case '9': {
2596 add(current);
2597 goto scan_number_decimal2;
2598 }
2599
2600 default: {
2601 error_message = "invalid number; expected digit after '.'";
2602 return token_type::parse_error;
2603 }
2604 }
2605
2606 scan_number_decimal2:
2607 // we just parsed at least one number after a decimal point
2608 switch (get()) {
2609 case '0':
2610 case '1':
2611 case '2':
2612 case '3':
2613 case '4':
2614 case '5':
2615 case '6':
2616 case '7':
2617 case '8':
2618 case '9': {
2619 add(current);
2620 goto scan_number_decimal2;
2621 }
2622
2623 case 'e':
2624 case 'E': {
2625 add(current);
2626 goto scan_number_exponent;
2627 }
2628
2629 default:
2630 goto scan_number_done;
2631 }
2632
2633 scan_number_exponent:
2634 // we just parsed an exponent
2635 number_type = token_type::value_float;
2636 switch (get()) {
2637 case '+':
2638 case '-': {
2639 add(current);
2640 goto scan_number_sign;
2641 }
2642
2643 case '0':
2644 case '1':
2645 case '2':
2646 case '3':
2647 case '4':
2648 case '5':
2649 case '6':
2650 case '7':
2651 case '8':
2652 case '9': {
2653 add(current);
2654 goto scan_number_any2;
2655 }
2656
2657 default: {
2658 error_message =
2659 "invalid number; expected '+', '-', or digit after exponent";
2660 return token_type::parse_error;
2661 }
2662 }
2663
2664 scan_number_sign:
2665 // we just parsed an exponent sign
2666 switch (get()) {
2667 case '0':
2668 case '1':
2669 case '2':
2670 case '3':
2671 case '4':
2672 case '5':
2673 case '6':
2674 case '7':
2675 case '8':
2676 case '9': {
2677 add(current);
2678 goto scan_number_any2;
2679 }
2680
2681 default: {
2682 error_message = "invalid number; expected digit after exponent sign";
2683 return token_type::parse_error;
2684 }
2685 }
2686
2687 scan_number_any2:
2688 // we just parsed a number after the exponent or exponent sign
2689 switch (get()) {
2690 case '0':
2691 case '1':
2692 case '2':
2693 case '3':
2694 case '4':
2695 case '5':
2696 case '6':
2697 case '7':
2698 case '8':
2699 case '9': {
2700 add(current);
2701 goto scan_number_any2;
2702 }
2703
2704 default:
2705 goto scan_number_done;
2706 }
2707
2708 scan_number_done:
2709 // unget the character after the number (we only read it to know that
2710 // we are done scanning a number)
2711 unget();
2712
2713 char* endptr = nullptr;
2714 errno = 0;
2715
2716 // try to parse integers first and fall back to floats
2717 if (number_type == token_type::value_unsigned) {
2718 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2719
2720 // we checked the number format before
2721 assert(endptr == token_buffer.data() + token_buffer.size());
2722
2723 if (errno == 0) {
2724 value_unsigned = static_cast<number_unsigned_t>(x);
2725 if (value_unsigned == x) {
2726 return token_type::value_unsigned;
2727 }
2728 }
2729 } else if (number_type == token_type::value_integer) {
2730 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2731
2732 // we checked the number format before
2733 assert(endptr == token_buffer.data() + token_buffer.size());
2734
2735 if (errno == 0) {
2736 value_integer = static_cast<number_integer_t>(x);
2737 if (value_integer == x) {
2738 return token_type::value_integer;
2739 }
2740 }
2741 }
2742
2743 // this code is reached if we parse a floating-point number or if an
2744 // integer conversion above failed
2745 strtof(value_float, token_buffer.data(), &endptr);
2746
2747 // we checked the number format before
2748 assert(endptr == token_buffer.data() + token_buffer.size());
2749
2750 return token_type::value_float;
2751 }
2752
2758 token_type scan_literal(const char* literal_text, const std::size_t length,
2759 token_type return_type)
2760 {
2761 assert(current == literal_text[0]);
2762 for (std::size_t i = 1; i < length; ++i) {
2763 if (JSON_UNLIKELY(get() != literal_text[i])) {
2764 error_message = "invalid literal";
2765 return token_type::parse_error;
2766 }
2767 }
2768 return return_type;
2769 }
2770
2772 // input management
2774
2776 void reset() noexcept
2777 {
2778 token_buffer.clear();
2779 token_string.clear();
2780 token_string.push_back(std::char_traits<char>::to_char_type(current));
2781 }
2782
2783 /*
2784 @brief get next character from the input
2785
2786 This function provides the interface to the used input adapter. It does
2787 not throw in case the input reached EOF, but returns a
2788 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
2789 for use in error messages.
2790
2791 @return character read from the input
2792 */
2793 std::char_traits<char>::int_type get()
2794 {
2795 ++chars_read;
2796 current = ia->get_character();
2797 if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2798 token_string.push_back(std::char_traits<char>::to_char_type(current));
2799 }
2800 return current;
2801 }
2802
2804 void unget()
2805 {
2806 --chars_read;
2807 if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2808 ia->unget_character();
2809 assert(token_string.size() != 0);
2810 token_string.pop_back();
2811 }
2812 }
2813
2815 void add(int c)
2816 {
2817 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2818 }
2819
2820 public:
2822 // value getters
2824
2826 constexpr number_integer_t get_number_integer() const noexcept
2827 {
2828 return value_integer;
2829 }
2830
2832 constexpr number_unsigned_t get_number_unsigned() const noexcept
2833 {
2834 return value_unsigned;
2835 }
2836
2838 constexpr number_float_t get_number_float() const noexcept
2839 {
2840 return value_float;
2841 }
2842
2844 string_t&& move_string()
2845 {
2846 return std::move(token_buffer);
2847 }
2848
2850 // diagnostics
2852
2854 constexpr std::size_t get_position() const noexcept
2855 {
2856 return chars_read;
2857 }
2858
2862 std::string get_token_string() const
2863 {
2864 // escape control characters
2865 std::string result;
2866 for (const auto c : token_string) {
2867 if ('\x00' <= c and c <= '\x1F') {
2868 // escape control characters
2869 std::stringstream ss;
2870 ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
2871 << std::hex << static_cast<int>(c) << ">";
2872 result += ss.str();
2873 } else {
2874 // add character as is
2875 result.push_back(c);
2876 }
2877 }
2878
2879 return result;
2880 }
2881
2883 constexpr const char* get_error_message() const noexcept
2884 {
2885 return error_message;
2886 }
2887
2889 // actual scanner
2891
2892 token_type scan()
2893 {
2894 // read next character and ignore whitespace
2895 do {
2896 get();
2897 } while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2898
2899 switch (current) {
2900 // structural characters
2901 case '[':
2902 return token_type::begin_array;
2903 case ']':
2904 return token_type::end_array;
2905 case '{':
2906 return token_type::begin_object;
2907 case '}':
2908 return token_type::end_object;
2909 case ':':
2910 return token_type::name_separator;
2911 case ',':
2912 return token_type::value_separator;
2913
2914 // literals
2915 case 't':
2916 return scan_literal("true", 4, token_type::literal_true);
2917 case 'f':
2918 return scan_literal("false", 5, token_type::literal_false);
2919 case 'n':
2920 return scan_literal("null", 4, token_type::literal_null);
2921
2922 // string
2923 case '\"':
2924 return scan_string();
2925
2926 // number
2927 case '-':
2928 case '0':
2929 case '1':
2930 case '2':
2931 case '3':
2932 case '4':
2933 case '5':
2934 case '6':
2935 case '7':
2936 case '8':
2937 case '9':
2938 return scan_number();
2939
2940 // end of input (the null byte is needed when parsing from
2941 // string literals)
2942 case '\0':
2943 case std::char_traits<char>::eof():
2944 return token_type::end_of_input;
2945
2946 // error
2947 default:
2948 error_message = "invalid literal";
2949 return token_type::parse_error;
2950 }
2951 }
2952
2953 private:
2955 detail::input_adapter_t ia = nullptr;
2956
2958 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2959
2961 std::size_t chars_read = 0;
2962
2964 std::vector<char> token_string{};
2965
2967 string_t token_buffer{};
2968
2970 const char* error_message = "";
2971
2972 // number values
2973 number_integer_t value_integer = 0;
2974 number_unsigned_t value_unsigned = 0;
2975 number_float_t value_float = 0;
2976
2978 const char decimal_point_char = '.';
2979};
2980} // namespace detail
2981} // namespace nlohmann
2982
2983// #include <nlohmann/detail/input/parser.hpp>
2984
2985#include <cassert> // assert
2986#include <cmath> // isfinite
2987#include <cstdint> // uint8_t
2988#include <functional> // function
2989#include <string> // string
2990#include <utility> // move
2991
2992// #include <nlohmann/detail/exceptions.hpp>
2993
2994// #include <nlohmann/detail/macro_scope.hpp>
2995
2996// #include <nlohmann/detail/input/input_adapters.hpp>
2997
2998// #include <nlohmann/detail/input/lexer.hpp>
2999
3000// #include <nlohmann/detail/value_t.hpp>
3001
3002namespace nlohmann
3003{
3004namespace detail
3005{
3007// parser //
3009
3015template <typename BasicJsonType>
3017{
3018 using number_integer_t = typename BasicJsonType::number_integer_t;
3019 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3020 using number_float_t = typename BasicJsonType::number_float_t;
3021 using string_t = typename BasicJsonType::string_t;
3022 using lexer_t = lexer<BasicJsonType>;
3023 using token_type = typename lexer_t::token_type;
3024
3025 public:
3026 enum class parse_event_t : uint8_t {
3030 object_end,
3034 array_end,
3036 key,
3038 value
3039 };
3040
3042 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
3043
3045 explicit parser(detail::input_adapter_t adapter,
3046 const parser_callback_t cb = nullptr,
3047 const bool allow_exceptions_ = true)
3048 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3049 {
3050 }
3051
3062 void parse(const bool strict, BasicJsonType& result)
3063 {
3064 // read first token
3065 get_token();
3066
3067 parse_internal(true, result);
3068 result.assert_invariant();
3069
3070 // in strict mode, input must be completely read
3071 if (strict) {
3072 get_token();
3073 expect(token_type::end_of_input);
3074 }
3075
3076 // in case of an error, return discarded value
3077 if (errored) {
3078 result = value_t::discarded;
3079 return;
3080 }
3081
3082 // set top-level value to null if it was discarded by the callback
3083 // function
3084 if (result.is_discarded()) {
3085 result = nullptr;
3086 }
3087 }
3088
3095 bool accept(const bool strict = true)
3096 {
3097 // read first token
3098 get_token();
3099
3100 if (not accept_internal()) {
3101 return false;
3102 }
3103
3104 // strict => last token must be EOF
3105 return not strict or (get_token() == token_type::end_of_input);
3106 }
3107
3108 private:
3115 void parse_internal(bool keep, BasicJsonType& result)
3116 {
3117 // never parse after a parse error was detected
3118 assert(not errored);
3119
3120 // start with a discarded value
3121 if (not result.is_discarded()) {
3122 result.m_value.destroy(result.m_type);
3123 result.m_type = value_t::discarded;
3124 }
3125
3126 switch (last_token) {
3127 case token_type::begin_object: {
3128 if (keep) {
3129 if (callback) {
3130 keep = callback(depth++, parse_event_t::object_start, result);
3131 }
3132
3133 if (not callback or keep) {
3134 // explicitly set result to object to cope with {}
3135 result.m_type = value_t::object;
3136 result.m_value = value_t::object;
3137 }
3138 }
3139
3140 // read next token
3141 get_token();
3142
3143 // closing } -> we are done
3144 if (last_token == token_type::end_object) {
3145 if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3146 result.m_value.destroy(result.m_type);
3147 result.m_type = value_t::discarded;
3148 }
3149 break;
3150 }
3151
3152 // parse values
3153 string_t key;
3154 BasicJsonType value;
3155 while (true) {
3156 // store key
3157 if (not expect(token_type::value_string)) {
3158 return;
3159 }
3160 key = m_lexer.move_string();
3161
3162 bool keep_tag = false;
3163 if (keep) {
3164 if (callback) {
3165 BasicJsonType k(key);
3166 keep_tag = callback(depth, parse_event_t::key, k);
3167 } else {
3168 keep_tag = true;
3169 }
3170 }
3171
3172 // parse separator (:)
3173 get_token();
3174 if (not expect(token_type::name_separator)) {
3175 return;
3176 }
3177
3178 // parse and add value
3179 get_token();
3180 value.m_value.destroy(value.m_type);
3181 value.m_type = value_t::discarded;
3182 parse_internal(keep, value);
3183
3184 if (JSON_UNLIKELY(errored)) {
3185 return;
3186 }
3187
3188 if (keep and keep_tag and not value.is_discarded()) {
3189 result.m_value.object->emplace(std::move(key), std::move(value));
3190 }
3191
3192 // comma -> next value
3193 get_token();
3194 if (last_token == token_type::value_separator) {
3195 get_token();
3196 continue;
3197 }
3198
3199 // closing }
3200 if (not expect(token_type::end_object)) {
3201 return;
3202 }
3203 break;
3204 }
3205
3206 if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3207 result.m_value.destroy(result.m_type);
3208 result.m_type = value_t::discarded;
3209 }
3210 break;
3211 }
3212
3213 case token_type::begin_array: {
3214 if (keep) {
3215 if (callback) {
3216 keep = callback(depth++, parse_event_t::array_start, result);
3217 }
3218
3219 if (not callback or keep) {
3220 // explicitly set result to array to cope with []
3221 result.m_type = value_t::array;
3222 result.m_value = value_t::array;
3223 }
3224 }
3225
3226 // read next token
3227 get_token();
3228
3229 // closing ] -> we are done
3230 if (last_token == token_type::end_array) {
3231 if (callback and not callback(--depth, parse_event_t::array_end, result)) {
3232 result.m_value.destroy(result.m_type);
3233 result.m_type = value_t::discarded;
3234 }
3235 break;
3236 }
3237
3238 // parse values
3239 BasicJsonType value;
3240 while (true) {
3241 // parse value
3242 value.m_value.destroy(value.m_type);
3243 value.m_type = value_t::discarded;
3244 parse_internal(keep, value);
3245
3246 if (JSON_UNLIKELY(errored)) {
3247 return;
3248 }
3249
3250 if (keep and not value.is_discarded()) {
3251 result.m_value.array->push_back(std::move(value));
3252 }
3253
3254 // comma -> next value
3255 get_token();
3256 if (last_token == token_type::value_separator) {
3257 get_token();
3258 continue;
3259 }
3260
3261 // closing ]
3262 if (not expect(token_type::end_array)) {
3263 return;
3264 }
3265 break;
3266 }
3267
3268 if (keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
3269 result.m_value.destroy(result.m_type);
3270 result.m_type = value_t::discarded;
3271 }
3272 break;
3273 }
3274
3275 case token_type::literal_null: {
3276 result.m_type = value_t::null;
3277 break;
3278 }
3279
3280 case token_type::value_string: {
3281 result.m_type = value_t::string;
3282 result.m_value = m_lexer.move_string();
3283 break;
3284 }
3285
3286 case token_type::literal_true: {
3287 result.m_type = value_t::boolean;
3288 result.m_value = true;
3289 break;
3290 }
3291
3292 case token_type::literal_false: {
3293 result.m_type = value_t::boolean;
3294 result.m_value = false;
3295 break;
3296 }
3297
3298 case token_type::value_unsigned: {
3299 result.m_type = value_t::number_unsigned;
3300 result.m_value = m_lexer.get_number_unsigned();
3301 break;
3302 }
3303
3304 case token_type::value_integer: {
3305 result.m_type = value_t::number_integer;
3306 result.m_value = m_lexer.get_number_integer();
3307 break;
3308 }
3309
3310 case token_type::value_float: {
3311 result.m_type = value_t::number_float;
3312 result.m_value = m_lexer.get_number_float();
3313
3314 // throw in case of infinity or NAN
3315 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
3316 if (allow_exceptions) {
3317 JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3318 m_lexer.get_token_string() + "'"));
3319 }
3320 expect(token_type::uninitialized);
3321 }
3322 break;
3323 }
3324
3325 case token_type::parse_error: {
3326 // using "uninitialized" to avoid "expected" message
3327 if (not expect(token_type::uninitialized)) {
3328 return;
3329 }
3330 break; // LCOV_EXCL_LINE
3331 }
3332
3333 default: {
3334 // the last token was unexpected; we expected a value
3335 if (not expect(token_type::literal_or_value)) {
3336 return;
3337 }
3338 break; // LCOV_EXCL_LINE
3339 }
3340 }
3341
3342 if (keep and callback and not callback(depth, parse_event_t::value, result)) {
3343 result.m_value.destroy(result.m_type);
3344 result.m_type = value_t::discarded;
3345 }
3346 }
3347
3358 bool accept_internal()
3359 {
3360 switch (last_token) {
3361 case token_type::begin_object: {
3362 // read next token
3363 get_token();
3364
3365 // closing } -> we are done
3366 if (last_token == token_type::end_object) {
3367 return true;
3368 }
3369
3370 // parse values
3371 while (true) {
3372 // parse key
3373 if (last_token != token_type::value_string) {
3374 return false;
3375 }
3376
3377 // parse separator (:)
3378 get_token();
3379 if (last_token != token_type::name_separator) {
3380 return false;
3381 }
3382
3383 // parse value
3384 get_token();
3385 if (not accept_internal()) {
3386 return false;
3387 }
3388
3389 // comma -> next value
3390 get_token();
3391 if (last_token == token_type::value_separator) {
3392 get_token();
3393 continue;
3394 }
3395
3396 // closing }
3397 return (last_token == token_type::end_object);
3398 }
3399 }
3400
3401 case token_type::begin_array: {
3402 // read next token
3403 get_token();
3404
3405 // closing ] -> we are done
3406 if (last_token == token_type::end_array) {
3407 return true;
3408 }
3409
3410 // parse values
3411 while (true) {
3412 // parse value
3413 if (not accept_internal()) {
3414 return false;
3415 }
3416
3417 // comma -> next value
3418 get_token();
3419 if (last_token == token_type::value_separator) {
3420 get_token();
3421 continue;
3422 }
3423
3424 // closing ]
3425 return (last_token == token_type::end_array);
3426 }
3427 }
3428
3429 case token_type::value_float: {
3430 // reject infinity or NAN
3431 return std::isfinite(m_lexer.get_number_float());
3432 }
3433
3434 case token_type::literal_false:
3435 case token_type::literal_null:
3436 case token_type::literal_true:
3437 case token_type::value_integer:
3438 case token_type::value_string:
3439 case token_type::value_unsigned:
3440 return true;
3441
3442 default: // the last token was unexpected
3443 return false;
3444 }
3445 }
3446
3448 token_type get_token()
3449 {
3450 return (last_token = m_lexer.scan());
3451 }
3452
3456 bool expect(token_type t)
3457 {
3458 if (JSON_UNLIKELY(t != last_token)) {
3459 errored = true;
3460 expected = t;
3461 if (allow_exceptions) {
3462 throw_exception();
3463 } else {
3464 return false;
3465 }
3466 }
3467
3468 return true;
3469 }
3470
3471 [[noreturn]] void throw_exception() const
3472 {
3473 std::string error_msg = "syntax error - ";
3474 if (last_token == token_type::parse_error) {
3475 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3476 m_lexer.get_token_string() + "'";
3477 } else {
3478 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3479 }
3480
3481 if (expected != token_type::uninitialized) {
3482 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3483 }
3484
3485 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3486 }
3487
3488 private:
3490 int depth = 0;
3492 const parser_callback_t callback = nullptr;
3494 token_type last_token = token_type::uninitialized;
3496 lexer_t m_lexer;
3498 bool errored = false;
3500 token_type expected = token_type::uninitialized;
3502 const bool allow_exceptions = true;
3503};
3504} // namespace detail
3505} // namespace nlohmann
3506
3507// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3508
3509#include <cstddef> // ptrdiff_t
3510#include <limits> // numeric_limits
3511
3512namespace nlohmann
3513{
3514namespace detail
3515{
3516/*
3517@brief an iterator for primitive JSON types
3518
3519This class models an iterator for primitive JSON types (boolean, number,
3520string). It's only purpose is to allow the iterator/const_iterator classes
3521to "iterate" over primitive values. Internally, the iterator is modeled by
3522a `difference_type` variable. Value begin_value (`0`) models the begin,
3523end_value (`1`) models past the end.
3524*/
3526{
3527 private:
3528 using difference_type = std::ptrdiff_t;
3529 static constexpr difference_type begin_value = 0;
3530 static constexpr difference_type end_value = begin_value + 1;
3531
3533 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3534
3535 public:
3536 constexpr difference_type get_value() const noexcept
3537 {
3538 return m_it;
3539 }
3540
3542 void set_begin() noexcept
3543 {
3544 m_it = begin_value;
3545 }
3546
3548 void set_end() noexcept
3549 {
3550 m_it = end_value;
3551 }
3552
3554 constexpr bool is_begin() const noexcept
3555 {
3556 return m_it == begin_value;
3557 }
3558
3560 constexpr bool is_end() const noexcept
3561 {
3562 return m_it == end_value;
3563 }
3564
3565 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3566 {
3567 return lhs.m_it == rhs.m_it;
3568 }
3569
3570 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3571 {
3572 return lhs.m_it < rhs.m_it;
3573 }
3574
3575 primitive_iterator_t operator+(difference_type n) noexcept
3576 {
3577 auto result = *this;
3578 result += n;
3579 return result;
3580 }
3581
3582 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3583 {
3584 return lhs.m_it - rhs.m_it;
3585 }
3586
3588 {
3589 ++m_it;
3590 return *this;
3591 }
3592
3594 {
3595 auto result = *this;
3596 m_it++;
3597 return result;
3598 }
3599
3601 {
3602 --m_it;
3603 return *this;
3604 }
3605
3607 {
3608 auto result = *this;
3609 m_it--;
3610 return result;
3611 }
3612
3613 primitive_iterator_t& operator+=(difference_type n) noexcept
3614 {
3615 m_it += n;
3616 return *this;
3617 }
3618
3619 primitive_iterator_t& operator-=(difference_type n) noexcept
3620 {
3621 m_it -= n;
3622 return *this;
3623 }
3624};
3625} // namespace detail
3626} // namespace nlohmann
3627
3628// #include <nlohmann/detail/iterators/internal_iterator.hpp>
3629
3630// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3631
3632namespace nlohmann
3633{
3634namespace detail
3635{
3642template <typename BasicJsonType>
3645 typename BasicJsonType::object_t::iterator object_iterator{};
3647 typename BasicJsonType::array_t::iterator array_iterator{};
3650};
3651} // namespace detail
3652} // namespace nlohmann
3653
3654// #include <nlohmann/detail/iterators/iter_impl.hpp>
3655
3656#include <ciso646> // not
3657#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
3658#include <type_traits> // conditional, is_const, remove_const
3659
3660// #include <nlohmann/detail/exceptions.hpp>
3661
3662// #include <nlohmann/detail/iterators/internal_iterator.hpp>
3663
3664// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3665
3666// #include <nlohmann/detail/macro_scope.hpp>
3667
3668// #include <nlohmann/detail/meta.hpp>
3669
3670// #include <nlohmann/detail/value_t.hpp>
3671
3672namespace nlohmann
3673{
3674namespace detail
3675{
3676// forward declare, to be able to friend it later on
3677template <typename IteratorType>
3678class iteration_proxy;
3679
3700template <typename BasicJsonType>
3702{
3704 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
3705 friend BasicJsonType;
3707
3708 using object_t = typename BasicJsonType::object_t;
3709 using array_t = typename BasicJsonType::array_t;
3710 // make sure BasicJsonType is basic_json or const basic_json
3712 "iter_impl only accepts (const) basic_json");
3713
3714 public:
3720 using iterator_category = std::bidirectional_iterator_tag;
3721
3723 using value_type = typename BasicJsonType::value_type;
3725 using difference_type = typename BasicJsonType::difference_type;
3727 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3728 typename BasicJsonType::const_pointer,
3729 typename BasicJsonType::pointer>::type;
3732 typename std::conditional<std::is_const<BasicJsonType>::value,
3733 typename BasicJsonType::const_reference,
3734 typename BasicJsonType::reference>::type;
3735
3737 iter_impl() = default;
3738
3745 explicit iter_impl(pointer object) noexcept : m_object(object)
3746 {
3747 assert(m_object != nullptr);
3748
3749 switch (m_object->m_type) {
3750 case value_t::object: {
3751 m_it.object_iterator = typename object_t::iterator();
3752 break;
3753 }
3754
3755 case value_t::array: {
3756 m_it.array_iterator = typename array_t::iterator();
3757 break;
3758 }
3759
3760 default: {
3762 break;
3763 }
3764 }
3765 }
3766
3781 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3782 : m_object(other.m_object), m_it(other.m_it) {}
3783
3790 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3791 {
3792 m_object = other.m_object;
3793 m_it = other.m_it;
3794 return *this;
3795 }
3796
3797 private:
3802 void set_begin() noexcept
3803 {
3804 assert(m_object != nullptr);
3805
3806 switch (m_object->m_type) {
3807 case value_t::object: {
3808 m_it.object_iterator = m_object->m_value.object->begin();
3809 break;
3810 }
3811
3812 case value_t::array: {
3813 m_it.array_iterator = m_object->m_value.array->begin();
3814 break;
3815 }
3816
3817 case value_t::null: {
3818 // set to end so begin()==end() is true: null is empty
3820 break;
3821 }
3822
3823 default: {
3825 break;
3826 }
3827 }
3828 }
3829
3834 void set_end() noexcept
3835 {
3836 assert(m_object != nullptr);
3837
3838 switch (m_object->m_type) {
3839 case value_t::object: {
3840 m_it.object_iterator = m_object->m_value.object->end();
3841 break;
3842 }
3843
3844 case value_t::array: {
3845 m_it.array_iterator = m_object->m_value.array->end();
3846 break;
3847 }
3848
3849 default: {
3851 break;
3852 }
3853 }
3854 }
3855
3856 public:
3862 {
3863 assert(m_object != nullptr);
3864
3865 switch (m_object->m_type) {
3866 case value_t::object: {
3867 assert(m_it.object_iterator != m_object->m_value.object->end());
3868 return m_it.object_iterator->second;
3869 }
3870
3871 case value_t::array: {
3872 assert(m_it.array_iterator != m_object->m_value.array->end());
3873 return *m_it.array_iterator;
3874 }
3875
3876 case value_t::null:
3877 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3878
3879 default: {
3881 return *m_object;
3882 }
3883
3884 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3885 }
3886 }
3887 }
3888
3894 {
3895 assert(m_object != nullptr);
3896
3897 switch (m_object->m_type) {
3898 case value_t::object: {
3899 assert(m_it.object_iterator != m_object->m_value.object->end());
3900 return &(m_it.object_iterator->second);
3901 }
3902
3903 case value_t::array: {
3904 assert(m_it.array_iterator != m_object->m_value.array->end());
3905 return &*m_it.array_iterator;
3906 }
3907
3908 default: {
3910 return m_object;
3911 }
3912
3913 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3914 }
3915 }
3916 }
3917
3923 {
3924 auto result = *this;
3925 ++(*this);
3926 return result;
3927 }
3928
3934 {
3935 assert(m_object != nullptr);
3936
3937 switch (m_object->m_type) {
3938 case value_t::object: {
3939 std::advance(m_it.object_iterator, 1);
3940 break;
3941 }
3942
3943 case value_t::array: {
3944 std::advance(m_it.array_iterator, 1);
3945 break;
3946 }
3947
3948 default: {
3949 ++m_it.primitive_iterator;
3950 break;
3951 }
3952 }
3953
3954 return *this;
3955 }
3956
3962 {
3963 auto result = *this;
3964 --(*this);
3965 return result;
3966 }
3967
3973 {
3974 assert(m_object != nullptr);
3975
3976 switch (m_object->m_type) {
3977 case value_t::object: {
3978 std::advance(m_it.object_iterator, -1);
3979 break;
3980 }
3981
3982 case value_t::array: {
3983 std::advance(m_it.array_iterator, -1);
3984 break;
3985 }
3986
3987 default: {
3988 --m_it.primitive_iterator;
3989 break;
3990 }
3991 }
3992
3993 return *this;
3994 }
3995
4000 bool operator==(const iter_impl& other) const
4001 {
4002 // if objects are not the same, the comparison is undefined
4003 if (JSON_UNLIKELY(m_object != other.m_object)) {
4004 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4005 }
4006
4007 assert(m_object != nullptr);
4008
4009 switch (m_object->m_type) {
4010 case value_t::object:
4011 return (m_it.object_iterator == other.m_it.object_iterator);
4012
4013 case value_t::array:
4014 return (m_it.array_iterator == other.m_it.array_iterator);
4015
4016 default:
4017 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
4018 }
4019 }
4020
4025 bool operator!=(const iter_impl& other) const
4026 {
4027 return not operator==(other);
4028 }
4029
4034 bool operator<(const iter_impl& other) const
4035 {
4036 // if objects are not the same, the comparison is undefined
4037 if (JSON_UNLIKELY(m_object != other.m_object)) {
4038 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4039 }
4040
4041 assert(m_object != nullptr);
4042
4043 switch (m_object->m_type) {
4044 case value_t::object:
4045 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
4046
4047 case value_t::array:
4048 return (m_it.array_iterator < other.m_it.array_iterator);
4049
4050 default:
4051 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4052 }
4053 }
4054
4059 bool operator<=(const iter_impl& other) const
4060 {
4061 return not other.operator<(*this);
4062 }
4063
4068 bool operator>(const iter_impl& other) const
4069 {
4070 return not operator<=(other);
4071 }
4072
4077 bool operator>=(const iter_impl& other) const
4078 {
4079 return not operator<(other);
4080 }
4081
4087 {
4088 assert(m_object != nullptr);
4089
4090 switch (m_object->m_type) {
4091 case value_t::object:
4092 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4093
4094 case value_t::array: {
4095 std::advance(m_it.array_iterator, i);
4096 break;
4097 }
4098
4099 default: {
4100 m_it.primitive_iterator += i;
4101 break;
4102 }
4103 }
4104
4105 return *this;
4106 }
4107
4113 {
4114 return operator+=(-i);
4115 }
4116
4122 {
4123 auto result = *this;
4124 result += i;
4125 return result;
4126 }
4127
4133 {
4134 auto result = it;
4135 result += i;
4136 return result;
4137 }
4138
4144 {
4145 auto result = *this;
4146 result -= i;
4147 return result;
4148 }
4149
4155 {
4156 assert(m_object != nullptr);
4157
4158 switch (m_object->m_type) {
4159 case value_t::object:
4160 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4161
4162 case value_t::array:
4163 return m_it.array_iterator - other.m_it.array_iterator;
4164
4165 default:
4166 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4167 }
4168 }
4169
4175 {
4176 assert(m_object != nullptr);
4177
4178 switch (m_object->m_type) {
4179 case value_t::object:
4180 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4181
4182 case value_t::array:
4183 return *std::next(m_it.array_iterator, n);
4184
4185 case value_t::null:
4186 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4187
4188 default: {
4189 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
4190 return *m_object;
4191 }
4192
4193 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4194 }
4195 }
4196 }
4197
4202 typename object_t::key_type key() const
4203 {
4204 assert(m_object != nullptr);
4205
4206 if (JSON_LIKELY(m_object->is_object())) {
4207 return m_it.object_iterator->first;
4208 }
4209
4210 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4211 }
4212
4218 {
4219 return operator*();
4220 }
4221
4222 private:
4224 pointer m_object = nullptr;
4227};
4228} // namespace detail
4229} // namespace nlohmann
4230
4231// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4232
4233#include <cstddef> // size_t
4234#include <string> // string, to_string
4235
4236// #include <nlohmann/detail/value_t.hpp>
4237
4238namespace nlohmann
4239{
4240namespace detail
4241{
4243template <typename IteratorType>
4245{
4246 private:
4248 class iteration_proxy_internal
4249 {
4250 private:
4252 IteratorType anchor;
4254 std::size_t array_index = 0;
4255
4256 public:
4257 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4258
4260 iteration_proxy_internal& operator*()
4261 {
4262 return *this;
4263 }
4264
4266 iteration_proxy_internal& operator++()
4267 {
4268 ++anchor;
4269 ++array_index;
4270
4271 return *this;
4272 }
4273
4275 bool operator!=(const iteration_proxy_internal& o) const noexcept
4276 {
4277 return anchor != o.anchor;
4278 }
4279
4281 std::string key() const
4282 {
4283 assert(anchor.m_object != nullptr);
4284
4285 switch (anchor.m_object->type()) {
4286 // use integer array index as key
4287 case value_t::array:
4288 return std::to_string(array_index);
4289
4290 // use key from the object
4291 case value_t::object:
4292 return anchor.key();
4293
4294 // use an empty key for all primitive types
4295 default:
4296 return "";
4297 }
4298 }
4299
4301 typename IteratorType::reference value() const
4302 {
4303 return anchor.value();
4304 }
4305 };
4306
4308 typename IteratorType::reference container;
4309
4310 public:
4312 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4313 : container(cont) {}
4314
4316 iteration_proxy_internal begin() noexcept
4317 {
4318 return iteration_proxy_internal(container.begin());
4319 }
4320
4322 iteration_proxy_internal end() noexcept
4323 {
4324 return iteration_proxy_internal(container.end());
4325 }
4326};
4327} // namespace detail
4328} // namespace nlohmann
4329
4330// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
4331
4332#include <cstddef> // ptrdiff_t
4333#include <iterator> // reverse_iterator
4334#include <utility> // declval
4335
4336namespace nlohmann
4337{
4338namespace detail
4339{
4341// reverse_iterator //
4343
4362template <typename Base>
4363class json_reverse_iterator : public std::reverse_iterator<Base>
4364{
4365 public:
4366 using difference_type = std::ptrdiff_t;
4368 using base_iterator = std::reverse_iterator<Base>;
4370 using reference = typename Base::reference;
4371
4373 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
4374 : base_iterator(it) {}
4375
4378
4381 {
4382 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4383 }
4384
4387 {
4388 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4389 }
4390
4393 {
4394 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4395 }
4396
4399 {
4400 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4401 }
4402
4405 {
4406 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4407 }
4408
4411 {
4412 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4413 }
4414
4417 {
4418 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4419 }
4420
4423 {
4424 return base_iterator(*this) - base_iterator(other);
4425 }
4426
4429 {
4430 return *(this->operator+(n));
4431 }
4432
4434 auto key() const -> decltype(std::declval<Base>().key())
4435 {
4436 auto it = --this->base();
4437 return it.key();
4438 }
4439
4442 {
4443 auto it = --this->base();
4444 return it.operator*();
4445 }
4446};
4447} // namespace detail
4448} // namespace nlohmann
4449
4450// #include <nlohmann/detail/output/output_adapters.hpp>
4451
4452#include <algorithm> // copy
4453#include <cstddef> // size_t
4454#include <ios> // streamsize
4455#include <iterator> // back_inserter
4456#include <memory> // shared_ptr, make_shared
4457#include <ostream> // basic_ostream
4458#include <string> // basic_string
4459#include <vector> // vector
4460
4461namespace nlohmann
4462{
4463namespace detail
4464{
4466template <typename CharType>
4468 virtual void write_character(CharType c) = 0;
4469 virtual void write_characters(const CharType* s, std::size_t length) = 0;
4470 virtual ~output_adapter_protocol() = default;
4471};
4472
4474template <typename CharType>
4475using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4476
4478template <typename CharType>
4480{
4481 public:
4482 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4483
4484 void write_character(CharType c) override
4485 {
4486 v.push_back(c);
4487 }
4488
4489 void write_characters(const CharType* s, std::size_t length) override
4490 {
4491 std::copy(s, s + length, std::back_inserter(v));
4492 }
4493
4494 private:
4495 std::vector<CharType>& v;
4496};
4497
4499template <typename CharType>
4501{
4502 public:
4503 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4504
4505 void write_character(CharType c) override
4506 {
4507 stream.put(c);
4508 }
4509
4510 void write_characters(const CharType* s, std::size_t length) override
4511 {
4512 stream.write(s, static_cast<std::streamsize>(length));
4513 }
4514
4515 private:
4516 std::basic_ostream<CharType>& stream;
4517};
4518
4520template <typename CharType, typename StringType = std::basic_string<CharType>>
4522{
4523 public:
4524 explicit output_string_adapter(StringType& s) : str(s) {}
4525
4526 void write_character(CharType c) override
4527 {
4528 str.push_back(c);
4529 }
4530
4531 void write_characters(const CharType* s, std::size_t length) override
4532 {
4533 str.append(s, length);
4534 }
4535
4536 private:
4537 StringType& str;
4538};
4539
4540template <typename CharType, typename StringType = std::basic_string<CharType>>
4542{
4543 public:
4544 output_adapter(std::vector<CharType>& vec)
4545 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4546
4547 output_adapter(std::basic_ostream<CharType>& s)
4548 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4549
4550 output_adapter(StringType& s)
4551 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
4552
4554 {
4555 return oa;
4556 }
4557
4558 private:
4559 output_adapter_t<CharType> oa = nullptr;
4560};
4561} // namespace detail
4562} // namespace nlohmann
4563
4564// #include <nlohmann/detail/input/binary_reader.hpp>
4565
4566#include <algorithm> // generate_n
4567#include <array> // array
4568#include <cassert> // assert
4569#include <cmath> // ldexp
4570#include <cstddef> // size_t
4571#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4572#include <cstring> // memcpy
4573#include <iomanip> // setw, setfill
4574#include <ios> // hex
4575#include <iterator> // back_inserter
4576#include <limits> // numeric_limits
4577#include <sstream> // stringstream
4578#include <string> // char_traits, string
4579#include <utility> // make_pair, move
4580
4581// #include <nlohmann/detail/input/input_adapters.hpp>
4582
4583// #include <nlohmann/detail/exceptions.hpp>
4584
4585// #include <nlohmann/detail/macro_scope.hpp>
4586
4587// #include <nlohmann/detail/value_t.hpp>
4588
4589namespace nlohmann
4590{
4591namespace detail
4592{
4594// binary reader //
4596
4600template <typename BasicJsonType>
4601class binary_reader
4602{
4603 using number_integer_t = typename BasicJsonType::number_integer_t;
4604 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4605 using string_t = typename BasicJsonType::string_t;
4606
4607 public:
4613 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4614 {
4615 assert(ia);
4616 }
4617
4628 BasicJsonType parse_cbor(const bool strict)
4629 {
4630 const auto res = parse_cbor_internal();
4631 if (strict) {
4632 get();
4633 expect_eof();
4634 }
4635 return res;
4636 }
4637
4648 BasicJsonType parse_msgpack(const bool strict)
4649 {
4650 const auto res = parse_msgpack_internal();
4651 if (strict) {
4652 get();
4653 expect_eof();
4654 }
4655 return res;
4656 }
4657
4668 BasicJsonType parse_ubjson(const bool strict)
4669 {
4670 const auto res = parse_ubjson_internal();
4671 if (strict) {
4672 get_ignore_noop();
4673 expect_eof();
4674 }
4675 return res;
4676 }
4677
4685 static constexpr bool little_endianess(int num = 1) noexcept
4686 {
4687 return (*reinterpret_cast<char*>(&num) == 1);
4688 }
4689
4690 private:
4696 BasicJsonType parse_cbor_internal(const bool get_char = true)
4697 {
4698 switch (get_char ? get() : current) {
4699 // EOF
4700 case std::char_traits<char>::eof():
4701 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4702
4703 // Integer 0x00..0x17 (0..23)
4704 case 0x00:
4705 case 0x01:
4706 case 0x02:
4707 case 0x03:
4708 case 0x04:
4709 case 0x05:
4710 case 0x06:
4711 case 0x07:
4712 case 0x08:
4713 case 0x09:
4714 case 0x0A:
4715 case 0x0B:
4716 case 0x0C:
4717 case 0x0D:
4718 case 0x0E:
4719 case 0x0F:
4720 case 0x10:
4721 case 0x11:
4722 case 0x12:
4723 case 0x13:
4724 case 0x14:
4725 case 0x15:
4726 case 0x16:
4727 case 0x17:
4728 return static_cast<number_unsigned_t>(current);
4729
4730 case 0x18: // Unsigned integer (one-byte uint8_t follows)
4731 return get_number<uint8_t>();
4732
4733 case 0x19: // Unsigned integer (two-byte uint16_t follows)
4734 return get_number<uint16_t>();
4735
4736 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
4737 return get_number<uint32_t>();
4738
4739 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
4740 return get_number<uint64_t>();
4741
4742 // Negative integer -1-0x00..-1-0x17 (-1..-24)
4743 case 0x20:
4744 case 0x21:
4745 case 0x22:
4746 case 0x23:
4747 case 0x24:
4748 case 0x25:
4749 case 0x26:
4750 case 0x27:
4751 case 0x28:
4752 case 0x29:
4753 case 0x2A:
4754 case 0x2B:
4755 case 0x2C:
4756 case 0x2D:
4757 case 0x2E:
4758 case 0x2F:
4759 case 0x30:
4760 case 0x31:
4761 case 0x32:
4762 case 0x33:
4763 case 0x34:
4764 case 0x35:
4765 case 0x36:
4766 case 0x37:
4767 return static_cast<int8_t>(0x20 - 1 - current);
4768
4769 case 0x38: // Negative integer (one-byte uint8_t follows)
4770 {
4771 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4772 }
4773
4774 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
4775 {
4776 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4777 }
4778
4779 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
4780 {
4781 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4782 }
4783
4784 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
4785 {
4786 return static_cast<number_integer_t>(-1) -
4787 static_cast<number_integer_t>(get_number<uint64_t>());
4788 }
4789
4790 // UTF-8 string (0x00..0x17 bytes follow)
4791 case 0x60:
4792 case 0x61:
4793 case 0x62:
4794 case 0x63:
4795 case 0x64:
4796 case 0x65:
4797 case 0x66:
4798 case 0x67:
4799 case 0x68:
4800 case 0x69:
4801 case 0x6A:
4802 case 0x6B:
4803 case 0x6C:
4804 case 0x6D:
4805 case 0x6E:
4806 case 0x6F:
4807 case 0x70:
4808 case 0x71:
4809 case 0x72:
4810 case 0x73:
4811 case 0x74:
4812 case 0x75:
4813 case 0x76:
4814 case 0x77:
4815 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4816 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4817 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4818 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4819 case 0x7F: // UTF-8 string (indefinite length)
4820 {
4821 return get_cbor_string();
4822 }
4823
4824 // array (0x00..0x17 data items follow)
4825 case 0x80:
4826 case 0x81:
4827 case 0x82:
4828 case 0x83:
4829 case 0x84:
4830 case 0x85:
4831 case 0x86:
4832 case 0x87:
4833 case 0x88:
4834 case 0x89:
4835 case 0x8A:
4836 case 0x8B:
4837 case 0x8C:
4838 case 0x8D:
4839 case 0x8E:
4840 case 0x8F:
4841 case 0x90:
4842 case 0x91:
4843 case 0x92:
4844 case 0x93:
4845 case 0x94:
4846 case 0x95:
4847 case 0x96:
4848 case 0x97: {
4849 return get_cbor_array(current & 0x1F);
4850 }
4851
4852 case 0x98: // array (one-byte uint8_t for n follows)
4853 {
4854 return get_cbor_array(get_number<uint8_t>());
4855 }
4856
4857 case 0x99: // array (two-byte uint16_t for n follow)
4858 {
4859 return get_cbor_array(get_number<uint16_t>());
4860 }
4861
4862 case 0x9A: // array (four-byte uint32_t for n follow)
4863 {
4864 return get_cbor_array(get_number<uint32_t>());
4865 }
4866
4867 case 0x9B: // array (eight-byte uint64_t for n follow)
4868 {
4869 return get_cbor_array(get_number<uint64_t>());
4870 }
4871
4872 case 0x9F: // array (indefinite length)
4873 {
4874 BasicJsonType result = value_t::array;
4875 while (get() != 0xFF) {
4876 result.push_back(parse_cbor_internal(false));
4877 }
4878 return result;
4879 }
4880
4881 // map (0x00..0x17 pairs of data items follow)
4882 case 0xA0:
4883 case 0xA1:
4884 case 0xA2:
4885 case 0xA3:
4886 case 0xA4:
4887 case 0xA5:
4888 case 0xA6:
4889 case 0xA7:
4890 case 0xA8:
4891 case 0xA9:
4892 case 0xAA:
4893 case 0xAB:
4894 case 0xAC:
4895 case 0xAD:
4896 case 0xAE:
4897 case 0xAF:
4898 case 0xB0:
4899 case 0xB1:
4900 case 0xB2:
4901 case 0xB3:
4902 case 0xB4:
4903 case 0xB5:
4904 case 0xB6:
4905 case 0xB7: {
4906 return get_cbor_object(current & 0x1F);
4907 }
4908
4909 case 0xB8: // map (one-byte uint8_t for n follows)
4910 {
4911 return get_cbor_object(get_number<uint8_t>());
4912 }
4913
4914 case 0xB9: // map (two-byte uint16_t for n follow)
4915 {
4916 return get_cbor_object(get_number<uint16_t>());
4917 }
4918
4919 case 0xBA: // map (four-byte uint32_t for n follow)
4920 {
4921 return get_cbor_object(get_number<uint32_t>());
4922 }
4923
4924 case 0xBB: // map (eight-byte uint64_t for n follow)
4925 {
4926 return get_cbor_object(get_number<uint64_t>());
4927 }
4928
4929 case 0xBF: // map (indefinite length)
4930 {
4931 BasicJsonType result = value_t::object;
4932 while (get() != 0xFF) {
4933 auto key = get_cbor_string();
4934 result[key] = parse_cbor_internal();
4935 }
4936 return result;
4937 }
4938
4939 case 0xF4: // false
4940 {
4941 return false;
4942 }
4943
4944 case 0xF5: // true
4945 {
4946 return true;
4947 }
4948
4949 case 0xF6: // null
4950 {
4951 return value_t::null;
4952 }
4953
4954 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
4955 {
4956 const int byte1 = get();
4957 unexpect_eof();
4958 const int byte2 = get();
4959 unexpect_eof();
4960
4961 // code from RFC 7049, Appendix D, Figure 3:
4962 // As half-precision floating-point numbers were only added
4963 // to IEEE 754 in 2008, today's programming platforms often
4964 // still only have limited support for them. It is very
4965 // easy to include at least decoding support for them even
4966 // without such support. An example of a small decoder for
4967 // half-precision floating-point numbers in the C language
4968 // is shown in Fig. 3.
4969 const int half = (byte1 << 8) + byte2;
4970 const int exp = (half >> 10) & 0x1F;
4971 const int mant = half & 0x3FF;
4972 double val;
4973 if (exp == 0) {
4974 val = std::ldexp(mant, -24);
4975 } else if (exp != 31) {
4976 val = std::ldexp(mant + 1024, exp - 25);
4977 } else {
4978 val = (mant == 0) ? std::numeric_limits<double>::infinity()
4979 : std::numeric_limits<double>::quiet_NaN();
4980 }
4981 return (half & 0x8000) != 0 ? -val : val;
4982 }
4983
4984 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
4985 {
4986 return get_number<float>();
4987 }
4988
4989 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
4990 {
4991 return get_number<double>();
4992 }
4993
4994 default: // anything else (0xFF is handled inside the other types)
4995 {
4996 std::stringstream ss;
4997 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
4998 JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
4999 }
5000 }
5001 }
5002
5003 BasicJsonType parse_msgpack_internal()
5004 {
5005 switch (get()) {
5006 // EOF
5007 case std::char_traits<char>::eof():
5008 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5009
5010 // positive fixint
5011 case 0x00:
5012 case 0x01:
5013 case 0x02:
5014 case 0x03:
5015 case 0x04:
5016 case 0x05:
5017 case 0x06:
5018 case 0x07:
5019 case 0x08:
5020 case 0x09:
5021 case 0x0A:
5022 case 0x0B:
5023 case 0x0C:
5024 case 0x0D:
5025 case 0x0E:
5026 case 0x0F:
5027 case 0x10:
5028 case 0x11:
5029 case 0x12:
5030 case 0x13:
5031 case 0x14:
5032 case 0x15:
5033 case 0x16:
5034 case 0x17:
5035 case 0x18:
5036 case 0x19:
5037 case 0x1A:
5038 case 0x1B:
5039 case 0x1C:
5040 case 0x1D:
5041 case 0x1E:
5042 case 0x1F:
5043 case 0x20:
5044 case 0x21:
5045 case 0x22:
5046 case 0x23:
5047 case 0x24:
5048 case 0x25:
5049 case 0x26:
5050 case 0x27:
5051 case 0x28:
5052 case 0x29:
5053 case 0x2A:
5054 case 0x2B:
5055 case 0x2C:
5056 case 0x2D:
5057 case 0x2E:
5058 case 0x2F:
5059 case 0x30:
5060 case 0x31:
5061 case 0x32:
5062 case 0x33:
5063 case 0x34:
5064 case 0x35:
5065 case 0x36:
5066 case 0x37:
5067 case 0x38:
5068 case 0x39:
5069 case 0x3A:
5070 case 0x3B:
5071 case 0x3C:
5072 case 0x3D:
5073 case 0x3E:
5074 case 0x3F:
5075 case 0x40:
5076 case 0x41:
5077 case 0x42:
5078 case 0x43:
5079 case 0x44:
5080 case 0x45:
5081 case 0x46:
5082 case 0x47:
5083 case 0x48:
5084 case 0x49:
5085 case 0x4A:
5086 case 0x4B:
5087 case 0x4C:
5088 case 0x4D:
5089 case 0x4E:
5090 case 0x4F:
5091 case 0x50:
5092 case 0x51:
5093 case 0x52:
5094 case 0x53:
5095 case 0x54:
5096 case 0x55:
5097 case 0x56:
5098 case 0x57:
5099 case 0x58:
5100 case 0x59:
5101 case 0x5A:
5102 case 0x5B:
5103 case 0x5C:
5104 case 0x5D:
5105 case 0x5E:
5106 case 0x5F:
5107 case 0x60:
5108 case 0x61:
5109 case 0x62:
5110 case 0x63:
5111 case 0x64:
5112 case 0x65:
5113 case 0x66:
5114 case 0x67:
5115 case 0x68:
5116 case 0x69:
5117 case 0x6A:
5118 case 0x6B:
5119 case 0x6C:
5120 case 0x6D:
5121 case 0x6E:
5122 case 0x6F:
5123 case 0x70:
5124 case 0x71:
5125 case 0x72:
5126 case 0x73:
5127 case 0x74:
5128 case 0x75:
5129 case 0x76:
5130 case 0x77:
5131 case 0x78:
5132 case 0x79:
5133 case 0x7A:
5134 case 0x7B:
5135 case 0x7C:
5136 case 0x7D:
5137 case 0x7E:
5138 case 0x7F:
5139 return static_cast<number_unsigned_t>(current);
5140
5141 // fixmap
5142 case 0x80:
5143 case 0x81:
5144 case 0x82:
5145 case 0x83:
5146 case 0x84:
5147 case 0x85:
5148 case 0x86:
5149 case 0x87:
5150 case 0x88:
5151 case 0x89:
5152 case 0x8A:
5153 case 0x8B:
5154 case 0x8C:
5155 case 0x8D:
5156 case 0x8E:
5157 case 0x8F: {
5158 return get_msgpack_object(current & 0x0F);
5159 }
5160
5161 // fixarray
5162 case 0x90:
5163 case 0x91:
5164 case 0x92:
5165 case 0x93:
5166 case 0x94:
5167 case 0x95:
5168 case 0x96:
5169 case 0x97:
5170 case 0x98:
5171 case 0x99:
5172 case 0x9A:
5173 case 0x9B:
5174 case 0x9C:
5175 case 0x9D:
5176 case 0x9E:
5177 case 0x9F: {
5178 return get_msgpack_array(current & 0x0F);
5179 }
5180
5181 // fixstr
5182 case 0xA0:
5183 case 0xA1:
5184 case 0xA2:
5185 case 0xA3:
5186 case 0xA4:
5187 case 0xA5:
5188 case 0xA6:
5189 case 0xA7:
5190 case 0xA8:
5191 case 0xA9:
5192 case 0xAA:
5193 case 0xAB:
5194 case 0xAC:
5195 case 0xAD:
5196 case 0xAE:
5197 case 0xAF:
5198 case 0xB0:
5199 case 0xB1:
5200 case 0xB2:
5201 case 0xB3:
5202 case 0xB4:
5203 case 0xB5:
5204 case 0xB6:
5205 case 0xB7:
5206 case 0xB8:
5207 case 0xB9:
5208 case 0xBA:
5209 case 0xBB:
5210 case 0xBC:
5211 case 0xBD:
5212 case 0xBE:
5213 case 0xBF:
5214 return get_msgpack_string();
5215
5216 case 0xC0: // nil
5217 return value_t::null;
5218
5219 case 0xC2: // false
5220 return false;
5221
5222 case 0xC3: // true
5223 return true;
5224
5225 case 0xCA: // float 32
5226 return get_number<float>();
5227
5228 case 0xCB: // float 64
5229 return get_number<double>();
5230
5231 case 0xCC: // uint 8
5232 return get_number<uint8_t>();
5233
5234 case 0xCD: // uint 16
5235 return get_number<uint16_t>();
5236
5237 case 0xCE: // uint 32
5238 return get_number<uint32_t>();
5239
5240 case 0xCF: // uint 64
5241 return get_number<uint64_t>();
5242
5243 case 0xD0: // int 8
5244 return get_number<int8_t>();
5245
5246 case 0xD1: // int 16
5247 return get_number<int16_t>();
5248
5249 case 0xD2: // int 32
5250 return get_number<int32_t>();
5251
5252 case 0xD3: // int 64
5253 return get_number<int64_t>();
5254
5255 case 0xD9: // str 8
5256 case 0xDA: // str 16
5257 case 0xDB: // str 32
5258 return get_msgpack_string();
5259
5260 case 0xDC: // array 16
5261 {
5262 return get_msgpack_array(get_number<uint16_t>());
5263 }
5264
5265 case 0xDD: // array 32
5266 {
5267 return get_msgpack_array(get_number<uint32_t>());
5268 }
5269
5270 case 0xDE: // map 16
5271 {
5272 return get_msgpack_object(get_number<uint16_t>());
5273 }
5274
5275 case 0xDF: // map 32
5276 {
5277 return get_msgpack_object(get_number<uint32_t>());
5278 }
5279
5280 // positive fixint
5281 case 0xE0:
5282 case 0xE1:
5283 case 0xE2:
5284 case 0xE3:
5285 case 0xE4:
5286 case 0xE5:
5287 case 0xE6:
5288 case 0xE7:
5289 case 0xE8:
5290 case 0xE9:
5291 case 0xEA:
5292 case 0xEB:
5293 case 0xEC:
5294 case 0xED:
5295 case 0xEE:
5296 case 0xEF:
5297 case 0xF0:
5298 case 0xF1:
5299 case 0xF2:
5300 case 0xF3:
5301 case 0xF4:
5302 case 0xF5:
5303 case 0xF6:
5304 case 0xF7:
5305 case 0xF8:
5306 case 0xF9:
5307 case 0xFA:
5308 case 0xFB:
5309 case 0xFC:
5310 case 0xFD:
5311 case 0xFE:
5312 case 0xFF:
5313 return static_cast<int8_t>(current);
5314
5315 default: // anything else
5316 {
5317 std::stringstream ss;
5318 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5319 JSON_THROW(parse_error::create(112, chars_read,
5320 "error reading MessagePack; last byte: 0x" + ss.str()));
5321 }
5322 }
5323 }
5324
5330 BasicJsonType parse_ubjson_internal(const bool get_char = true)
5331 {
5332 return get_ubjson_value(get_char ? get_ignore_noop() : current);
5333 }
5334
5344 int get()
5345 {
5346 ++chars_read;
5347 return (current = ia->get_character());
5348 }
5349
5353 int get_ignore_noop()
5354 {
5355 do {
5356 get();
5357 } while (current == 'N');
5358
5359 return current;
5360 }
5361
5362 /*
5363 @brief read a number from the input
5364
5365 @tparam NumberType the type of the number
5366
5367 @return number of type @a NumberType
5368
5369 @note This function needs to respect the system's endianess, because
5370 bytes in CBOR and MessagePack are stored in network order (big
5371 endian) and therefore need reordering on little endian systems.
5372
5373 @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5374 */
5375 template <typename NumberType>
5376 NumberType get_number()
5377 {
5378 // step 1: read input into array with system's byte order
5379 std::array<uint8_t, sizeof(NumberType)> vec;
5380 for (std::size_t i = 0; i < sizeof(NumberType); ++i) {
5381 get();
5382 unexpect_eof();
5383
5384 // reverse byte order prior to conversion if necessary
5385 if (is_little_endian) {
5386 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5387 } else {
5388 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5389 }
5390 }
5391
5392 // step 2: convert array into number of type T and return
5393 NumberType result;
5394 std::memcpy(&result, vec.data(), sizeof(NumberType));
5395 return result;
5396 }
5397
5411 template <typename NumberType>
5412 string_t get_string(const NumberType len)
5413 {
5414 string_t result;
5415 std::generate_n(std::back_inserter(result), len, [this]() {
5416 get();
5417 unexpect_eof();
5418 return static_cast<char>(current);
5419 });
5420 return result;
5421 }
5422
5435 string_t get_cbor_string()
5436 {
5437 unexpect_eof();
5438
5439 switch (current) {
5440 // UTF-8 string (0x00..0x17 bytes follow)
5441 case 0x60:
5442 case 0x61:
5443 case 0x62:
5444 case 0x63:
5445 case 0x64:
5446 case 0x65:
5447 case 0x66:
5448 case 0x67:
5449 case 0x68:
5450 case 0x69:
5451 case 0x6A:
5452 case 0x6B:
5453 case 0x6C:
5454 case 0x6D:
5455 case 0x6E:
5456 case 0x6F:
5457 case 0x70:
5458 case 0x71:
5459 case 0x72:
5460 case 0x73:
5461 case 0x74:
5462 case 0x75:
5463 case 0x76:
5464 case 0x77: {
5465 return get_string(current & 0x1F);
5466 }
5467
5468 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5469 {
5470 return get_string(get_number<uint8_t>());
5471 }
5472
5473 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5474 {
5475 return get_string(get_number<uint16_t>());
5476 }
5477
5478 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5479 {
5480 return get_string(get_number<uint32_t>());
5481 }
5482
5483 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5484 {
5485 return get_string(get_number<uint64_t>());
5486 }
5487
5488 case 0x7F: // UTF-8 string (indefinite length)
5489 {
5490 string_t result;
5491 while (get() != 0xFF) {
5492 result.append(get_cbor_string());
5493 }
5494 return result;
5495 }
5496
5497 default: {
5498 std::stringstream ss;
5499 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5500 JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
5501 }
5502 }
5503 }
5504
5505 template <typename NumberType>
5506 BasicJsonType get_cbor_array(const NumberType len)
5507 {
5508 BasicJsonType result = value_t::array;
5509 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
5510 return parse_cbor_internal();
5511 });
5512 return result;
5513 }
5514
5515 template <typename NumberType>
5516 BasicJsonType get_cbor_object(const NumberType len)
5517 {
5518 BasicJsonType result = value_t::object;
5519 std::generate_n(std::inserter(*result.m_value.object,
5520 result.m_value.object->end()),
5521 len, [this]() {
5522 get();
5523 auto key = get_cbor_string();
5524 auto val = parse_cbor_internal();
5525 return std::make_pair(std::move(key), std::move(val));
5526 });
5527 return result;
5528 }
5529
5541 string_t get_msgpack_string()
5542 {
5543 unexpect_eof();
5544
5545 switch (current) {
5546 // fixstr
5547 case 0xA0:
5548 case 0xA1:
5549 case 0xA2:
5550 case 0xA3:
5551 case 0xA4:
5552 case 0xA5:
5553 case 0xA6:
5554 case 0xA7:
5555 case 0xA8:
5556 case 0xA9:
5557 case 0xAA:
5558 case 0xAB:
5559 case 0xAC:
5560 case 0xAD:
5561 case 0xAE:
5562 case 0xAF:
5563 case 0xB0:
5564 case 0xB1:
5565 case 0xB2:
5566 case 0xB3:
5567 case 0xB4:
5568 case 0xB5:
5569 case 0xB6:
5570 case 0xB7:
5571 case 0xB8:
5572 case 0xB9:
5573 case 0xBA:
5574 case 0xBB:
5575 case 0xBC:
5576 case 0xBD:
5577 case 0xBE:
5578 case 0xBF: {
5579 return get_string(current & 0x1F);
5580 }
5581
5582 case 0xD9: // str 8
5583 {
5584 return get_string(get_number<uint8_t>());
5585 }
5586
5587 case 0xDA: // str 16
5588 {
5589 return get_string(get_number<uint16_t>());
5590 }
5591
5592 case 0xDB: // str 32
5593 {
5594 return get_string(get_number<uint32_t>());
5595 }
5596
5597 default: {
5598 std::stringstream ss;
5599 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5600 JSON_THROW(parse_error::create(113, chars_read,
5601 "expected a MessagePack string; last byte: 0x" + ss.str()));
5602 }
5603 }
5604 }
5605
5606 template <typename NumberType>
5607 BasicJsonType get_msgpack_array(const NumberType len)
5608 {
5609 BasicJsonType result = value_t::array;
5610 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
5611 return parse_msgpack_internal();
5612 });
5613 return result;
5614 }
5615
5616 template <typename NumberType>
5617 BasicJsonType get_msgpack_object(const NumberType len)
5618 {
5619 BasicJsonType result = value_t::object;
5620 std::generate_n(std::inserter(*result.m_value.object,
5621 result.m_value.object->end()),
5622 len, [this]() {
5623 get();
5624 auto key = get_msgpack_string();
5625 auto val = parse_msgpack_internal();
5626 return std::make_pair(std::move(key), std::move(val));
5627 });
5628 return result;
5629 }
5630
5647 string_t get_ubjson_string(const bool get_char = true)
5648 {
5649 if (get_char) {
5650 get(); // TODO: may we ignore N here?
5651 }
5652
5653 unexpect_eof();
5654
5655 switch (current) {
5656 case 'U':
5657 return get_string(get_number<uint8_t>());
5658 case 'i':
5659 return get_string(get_number<int8_t>());
5660 case 'I':
5661 return get_string(get_number<int16_t>());
5662 case 'l':
5663 return get_string(get_number<int32_t>());
5664 case 'L':
5665 return get_string(get_number<int64_t>());
5666 default:
5667 std::stringstream ss;
5668 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5669 JSON_THROW(parse_error::create(113, chars_read,
5670 "expected a UBJSON string; last byte: 0x" + ss.str()));
5671 }
5672 }
5673
5682 std::pair<std::size_t, int> get_ubjson_size_type()
5683 {
5684 std::size_t sz = string_t::npos;
5685 int tc = 0;
5686
5687 get_ignore_noop();
5688
5689 if (current == '$') {
5690 tc = get(); // must not ignore 'N', because 'N' maybe the type
5691 unexpect_eof();
5692
5693 get_ignore_noop();
5694 if (current != '#') {
5695 std::stringstream ss;
5696 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5697 JSON_THROW(parse_error::create(112, chars_read,
5698 "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
5699 }
5700 sz = parse_ubjson_internal();
5701 } else if (current == '#') {
5702 sz = parse_ubjson_internal();
5703 }
5704
5705 return std::make_pair(sz, tc);
5706 }
5707
5708 BasicJsonType get_ubjson_value(const int prefix)
5709 {
5710 switch (prefix) {
5711 case std::char_traits<char>::eof(): // EOF
5712 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5713
5714 case 'T': // true
5715 return true;
5716 case 'F': // false
5717 return false;
5718
5719 case 'Z': // null
5720 return nullptr;
5721
5722 case 'U':
5723 return get_number<uint8_t>();
5724 case 'i':
5725 return get_number<int8_t>();
5726 case 'I':
5727 return get_number<int16_t>();
5728 case 'l':
5729 return get_number<int32_t>();
5730 case 'L':
5731 return get_number<int64_t>();
5732 case 'd':
5733 return get_number<float>();
5734 case 'D':
5735 return get_number<double>();
5736
5737 case 'C': // char
5738 {
5739 get();
5740 unexpect_eof();
5741 if (JSON_UNLIKELY(current > 127)) {
5742 std::stringstream ss;
5743 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5744 JSON_THROW(parse_error::create(113, chars_read,
5745 "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
5746 }
5747 return string_t(1, static_cast<char>(current));
5748 }
5749
5750 case 'S': // string
5751 return get_ubjson_string();
5752
5753 case '[': // array
5754 return get_ubjson_array();
5755
5756 case '{': // object
5757 return get_ubjson_object();
5758
5759 default: // anything else
5760 std::stringstream ss;
5761 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5762 JSON_THROW(parse_error::create(112, chars_read,
5763 "error reading UBJSON; last byte: 0x" + ss.str()));
5764 }
5765 }
5766
5767 BasicJsonType get_ubjson_array()
5768 {
5769 BasicJsonType result = value_t::array;
5770 const auto size_and_type = get_ubjson_size_type();
5771
5772 if (size_and_type.first != string_t::npos) {
5773 if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5775 "excessive array size: " + std::to_string(size_and_type.first)));
5776 }
5777
5778 if (size_and_type.second != 0) {
5779 if (size_and_type.second != 'N') {
5780 std::generate_n(std::back_inserter(*result.m_value.array),
5781 size_and_type.first, [this, size_and_type]() {
5782 return get_ubjson_value(size_and_type.second);
5783 });
5784 }
5785 } else {
5786 std::generate_n(std::back_inserter(*result.m_value.array),
5787 size_and_type.first, [this]() {
5788 return parse_ubjson_internal();
5789 });
5790 }
5791 } else {
5792 while (current != ']') {
5793 result.push_back(parse_ubjson_internal(false));
5794 get_ignore_noop();
5795 }
5796 }
5797
5798 return result;
5799 }
5800
5801 BasicJsonType get_ubjson_object()
5802 {
5803 BasicJsonType result = value_t::object;
5804 const auto size_and_type = get_ubjson_size_type();
5805
5806 if (size_and_type.first != string_t::npos) {
5807 if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5809 "excessive object size: " + std::to_string(size_and_type.first)));
5810 }
5811
5812 if (size_and_type.second != 0) {
5813 std::generate_n(std::inserter(*result.m_value.object,
5814 result.m_value.object->end()),
5815 size_and_type.first, [this, size_and_type]() {
5816 auto key = get_ubjson_string();
5817 auto val = get_ubjson_value(size_and_type.second);
5818 return std::make_pair(std::move(key), std::move(val));
5819 });
5820 } else {
5821 std::generate_n(std::inserter(*result.m_value.object,
5822 result.m_value.object->end()),
5823 size_and_type.first, [this]() {
5824 auto key = get_ubjson_string();
5825 auto val = parse_ubjson_internal();
5826 return std::make_pair(std::move(key), std::move(val));
5827 });
5828 }
5829 } else {
5830 while (current != '}') {
5831 auto key = get_ubjson_string(false);
5832 result[std::move(key)] = parse_ubjson_internal();
5833 get_ignore_noop();
5834 }
5835 }
5836
5837 return result;
5838 }
5839
5844 void expect_eof() const
5845 {
5846 if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
5847 JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
5848 }
5849 }
5850
5855 void unexpect_eof() const
5856 {
5857 if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
5858 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5859 }
5860 }
5861
5862 private:
5864 input_adapter_t ia = nullptr;
5865
5867 int current = std::char_traits<char>::eof();
5868
5870 std::size_t chars_read = 0;
5871
5873 const bool is_little_endian = little_endianess();
5874};
5875} // namespace detail
5876} // namespace nlohmann
5877
5878// #include <nlohmann/detail/output/binary_writer.hpp>
5879
5880#include <algorithm> // reverse
5881#include <array> // array
5882#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5883#include <cstring> // memcpy
5884#include <limits> // numeric_limits
5885
5886// #include <nlohmann/detail/input/binary_reader.hpp>
5887
5888// #include <nlohmann/detail/output/output_adapters.hpp>
5889
5890namespace nlohmann
5891{
5892namespace detail
5893{
5895// binary writer //
5897
5901template <typename BasicJsonType, typename CharType>
5902class binary_writer
5903{
5904 public:
5910 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5911 {
5912 assert(oa);
5913 }
5914
5918 void write_cbor(const BasicJsonType& j)
5919 {
5920 switch (j.type()) {
5921 case value_t::null: {
5922 oa->write_character(static_cast<CharType>(0xF6));
5923 break;
5924 }
5925
5926 case value_t::boolean: {
5927 oa->write_character(j.m_value.boolean
5928 ? static_cast<CharType>(0xF5)
5929 : static_cast<CharType>(0xF4));
5930 break;
5931 }
5932
5933 case value_t::number_integer: {
5934 if (j.m_value.number_integer >= 0) {
5935 // CBOR does not differentiate between positive signed
5936 // integers and unsigned integers. Therefore, we used the
5937 // code from the value_t::number_unsigned case here.
5938 if (j.m_value.number_integer <= 0x17) {
5939 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5940 } else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
5941 oa->write_character(static_cast<CharType>(0x18));
5942 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5943 } else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)()) {
5944 oa->write_character(static_cast<CharType>(0x19));
5945 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5946 } else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)()) {
5947 oa->write_character(static_cast<CharType>(0x1A));
5948 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5949 } else {
5950 oa->write_character(static_cast<CharType>(0x1B));
5951 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5952 }
5953 } else {
5954 // The conversions below encode the sign in the first
5955 // byte, and the value is converted to a positive number.
5956 const auto positive_number = -1 - j.m_value.number_integer;
5957 if (j.m_value.number_integer >= -24) {
5958 write_number(static_cast<uint8_t>(0x20 + positive_number));
5959 } else if (positive_number <= (std::numeric_limits<uint8_t>::max)()) {
5960 oa->write_character(static_cast<CharType>(0x38));
5961 write_number(static_cast<uint8_t>(positive_number));
5962 } else if (positive_number <= (std::numeric_limits<uint16_t>::max)()) {
5963 oa->write_character(static_cast<CharType>(0x39));
5964 write_number(static_cast<uint16_t>(positive_number));
5965 } else if (positive_number <= (std::numeric_limits<uint32_t>::max)()) {
5966 oa->write_character(static_cast<CharType>(0x3A));
5967 write_number(static_cast<uint32_t>(positive_number));
5968 } else {
5969 oa->write_character(static_cast<CharType>(0x3B));
5970 write_number(static_cast<uint64_t>(positive_number));
5971 }
5972 }
5973 break;
5974 }
5975
5976 case value_t::number_unsigned: {
5977 if (j.m_value.number_unsigned <= 0x17) {
5978 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5979 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
5980 oa->write_character(static_cast<CharType>(0x18));
5981 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5982 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
5983 oa->write_character(static_cast<CharType>(0x19));
5984 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
5985 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
5986 oa->write_character(static_cast<CharType>(0x1A));
5987 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
5988 } else {
5989 oa->write_character(static_cast<CharType>(0x1B));
5990 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
5991 }
5992 break;
5993 }
5994
5995 case value_t::number_float: // Double-Precision Float
5996 {
5997 oa->write_character(static_cast<CharType>(0xFB));
5998 write_number(j.m_value.number_float);
5999 break;
6000 }
6001
6002 case value_t::string: {
6003 // step 1: write control byte and the string length
6004 const auto N = j.m_value.string->size();
6005 if (N <= 0x17) {
6006 write_number(static_cast<uint8_t>(0x60 + N));
6007 } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6008 oa->write_character(static_cast<CharType>(0x78));
6009 write_number(static_cast<uint8_t>(N));
6010 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6011 oa->write_character(static_cast<CharType>(0x79));
6012 write_number(static_cast<uint16_t>(N));
6013 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6014 oa->write_character(static_cast<CharType>(0x7A));
6015 write_number(static_cast<uint32_t>(N));
6016 }
6017 // LCOV_EXCL_START
6018 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6019 oa->write_character(static_cast<CharType>(0x7B));
6020 write_number(static_cast<uint64_t>(N));
6021 }
6022 // LCOV_EXCL_STOP
6023
6024 // step 2: write the string
6025 oa->write_characters(
6026 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6027 j.m_value.string->size());
6028 break;
6029 }
6030
6031 case value_t::array: {
6032 // step 1: write control byte and the array size
6033 const auto N = j.m_value.array->size();
6034 if (N <= 0x17) {
6035 write_number(static_cast<uint8_t>(0x80 + N));
6036 } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6037 oa->write_character(static_cast<CharType>(0x98));
6038 write_number(static_cast<uint8_t>(N));
6039 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6040 oa->write_character(static_cast<CharType>(0x99));
6041 write_number(static_cast<uint16_t>(N));
6042 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6043 oa->write_character(static_cast<CharType>(0x9A));
6044 write_number(static_cast<uint32_t>(N));
6045 }
6046 // LCOV_EXCL_START
6047 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6048 oa->write_character(static_cast<CharType>(0x9B));
6049 write_number(static_cast<uint64_t>(N));
6050 }
6051 // LCOV_EXCL_STOP
6052
6053 // step 2: write each element
6054 for (const auto& el : *j.m_value.array) {
6055 write_cbor(el);
6056 }
6057 break;
6058 }
6059
6060 case value_t::object: {
6061 // step 1: write control byte and the object size
6062 const auto N = j.m_value.object->size();
6063 if (N <= 0x17) {
6064 write_number(static_cast<uint8_t>(0xA0 + N));
6065 } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6066 oa->write_character(static_cast<CharType>(0xB8));
6067 write_number(static_cast<uint8_t>(N));
6068 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6069 oa->write_character(static_cast<CharType>(0xB9));
6070 write_number(static_cast<uint16_t>(N));
6071 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6072 oa->write_character(static_cast<CharType>(0xBA));
6073 write_number(static_cast<uint32_t>(N));
6074 }
6075 // LCOV_EXCL_START
6076 else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6077 oa->write_character(static_cast<CharType>(0xBB));
6078 write_number(static_cast<uint64_t>(N));
6079 }
6080 // LCOV_EXCL_STOP
6081
6082 // step 2: write each element
6083 for (const auto& el : *j.m_value.object) {
6084 write_cbor(el.first);
6085 write_cbor(el.second);
6086 }
6087 break;
6088 }
6089
6090 default:
6091 break;
6092 }
6093 }
6094
6098 void write_msgpack(const BasicJsonType& j)
6099 {
6100 switch (j.type()) {
6101 case value_t::null: // nil
6102 {
6103 oa->write_character(static_cast<CharType>(0xC0));
6104 break;
6105 }
6106
6107 case value_t::boolean: // true and false
6108 {
6109 oa->write_character(j.m_value.boolean
6110 ? static_cast<CharType>(0xC3)
6111 : static_cast<CharType>(0xC2));
6112 break;
6113 }
6114
6115 case value_t::number_integer: {
6116 if (j.m_value.number_integer >= 0) {
6117 // MessagePack does not differentiate between positive
6118 // signed integers and unsigned integers. Therefore, we used
6119 // the code from the value_t::number_unsigned case here.
6120 if (j.m_value.number_unsigned < 128) {
6121 // positive fixnum
6122 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6123 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6124 // uint 8
6125 oa->write_character(static_cast<CharType>(0xCC));
6126 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6127 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6128 // uint 16
6129 oa->write_character(static_cast<CharType>(0xCD));
6130 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6131 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6132 // uint 32
6133 oa->write_character(static_cast<CharType>(0xCE));
6134 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6135 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6136 // uint 64
6137 oa->write_character(static_cast<CharType>(0xCF));
6138 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6139 }
6140 } else {
6141 if (j.m_value.number_integer >= -32) {
6142 // negative fixnum
6143 write_number(static_cast<int8_t>(j.m_value.number_integer));
6144 } else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6145 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6146 // int 8
6147 oa->write_character(static_cast<CharType>(0xD0));
6148 write_number(static_cast<int8_t>(j.m_value.number_integer));
6149 } else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6150 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6151 // int 16
6152 oa->write_character(static_cast<CharType>(0xD1));
6153 write_number(static_cast<int16_t>(j.m_value.number_integer));
6154 } else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6155 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6156 // int 32
6157 oa->write_character(static_cast<CharType>(0xD2));
6158 write_number(static_cast<int32_t>(j.m_value.number_integer));
6159 } else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6160 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)()) {
6161 // int 64
6162 oa->write_character(static_cast<CharType>(0xD3));
6163 write_number(static_cast<int64_t>(j.m_value.number_integer));
6164 }
6165 }
6166 break;
6167 }
6168
6169 case value_t::number_unsigned: {
6170 if (j.m_value.number_unsigned < 128) {
6171 // positive fixnum
6172 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6173 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6174 // uint 8
6175 oa->write_character(static_cast<CharType>(0xCC));
6176 write_number(static_cast<uint8_t>(j.m_value.number_integer));
6177 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6178 // uint 16
6179 oa->write_character(static_cast<CharType>(0xCD));
6180 write_number(static_cast<uint16_t>(j.m_value.number_integer));
6181 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6182 // uint 32
6183 oa->write_character(static_cast<CharType>(0xCE));
6184 write_number(static_cast<uint32_t>(j.m_value.number_integer));
6185 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6186 // uint 64
6187 oa->write_character(static_cast<CharType>(0xCF));
6188 write_number(static_cast<uint64_t>(j.m_value.number_integer));
6189 }
6190 break;
6191 }
6192
6193 case value_t::number_float: // float 64
6194 {
6195 oa->write_character(static_cast<CharType>(0xCB));
6196 write_number(j.m_value.number_float);
6197 break;
6198 }
6199
6200 case value_t::string: {
6201 // step 1: write control byte and the string length
6202 const auto N = j.m_value.string->size();
6203 if (N <= 31) {
6204 // fixstr
6205 write_number(static_cast<uint8_t>(0xA0 | N));
6206 } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6207 // str 8
6208 oa->write_character(static_cast<CharType>(0xD9));
6209 write_number(static_cast<uint8_t>(N));
6210 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6211 // str 16
6212 oa->write_character(static_cast<CharType>(0xDA));
6213 write_number(static_cast<uint16_t>(N));
6214 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6215 // str 32
6216 oa->write_character(static_cast<CharType>(0xDB));
6217 write_number(static_cast<uint32_t>(N));
6218 }
6219
6220 // step 2: write the string
6221 oa->write_characters(
6222 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6223 j.m_value.string->size());
6224 break;
6225 }
6226
6227 case value_t::array: {
6228 // step 1: write control byte and the array size
6229 const auto N = j.m_value.array->size();
6230 if (N <= 15) {
6231 // fixarray
6232 write_number(static_cast<uint8_t>(0x90 | N));
6233 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6234 // array 16
6235 oa->write_character(static_cast<CharType>(0xDC));
6236 write_number(static_cast<uint16_t>(N));
6237 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6238 // array 32
6239 oa->write_character(static_cast<CharType>(0xDD));
6240 write_number(static_cast<uint32_t>(N));
6241 }
6242
6243 // step 2: write each element
6244 for (const auto& el : *j.m_value.array) {
6245 write_msgpack(el);
6246 }
6247 break;
6248 }
6249
6250 case value_t::object: {
6251 // step 1: write control byte and the object size
6252 const auto N = j.m_value.object->size();
6253 if (N <= 15) {
6254 // fixmap
6255 write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6256 } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6257 // map 16
6258 oa->write_character(static_cast<CharType>(0xDE));
6259 write_number(static_cast<uint16_t>(N));
6260 } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6261 // map 32
6262 oa->write_character(static_cast<CharType>(0xDF));
6263 write_number(static_cast<uint32_t>(N));
6264 }
6265
6266 // step 2: write each element
6267 for (const auto& el : *j.m_value.object) {
6268 write_msgpack(el.first);
6269 write_msgpack(el.second);
6270 }
6271 break;
6272 }
6273
6274 default:
6275 break;
6276 }
6277 }
6278
6285 void write_ubjson(const BasicJsonType& j, const bool use_count,
6286 const bool use_type, const bool add_prefix = true)
6287 {
6288 switch (j.type()) {
6289 case value_t::null: {
6290 if (add_prefix) {
6291 oa->write_character(static_cast<CharType>('Z'));
6292 }
6293 break;
6294 }
6295
6296 case value_t::boolean: {
6297 if (add_prefix) {
6298 oa->write_character(j.m_value.boolean
6299 ? static_cast<CharType>('T')
6300 : static_cast<CharType>('F'));
6301 }
6302 break;
6303 }
6304
6305 case value_t::number_integer: {
6306 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6307 break;
6308 }
6309
6310 case value_t::number_unsigned: {
6311 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6312 break;
6313 }
6314
6315 case value_t::number_float: {
6316 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6317 break;
6318 }
6319
6320 case value_t::string: {
6321 if (add_prefix) {
6322 oa->write_character(static_cast<CharType>('S'));
6323 }
6324 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
6325 oa->write_characters(
6326 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6327 j.m_value.string->size());
6328 break;
6329 }
6330
6331 case value_t::array: {
6332 if (add_prefix) {
6333 oa->write_character(static_cast<CharType>('['));
6334 }
6335
6336 bool prefix_required = true;
6337 if (use_type and not j.m_value.array->empty()) {
6338 assert(use_count);
6339 const char first_prefix = ubjson_prefix(j.front());
6340 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6341 [this, first_prefix](const BasicJsonType& v) {
6342 return ubjson_prefix(v) == first_prefix;
6343 });
6344
6345 if (same_prefix) {
6346 prefix_required = false;
6347 oa->write_character(static_cast<CharType>('$'));
6348 oa->write_character(static_cast<CharType>(first_prefix));
6349 }
6350 }
6351
6352 if (use_count) {
6353 oa->write_character(static_cast<CharType>('#'));
6354 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
6355 }
6356
6357 for (const auto& el : *j.m_value.array) {
6358 write_ubjson(el, use_count, use_type, prefix_required);
6359 }
6360
6361 if (not use_count) {
6362 oa->write_character(static_cast<CharType>(']'));
6363 }
6364
6365 break;
6366 }
6367
6368 case value_t::object: {
6369 if (add_prefix) {
6370 oa->write_character(static_cast<CharType>('{'));
6371 }
6372
6373 bool prefix_required = true;
6374 if (use_type and not j.m_value.object->empty()) {
6375 assert(use_count);
6376 const char first_prefix = ubjson_prefix(j.front());
6377 const bool same_prefix = std::all_of(j.begin(), j.end(),
6378 [this, first_prefix](const BasicJsonType& v) {
6379 return ubjson_prefix(v) == first_prefix;
6380 });
6381
6382 if (same_prefix) {
6383 prefix_required = false;
6384 oa->write_character(static_cast<CharType>('$'));
6385 oa->write_character(static_cast<CharType>(first_prefix));
6386 }
6387 }
6388
6389 if (use_count) {
6390 oa->write_character(static_cast<CharType>('#'));
6391 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
6392 }
6393
6394 for (const auto& el : *j.m_value.object) {
6395 write_number_with_ubjson_prefix(el.first.size(), true);
6396 oa->write_characters(
6397 reinterpret_cast<const CharType*>(el.first.c_str()),
6398 el.first.size());
6399 write_ubjson(el.second, use_count, use_type, prefix_required);
6400 }
6401
6402 if (not use_count) {
6403 oa->write_character(static_cast<CharType>('}'));
6404 }
6405
6406 break;
6407 }
6408
6409 default:
6410 break;
6411 }
6412 }
6413
6414 private:
6415 /*
6416 @brief write a number to output input
6417
6418 @param[in] n number of type @a NumberType
6419 @tparam NumberType the type of the number
6420
6421 @note This function needs to respect the system's endianess, because bytes
6422 in CBOR, MessagePack, and UBJSON are stored in network order (big
6423 endian) and therefore need reordering on little endian systems.
6424 */
6425 template <typename NumberType>
6426 void write_number(const NumberType n)
6427 {
6428 // step 1: write number to array of length NumberType
6429 std::array<CharType, sizeof(NumberType)> vec;
6430 std::memcpy(vec.data(), &n, sizeof(NumberType));
6431
6432 // step 2: write array to output (with possible reordering)
6433 if (is_little_endian) {
6434 // reverse byte order prior to conversion if necessary
6435 std::reverse(vec.begin(), vec.end());
6436 }
6437
6438 oa->write_characters(vec.data(), sizeof(NumberType));
6439 }
6440
6441 // UBJSON: write number (floating point)
6442 template <typename NumberType, typename std::enable_if<
6443 std::is_floating_point<NumberType>::value, int>::type = 0>
6444 void write_number_with_ubjson_prefix(const NumberType n,
6445 const bool add_prefix)
6446 {
6447 if (add_prefix) {
6448 oa->write_character(static_cast<CharType>('D')); // float64
6449 }
6450 write_number(n);
6451 }
6452
6453 // UBJSON: write number (unsigned integer)
6454 template <typename NumberType, typename std::enable_if<
6455 std::is_unsigned<NumberType>::value, int>::type = 0>
6456 void write_number_with_ubjson_prefix(const NumberType n,
6457 const bool add_prefix)
6458 {
6459 if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)())) {
6460 if (add_prefix) {
6461 oa->write_character(static_cast<CharType>('i')); // int8
6462 }
6463 write_number(static_cast<uint8_t>(n));
6464 } else if (n <= (std::numeric_limits<uint8_t>::max)()) {
6465 if (add_prefix) {
6466 oa->write_character(static_cast<CharType>('U')); // uint8
6467 }
6468 write_number(static_cast<uint8_t>(n));
6469 } else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)())) {
6470 if (add_prefix) {
6471 oa->write_character(static_cast<CharType>('I')); // int16
6472 }
6473 write_number(static_cast<int16_t>(n));
6474 } else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)())) {
6475 if (add_prefix) {
6476 oa->write_character(static_cast<CharType>('l')); // int32
6477 }
6478 write_number(static_cast<int32_t>(n));
6479 } else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)())) {
6480 if (add_prefix) {
6481 oa->write_character(static_cast<CharType>('L')); // int64
6482 }
6483 write_number(static_cast<int64_t>(n));
6484 } else {
6485 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
6486 }
6487 }
6488
6489 // UBJSON: write number (signed integer)
6490 template <typename NumberType, typename std::enable_if<
6491 std::is_signed<NumberType>::value and
6492 not std::is_floating_point<NumberType>::value,
6493 int>::type = 0>
6494 void write_number_with_ubjson_prefix(const NumberType n,
6495 const bool add_prefix)
6496 {
6497 if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)()) {
6498 if (add_prefix) {
6499 oa->write_character(static_cast<CharType>('i')); // int8
6500 }
6501 write_number(static_cast<int8_t>(n));
6502 } else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)())) {
6503 if (add_prefix) {
6504 oa->write_character(static_cast<CharType>('U')); // uint8
6505 }
6506 write_number(static_cast<uint8_t>(n));
6507 } else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)()) {
6508 if (add_prefix) {
6509 oa->write_character(static_cast<CharType>('I')); // int16
6510 }
6511 write_number(static_cast<int16_t>(n));
6512 } else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)()) {
6513 if (add_prefix) {
6514 oa->write_character(static_cast<CharType>('l')); // int32
6515 }
6516 write_number(static_cast<int32_t>(n));
6517 } else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)()) {
6518 if (add_prefix) {
6519 oa->write_character(static_cast<CharType>('L')); // int64
6520 }
6521 write_number(static_cast<int64_t>(n));
6522 }
6523 // LCOV_EXCL_START
6524 else {
6525 JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
6526 }
6527 // LCOV_EXCL_STOP
6528 }
6529
6539 char ubjson_prefix(const BasicJsonType& j) const noexcept
6540 {
6541 switch (j.type()) {
6542 case value_t::null:
6543 return 'Z';
6544
6545 case value_t::boolean:
6546 return j.m_value.boolean ? 'T' : 'F';
6547
6548 case value_t::number_integer: {
6549 if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6550 return 'i';
6551 } else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
6552 return 'U';
6553 } else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6554 return 'I';
6555 } else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6556 return 'l';
6557 } else // no check and assume int64_t (see note above)
6558 {
6559 return 'L';
6560 }
6561 }
6562
6563 case value_t::number_unsigned: {
6564 if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)()) {
6565 return 'i';
6566 } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6567 return 'U';
6568 } else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)()) {
6569 return 'I';
6570 } else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)()) {
6571 return 'l';
6572 } else // no check and assume int64_t (see note above)
6573 {
6574 return 'L';
6575 }
6576 }
6577
6578 case value_t::number_float:
6579 return 'D';
6580
6581 case value_t::string:
6582 return 'S';
6583
6584 case value_t::array:
6585 return '[';
6586
6587 case value_t::object:
6588 return '{';
6589
6590 default: // discarded values
6591 return 'N';
6592 }
6593 }
6594
6595 private:
6597 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6598
6600 output_adapter_t<CharType> oa = nullptr;
6601};
6602} // namespace detail
6603} // namespace nlohmann
6604
6605// #include <nlohmann/detail/output/serializer.hpp>
6606
6607#include <algorithm> // reverse, remove, fill, find, none_of
6608#include <array> // array
6609#include <cassert> // assert
6610#include <ciso646> // and, or
6611#include <clocale> // localeconv, lconv
6612#include <cmath> // labs, isfinite, isnan, signbit
6613#include <cstddef> // size_t, ptrdiff_t
6614#include <cstdint> // uint8_t
6615#include <cstdio> // snprintf
6616#include <iomanip> // setfill
6617#include <iterator> // next
6618#include <limits> // numeric_limits
6619#include <string> // string
6620#include <sstream> // stringstream
6621#include <type_traits> // is_same
6622
6623// #include <nlohmann/detail/exceptions.hpp>
6624
6625// #include <nlohmann/detail/conversions/to_chars.hpp>
6626
6627#include <cassert> // assert
6628#include <ciso646> // or, and, not
6629#include <cmath> // signbit, isfinite
6630#include <cstdint> // intN_t, uintN_t
6631#include <cstring> // memcpy, memmove
6632
6633namespace nlohmann
6634{
6635namespace detail
6636{
6637
6657namespace dtoa_impl
6658{
6659
6660template <typename Target, typename Source>
6661Target reinterpret_bits(const Source source)
6662{
6663 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
6664
6665 Target target;
6666 std::memcpy(&target, &source, sizeof(Source));
6667 return target;
6668}
6669
6670struct diyfp // f * 2^e
6671{
6672 static constexpr int kPrecision = 64; // = q
6673
6674 uint64_t f;
6675 int e;
6676
6677 constexpr diyfp() noexcept : f(0), e(0) {}
6678 constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
6679
6684 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
6685 {
6686 assert(x.e == y.e);
6687 assert(x.f >= y.f);
6688
6689 return diyfp(x.f - y.f, x.e);
6690 }
6691
6696 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
6697 {
6698 static_assert(kPrecision == 64, "internal error");
6699
6700 // Computes:
6701 // f = round((x.f * y.f) / 2^q)
6702 // e = x.e + y.e + q
6703
6704 // Emulate the 64-bit * 64-bit multiplication:
6705 //
6706 // p = u * v
6707 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
6708 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
6709 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
6710 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
6711 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
6712 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
6713 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
6714 //
6715 // (Since Q might be larger than 2^32 - 1)
6716 //
6717 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
6718 //
6719 // (Q_hi + H does not overflow a 64-bit int)
6720 //
6721 // = p_lo + 2^64 p_hi
6722
6723 const uint64_t u_lo = x.f & 0xFFFFFFFF;
6724 const uint64_t u_hi = x.f >> 32;
6725 const uint64_t v_lo = y.f & 0xFFFFFFFF;
6726 const uint64_t v_hi = y.f >> 32;
6727
6728 const uint64_t p0 = u_lo * v_lo;
6729 const uint64_t p1 = u_lo * v_hi;
6730 const uint64_t p2 = u_hi * v_lo;
6731 const uint64_t p3 = u_hi * v_hi;
6732
6733 const uint64_t p0_hi = p0 >> 32;
6734 const uint64_t p1_lo = p1 & 0xFFFFFFFF;
6735 const uint64_t p1_hi = p1 >> 32;
6736 const uint64_t p2_lo = p2 & 0xFFFFFFFF;
6737 const uint64_t p2_hi = p2 >> 32;
6738
6739 uint64_t Q = p0_hi + p1_lo + p2_lo;
6740
6741 // The full product might now be computed as
6742 //
6743 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
6744 // p_lo = p0_lo + (Q << 32)
6745 //
6746 // But in this particular case here, the full p_lo is not required.
6747 // Effectively we only need to add the highest bit in p_lo to p_hi (and
6748 // Q_hi + 1 does not overflow).
6749
6750 Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
6751
6752 const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
6753
6754 return diyfp(h, x.e + y.e + 64);
6755 }
6756
6761 static diyfp normalize(diyfp x) noexcept
6762 {
6763 assert(x.f != 0);
6764
6765 while ((x.f >> 63) == 0) {
6766 x.f <<= 1;
6767 x.e--;
6768 }
6769
6770 return x;
6771 }
6772
6777 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
6778 {
6779 const int delta = x.e - target_exponent;
6780
6781 assert(delta >= 0);
6782 assert(((x.f << delta) >> delta) == x.f);
6783
6784 return diyfp(x.f << delta, target_exponent);
6785 }
6786};
6787
6788struct boundaries {
6789 diyfp w;
6790 diyfp minus;
6791 diyfp plus;
6792};
6793
6800template <typename FloatType>
6801boundaries compute_boundaries(FloatType value)
6802{
6803 assert(std::isfinite(value));
6804 assert(value > 0);
6805
6806 // Convert the IEEE representation into a diyfp.
6807 //
6808 // If v is denormal:
6809 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
6810 // If v is normalized:
6811 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
6812
6813 static_assert(std::numeric_limits<FloatType>::is_iec559,
6814 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
6815
6816 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
6817 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
6818 constexpr int kMinExp = 1 - kBias;
6819 constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
6820
6821 using bits_type = typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
6822
6823 const uint64_t bits = reinterpret_bits<bits_type>(value);
6824 const uint64_t E = bits >> (kPrecision - 1);
6825 const uint64_t F = bits & (kHiddenBit - 1);
6826
6827 const bool is_denormal = (E == 0);
6828 const diyfp v = is_denormal
6829 ? diyfp(F, kMinExp)
6830 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
6831
6832 // Compute the boundaries m- and m+ of the floating-point value
6833 // v = f * 2^e.
6834 //
6835 // Determine v- and v+, the floating-point predecessor and successor if v,
6836 // respectively.
6837 //
6838 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
6839 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
6840 //
6841 // v+ = v + 2^e
6842 //
6843 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
6844 // between m- and m+ round to v, regardless of how the input rounding
6845 // algorithm breaks ties.
6846 //
6847 // ---+-------------+-------------+-------------+-------------+--- (A)
6848 // v- m- v m+ v+
6849 //
6850 // -----------------+------+------+-------------+-------------+--- (B)
6851 // v- m- v m+ v+
6852
6853 const bool lower_boundary_is_closer = (F == 0 and E > 1);
6854 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
6855 const diyfp m_minus = lower_boundary_is_closer
6856 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
6857 : diyfp(2 * v.f - 1, v.e - 1); // (A)
6858
6859 // Determine the normalized w+ = m+.
6860 const diyfp w_plus = diyfp::normalize(m_plus);
6861
6862 // Determine w- = m- such that e_(w-) = e_(w+).
6863 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
6864
6865 return {diyfp::normalize(v), w_minus, w_plus};
6866}
6867
6868// Given normalized diyfp w, Grisu needs to find a (normalized) cached
6869// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
6870// within a certain range [alpha, gamma] (Definition 3.2 from [1])
6871//
6872// alpha <= e = e_c + e_w + q <= gamma
6873//
6874// or
6875//
6876// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
6877// <= f_c * f_w * 2^gamma
6878//
6879// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
6880//
6881// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
6882//
6883// or
6884//
6885// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
6886//
6887// The choice of (alpha,gamma) determines the size of the table and the form of
6888// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
6889// in practice:
6890//
6891// The idea is to cut the number c * w = f * 2^e into two parts, which can be
6892// processed independently: An integral part p1, and a fractional part p2:
6893//
6894// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
6895// = (f div 2^-e) + (f mod 2^-e) * 2^e
6896// = p1 + p2 * 2^e
6897//
6898// The conversion of p1 into decimal form requires a series of divisions and
6899// modulos by (a power of) 10. These operations are faster for 32-bit than for
6900// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
6901// achieved by choosing
6902//
6903// -e >= 32 or e <= -32 := gamma
6904//
6905// In order to convert the fractional part
6906//
6907// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
6908//
6909// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
6910// d[-i] are extracted in order:
6911//
6912// (10 * p2) div 2^-e = d[-1]
6913// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
6914//
6915// The multiplication by 10 must not overflow. It is sufficient to choose
6916//
6917// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
6918//
6919// Since p2 = f mod 2^-e < 2^-e,
6920//
6921// -e <= 60 or e >= -60 := alpha
6922
6923constexpr int kAlpha = -60;
6924constexpr int kGamma = -32;
6925
6926struct cached_power // c = f * 2^e ~= 10^k
6927{
6928 uint64_t f;
6929 int e;
6930 int k;
6931};
6932
6940inline cached_power get_cached_power_for_binary_exponent(int e)
6941{
6942 // Now
6943 //
6944 // alpha <= e_c + e + q <= gamma (1)
6945 // ==> f_c * 2^alpha <= c * 2^e * 2^q
6946 //
6947 // and since the c's are normalized, 2^(q-1) <= f_c,
6948 //
6949 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
6950 // ==> 2^(alpha - e - 1) <= c
6951 //
6952 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
6953 //
6954 // k = ceil( log_10( 2^(alpha - e - 1) ) )
6955 // = ceil( (alpha - e - 1) * log_10(2) )
6956 //
6957 // From the paper:
6958 // "In theory the result of the procedure could be wrong since c is rounded,
6959 // and the computation itself is approximated [...]. In practice, however,
6960 // this simple function is sufficient."
6961 //
6962 // For IEEE double precision floating-point numbers converted into
6963 // normalized diyfp's w = f * 2^e, with q = 64,
6964 //
6965 // e >= -1022 (min IEEE exponent)
6966 // -52 (p - 1)
6967 // -52 (p - 1, possibly normalize denormal IEEE numbers)
6968 // -11 (normalize the diyfp)
6969 // = -1137
6970 //
6971 // and
6972 //
6973 // e <= +1023 (max IEEE exponent)
6974 // -52 (p - 1)
6975 // -11 (normalize the diyfp)
6976 // = 960
6977 //
6978 // This binary exponent range [-1137,960] results in a decimal exponent
6979 // range [-307,324]. One does not need to store a cached power for each
6980 // k in this range. For each such k it suffices to find a cached power
6981 // such that the exponent of the product lies in [alpha,gamma].
6982 // This implies that the difference of the decimal exponents of adjacent
6983 // table entries must be less than or equal to
6984 //
6985 // floor( (gamma - alpha) * log_10(2) ) = 8.
6986 //
6987 // (A smaller distance gamma-alpha would require a larger table.)
6988
6989 // NB:
6990 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
6991
6992 constexpr int kCachedPowersSize = 79;
6993 constexpr int kCachedPowersMinDecExp = -300;
6994 constexpr int kCachedPowersDecStep = 8;
6995
6996 static constexpr cached_power kCachedPowers[] =
6997 {
6998 {0xAB70FE17C79AC6CA, -1060, -300},
6999 {0xFF77B1FCBEBCDC4F, -1034, -292},
7000 {0xBE5691EF416BD60C, -1007, -284},
7001 {0x8DD01FAD907FFC3C, -980, -276},
7002 {0xD3515C2831559A83, -954, -268},
7003 {0x9D71AC8FADA6C9B5, -927, -260},
7004 {0xEA9C227723EE8BCB, -901, -252},
7005 {0xAECC49914078536D, -874, -244},
7006 {0x823C12795DB6CE57, -847, -236},
7007 {0xC21094364DFB5637, -821, -228},
7008 {0x9096EA6F3848984F, -794, -220},
7009 {0xD77485CB25823AC7, -768, -212},
7010 {0xA086CFCD97BF97F4, -741, -204},
7011 {0xEF340A98172AACE5, -715, -196},
7012 {0xB23867FB2A35B28E, -688, -188},
7013 {0x84C8D4DFD2C63F3B, -661, -180},
7014 {0xC5DD44271AD3CDBA, -635, -172},
7015 {0x936B9FCEBB25C996, -608, -164},
7016 {0xDBAC6C247D62A584, -582, -156},
7017 {0xA3AB66580D5FDAF6, -555, -148},
7018 {0xF3E2F893DEC3F126, -529, -140},
7019 {0xB5B5ADA8AAFF80B8, -502, -132},
7020 {0x87625F056C7C4A8B, -475, -124},
7021 {0xC9BCFF6034C13053, -449, -116},
7022 {0x964E858C91BA2655, -422, -108},
7023 {0xDFF9772470297EBD, -396, -100},
7024 {0xA6DFBD9FB8E5B88F, -369, -92},
7025 {0xF8A95FCF88747D94, -343, -84},
7026 {0xB94470938FA89BCF, -316, -76},
7027 {0x8A08F0F8BF0F156B, -289, -68},
7028 {0xCDB02555653131B6, -263, -60},
7029 {0x993FE2C6D07B7FAC, -236, -52},
7030 {0xE45C10C42A2B3B06, -210, -44},
7031 {0xAA242499697392D3, -183, -36},
7032 {0xFD87B5F28300CA0E, -157, -28},
7033 {0xBCE5086492111AEB, -130, -20},
7034 {0x8CBCCC096F5088CC, -103, -12},
7035 {0xD1B71758E219652C, -77, -4},
7036 {0x9C40000000000000, -50, 4},
7037 {0xE8D4A51000000000, -24, 12},
7038 {0xAD78EBC5AC620000, 3, 20},
7039 {0x813F3978F8940984, 30, 28},
7040 {0xC097CE7BC90715B3, 56, 36},
7041 {0x8F7E32CE7BEA5C70, 83, 44},
7042 {0xD5D238A4ABE98068, 109, 52},
7043 {0x9F4F2726179A2245, 136, 60},
7044 {0xED63A231D4C4FB27, 162, 68},
7045 {0xB0DE65388CC8ADA8, 189, 76},
7046 {0x83C7088E1AAB65DB, 216, 84},
7047 {0xC45D1DF942711D9A, 242, 92},
7048 {0x924D692CA61BE758, 269, 100},
7049 {0xDA01EE641A708DEA, 295, 108},
7050 {0xA26DA3999AEF774A, 322, 116},
7051 {0xF209787BB47D6B85, 348, 124},
7052 {0xB454E4A179DD1877, 375, 132},
7053 {0x865B86925B9BC5C2, 402, 140},
7054 {0xC83553C5C8965D3D, 428, 148},
7055 {0x952AB45CFA97A0B3, 455, 156},
7056 {0xDE469FBD99A05FE3, 481, 164},
7057 {0xA59BC234DB398C25, 508, 172},
7058 {0xF6C69A72A3989F5C, 534, 180},
7059 {0xB7DCBF5354E9BECE, 561, 188},
7060 {0x88FCF317F22241E2, 588, 196},
7061 {0xCC20CE9BD35C78A5, 614, 204},
7062 {0x98165AF37B2153DF, 641, 212},
7063 {0xE2A0B5DC971F303A, 667, 220},
7064 {0xA8D9D1535CE3B396, 694, 228},
7065 {0xFB9B7CD9A4A7443C, 720, 236},
7066 {0xBB764C4CA7A44410, 747, 244},
7067 {0x8BAB8EEFB6409C1A, 774, 252},
7068 {0xD01FEF10A657842C, 800, 260},
7069 {0x9B10A4E5E9913129, 827, 268},
7070 {0xE7109BFBA19C0C9D, 853, 276},
7071 {0xAC2820D9623BF429, 880, 284},
7072 {0x80444B5E7AA7CF85, 907, 292},
7073 {0xBF21E44003ACDD2D, 933, 300},
7074 {0x8E679C2F5E44FF8F, 960, 308},
7075 {0xD433179D9C8CB841, 986, 316},
7076 {0x9E19DB92B4E31BA9, 1013, 324},
7077 };
7078
7079 // This computation gives exactly the same results for k as
7080 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
7081 // for |e| <= 1500, but doesn't require floating-point operations.
7082 // NB: log_10(2) ~= 78913 / 2^18
7083 assert(e >= -1500);
7084 assert(e <= 1500);
7085 const int f = kAlpha - e - 1;
7086 const int k = (f * 78913) / (1 << 18) + (f > 0);
7087
7088 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7089 assert(index >= 0);
7090 assert(index < kCachedPowersSize);
7091 static_cast<void>(kCachedPowersSize); // Fix warning.
7092
7093 const cached_power cached = kCachedPowers[index];
7094 assert(kAlpha <= cached.e + e + 64);
7095 assert(kGamma >= cached.e + e + 64);
7096
7097 return cached;
7098}
7099
7104inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
7105{
7106 // LCOV_EXCL_START
7107 if (n >= 1000000000) {
7108 pow10 = 1000000000;
7109 return 10;
7110 }
7111 // LCOV_EXCL_STOP
7112 else if (n >= 100000000) {
7113 pow10 = 100000000;
7114 return 9;
7115 } else if (n >= 10000000) {
7116 pow10 = 10000000;
7117 return 8;
7118 } else if (n >= 1000000) {
7119 pow10 = 1000000;
7120 return 7;
7121 } else if (n >= 100000) {
7122 pow10 = 100000;
7123 return 6;
7124 } else if (n >= 10000) {
7125 pow10 = 10000;
7126 return 5;
7127 } else if (n >= 1000) {
7128 pow10 = 1000;
7129 return 4;
7130 } else if (n >= 100) {
7131 pow10 = 100;
7132 return 3;
7133 } else if (n >= 10) {
7134 pow10 = 10;
7135 return 2;
7136 } else {
7137 pow10 = 1;
7138 return 1;
7139 }
7140}
7141
7142inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
7143 uint64_t rest, uint64_t ten_k)
7144{
7145 assert(len >= 1);
7146 assert(dist <= delta);
7147 assert(rest <= delta);
7148 assert(ten_k > 0);
7149
7150 // <--------------------------- delta ---->
7151 // <---- dist --------->
7152 // --------------[------------------+-------------------]--------------
7153 // M- w M+
7154 //
7155 // ten_k
7156 // <------>
7157 // <---- rest ---->
7158 // --------------[------------------+----+--------------]--------------
7159 // w V
7160 // = buf * 10^k
7161 //
7162 // ten_k represents a unit-in-the-last-place in the decimal representation
7163 // stored in buf.
7164 // Decrement buf by ten_k while this takes buf closer to w.
7165
7166 // The tests are written in this order to avoid overflow in unsigned
7167 // integer arithmetic.
7168
7169 while (rest < dist and delta - rest >= ten_k and (rest + ten_k < dist or dist - rest > rest + ten_k - dist)) {
7170 assert(buf[len - 1] != '0');
7171 buf[len - 1]--;
7172 rest += ten_k;
7173 }
7174}
7175
7180inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
7181 diyfp M_minus, diyfp w, diyfp M_plus)
7182{
7183 static_assert(kAlpha >= -60, "internal error");
7184 static_assert(kGamma <= -32, "internal error");
7185
7186 // Generates the digits (and the exponent) of a decimal floating-point
7187 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
7188 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
7189 //
7190 // <--------------------------- delta ---->
7191 // <---- dist --------->
7192 // --------------[------------------+-------------------]--------------
7193 // M- w M+
7194 //
7195 // Grisu2 generates the digits of M+ from left to right and stops as soon as
7196 // V is in [M-,M+].
7197
7198 assert(M_plus.e >= kAlpha);
7199 assert(M_plus.e <= kGamma);
7200
7201 uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
7202 uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
7203
7204 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
7205 //
7206 // M+ = f * 2^e
7207 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
7208 // = ((p1 ) * 2^-e + (p2 )) * 2^e
7209 // = p1 + p2 * 2^e
7210
7211 const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
7212
7213 uint32_t p1 = static_cast<uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
7214 uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
7215
7216 // 1)
7217 //
7218 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
7219
7220 assert(p1 > 0);
7221
7222 uint32_t pow10;
7223 const int k = find_largest_pow10(p1, pow10);
7224
7225 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
7226 //
7227 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
7228 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
7229 //
7230 // M+ = p1 + p2 * 2^e
7231 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
7232 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
7233 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
7234 //
7235 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
7236 //
7237 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
7238 //
7239 // but stop as soon as
7240 //
7241 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
7242
7243 int n = k;
7244 while (n > 0) {
7245 // Invariants:
7246 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
7247 // pow10 = 10^(n-1) <= p1 < 10^n
7248 //
7249 const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
7250 const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
7251 //
7252 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
7253 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
7254 //
7255 assert(d <= 9);
7256 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7257 //
7258 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
7259 //
7260 p1 = r;
7261 n--;
7262 //
7263 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
7264 // pow10 = 10^n
7265 //
7266
7267 // Now check if enough digits have been generated.
7268 // Compute
7269 //
7270 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
7271 //
7272 // Note:
7273 // Since rest and delta share the same exponent e, it suffices to
7274 // compare the significands.
7275 const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
7276 if (rest <= delta) {
7277 // V = buffer * 10^n, with M- <= V <= M+.
7278
7279 decimal_exponent += n;
7280
7281 // We may now just stop. But instead look if the buffer could be
7282 // decremented to bring V closer to w.
7283 //
7284 // pow10 = 10^n is now 1 ulp in the decimal representation V.
7285 // The rounding procedure works with diyfp's with an implicit
7286 // exponent of e.
7287 //
7288 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
7289 //
7290 const uint64_t ten_n = uint64_t{pow10} << -one.e;
7291 grisu2_round(buffer, length, dist, delta, rest, ten_n);
7292
7293 return;
7294 }
7295
7296 pow10 /= 10;
7297 //
7298 // pow10 = 10^(n-1) <= p1 < 10^n
7299 // Invariants restored.
7300 }
7301
7302 // 2)
7303 //
7304 // The digits of the integral part have been generated:
7305 //
7306 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
7307 // = buffer + p2 * 2^e
7308 //
7309 // Now generate the digits of the fractional part p2 * 2^e.
7310 //
7311 // Note:
7312 // No decimal point is generated: the exponent is adjusted instead.
7313 //
7314 // p2 actually represents the fraction
7315 //
7316 // p2 * 2^e
7317 // = p2 / 2^-e
7318 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
7319 //
7320 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
7321 //
7322 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
7323 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
7324 //
7325 // using
7326 //
7327 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
7328 // = ( d) * 2^-e + ( r)
7329 //
7330 // or
7331 // 10^m * p2 * 2^e = d + r * 2^e
7332 //
7333 // i.e.
7334 //
7335 // M+ = buffer + p2 * 2^e
7336 // = buffer + 10^-m * (d + r * 2^e)
7337 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
7338 //
7339 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
7340
7341 assert(p2 > delta);
7342
7343 int m = 0;
7344 for (;;) {
7345 // Invariant:
7346 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
7347 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
7348 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
7349 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
7350 //
7351 assert(p2 <= UINT64_MAX / 10);
7352 p2 *= 10;
7353 const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
7354 const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
7355 //
7356 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
7357 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
7358 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
7359 //
7360 assert(d <= 9);
7361 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7362 //
7363 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
7364 //
7365 p2 = r;
7366 m++;
7367 //
7368 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
7369 // Invariant restored.
7370
7371 // Check if enough digits have been generated.
7372 //
7373 // 10^-m * p2 * 2^e <= delta * 2^e
7374 // p2 * 2^e <= 10^m * delta * 2^e
7375 // p2 <= 10^m * delta
7376 delta *= 10;
7377 dist *= 10;
7378 if (p2 <= delta) {
7379 break;
7380 }
7381 }
7382
7383 // V = buffer * 10^-m, with M- <= V <= M+.
7384
7385 decimal_exponent -= m;
7386
7387 // 1 ulp in the decimal representation is now 10^-m.
7388 // Since delta and dist are now scaled by 10^m, we need to do the
7389 // same with ulp in order to keep the units in sync.
7390 //
7391 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
7392 //
7393 const uint64_t ten_m = one.f;
7394 grisu2_round(buffer, length, dist, delta, p2, ten_m);
7395
7396 // By construction this algorithm generates the shortest possible decimal
7397 // number (Loitsch, Theorem 6.2) which rounds back to w.
7398 // For an input number of precision p, at least
7399 //
7400 // N = 1 + ceil(p * log_10(2))
7401 //
7402 // decimal digits are sufficient to identify all binary floating-point
7403 // numbers (Matula, "In-and-Out conversions").
7404 // This implies that the algorithm does not produce more than N decimal
7405 // digits.
7406 //
7407 // N = 17 for p = 53 (IEEE double precision)
7408 // N = 9 for p = 24 (IEEE single precision)
7409}
7410
7416inline void grisu2(char* buf, int& len, int& decimal_exponent,
7417 diyfp m_minus, diyfp v, diyfp m_plus)
7418{
7419 assert(m_plus.e == m_minus.e);
7420 assert(m_plus.e == v.e);
7421
7422 // --------(-----------------------+-----------------------)-------- (A)
7423 // m- v m+
7424 //
7425 // --------------------(-----------+-----------------------)-------- (B)
7426 // m- v m+
7427 //
7428 // First scale v (and m- and m+) such that the exponent is in the range
7429 // [alpha, gamma].
7430
7431 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
7432
7433 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
7434
7435 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
7436 const diyfp w = diyfp::mul(v, c_minus_k);
7437 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7438 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
7439
7440 // ----(---+---)---------------(---+---)---------------(---+---)----
7441 // w- w w+
7442 // = c*m- = c*v = c*m+
7443 //
7444 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
7445 // w+ are now off by a small amount.
7446 // In fact:
7447 //
7448 // w - v * 10^k < 1 ulp
7449 //
7450 // To account for this inaccuracy, add resp. subtract 1 ulp.
7451 //
7452 // --------+---[---------------(---+---)---------------]---+--------
7453 // w- M- w M+ w+
7454 //
7455 // Now any number in [M-, M+] (bounds included) will round to w when input,
7456 // regardless of how the input rounding algorithm breaks ties.
7457 //
7458 // And digit_gen generates the shortest possible such number in [M-, M+].
7459 // Note that this does not mean that Grisu2 always generates the shortest
7460 // possible number in the interval (m-, m+).
7461 const diyfp M_minus(w_minus.f + 1, w_minus.e);
7462 const diyfp M_plus(w_plus.f - 1, w_plus.e);
7463
7464 decimal_exponent = -cached.k; // = -(-k) = k
7465
7466 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
7467}
7468
7474template <typename FloatType>
7475void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
7476{
7477 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
7478 "internal error: not enough precision");
7479
7480 assert(std::isfinite(value));
7481 assert(value > 0);
7482
7483// If the neighbors (and boundaries) of 'value' are always computed for double-precision
7484// numbers, all float's can be recovered using strtod (and strtof). However, the resulting
7485// decimal representations are not exactly "short".
7486//
7487// The documentation for 'std::to_chars' (http://en.cppreference.com/w/cpp/utility/to_chars)
7488// says "value is converted to a string as if by std::sprintf in the default ("C") locale"
7489// and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
7490// does.
7491// On the other hand, the documentation for 'std::to_chars' requires that "parsing the
7492// representation using the corresponding std::from_chars function recovers value exactly". That
7493// indicates that single precision floating-point numbers should be recovered using
7494// 'std::strtof'.
7495//
7496// NB: If the neighbors are computed for single-precision numbers, there is a single float
7497// (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
7498// value is off by 1 ulp.
7499#if 0
7500 const boundaries w = compute_boundaries(static_cast<double>(value));
7501#else
7502 const boundaries w = compute_boundaries(value);
7503#endif
7504
7505 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
7506}
7507
7513inline char* append_exponent(char* buf, int e)
7514{
7515 assert(e > -1000);
7516 assert(e < 1000);
7517
7518 if (e < 0) {
7519 e = -e;
7520 *buf++ = '-';
7521 } else {
7522 *buf++ = '+';
7523 }
7524
7525 uint32_t k = static_cast<uint32_t>(e);
7526 if (k < 10) {
7527 // Always print at least two digits in the exponent.
7528 // This is for compatibility with printf("%g").
7529 *buf++ = '0';
7530 *buf++ = static_cast<char>('0' + k);
7531 } else if (k < 100) {
7532 *buf++ = static_cast<char>('0' + k / 10);
7533 k %= 10;
7534 *buf++ = static_cast<char>('0' + k);
7535 } else {
7536 *buf++ = static_cast<char>('0' + k / 100);
7537 k %= 100;
7538 *buf++ = static_cast<char>('0' + k / 10);
7539 k %= 10;
7540 *buf++ = static_cast<char>('0' + k);
7541 }
7542
7543 return buf;
7544}
7545
7555inline char* format_buffer(char* buf, int len, int decimal_exponent,
7556 int min_exp, int max_exp)
7557{
7558 assert(min_exp < 0);
7559 assert(max_exp > 0);
7560
7561 const int k = len;
7562 const int n = len + decimal_exponent;
7563
7564 // v = buf * 10^(n-k)
7565 // k is the length of the buffer (number of decimal digits)
7566 // n is the position of the decimal point relative to the start of the buffer.
7567
7568 if (k <= n and n <= max_exp) {
7569 // digits[000]
7570 // len <= max_exp + 2
7571
7572 std::memset(buf + k, '0', static_cast<size_t>(n - k));
7573 // Make it look like a floating-point number (#362, #378)
7574 buf[n + 0] = '.';
7575 buf[n + 1] = '0';
7576 return buf + (n + 2);
7577 }
7578
7579 if (0 < n and n <= max_exp) {
7580 // dig.its
7581 // len <= max_digits10 + 1
7582
7583 assert(k > n);
7584
7585 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
7586 buf[n] = '.';
7587 return buf + (k + 1);
7588 }
7589
7590 if (min_exp < n and n <= 0) {
7591 // 0.[000]digits
7592 // len <= 2 + (-min_exp - 1) + max_digits10
7593
7594 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
7595 buf[0] = '0';
7596 buf[1] = '.';
7597 std::memset(buf + 2, '0', static_cast<size_t>(-n));
7598 return buf + (2 + (-n) + k);
7599 }
7600
7601 if (k == 1) {
7602 // dE+123
7603 // len <= 1 + 5
7604
7605 buf += 1;
7606 } else {
7607 // d.igitsE+123
7608 // len <= max_digits10 + 1 + 5
7609
7610 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
7611 buf[1] = '.';
7612 buf += 1 + k;
7613 }
7614
7615 *buf++ = 'e';
7616 return append_exponent(buf, n - 1);
7617}
7618
7619} // namespace dtoa_impl
7620
7631template <typename FloatType>
7632char* to_chars(char* first, char* last, FloatType value)
7633{
7634 static_cast<void>(last); // maybe unused - fix warning
7635 assert(std::isfinite(value));
7636
7637 // Use signbit(value) instead of (value < 0) since signbit works for -0.
7638 if (std::signbit(value)) {
7639 value = -value;
7640 *first++ = '-';
7641 }
7642
7643 if (value == 0) // +-0
7644 {
7645 *first++ = '0';
7646 // Make it look like a floating-point number (#362, #378)
7647 *first++ = '.';
7648 *first++ = '0';
7649 return first;
7650 }
7651
7652 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
7653
7654 // Compute v = buffer * 10^decimal_exponent.
7655 // The decimal digits are stored in the buffer, which needs to be interpreted
7656 // as an unsigned decimal integer.
7657 // len is the length of the buffer, i.e. the number of decimal digits.
7658 int len = 0;
7659 int decimal_exponent = 0;
7660 dtoa_impl::grisu2(first, len, decimal_exponent, value);
7661
7662 assert(len <= std::numeric_limits<FloatType>::max_digits10);
7663
7664 // Format the buffer like printf("%.*g", prec, value)
7665 constexpr int kMinExp = -4;
7666 // Use digits10 here to increase compatibility with version 2.
7667 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
7668
7669 assert(last - first >= kMaxExp + 2);
7670 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
7671 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
7672
7673 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
7674}
7675
7676} // namespace detail
7677} // namespace nlohmann
7678
7679// #include <nlohmann/detail/macro_scope.hpp>
7680
7681// #include <nlohmann/detail/meta.hpp>
7682
7683// #include <nlohmann/detail/output/output_adapters.hpp>
7684
7685// #include <nlohmann/detail/value_t.hpp>
7686
7687namespace nlohmann
7688{
7689namespace detail
7690{
7692// serialization //
7694
7695template <typename BasicJsonType>
7696class serializer
7697{
7698 using string_t = typename BasicJsonType::string_t;
7699 using number_float_t = typename BasicJsonType::number_float_t;
7700 using number_integer_t = typename BasicJsonType::number_integer_t;
7701 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7702 static constexpr uint8_t UTF8_ACCEPT = 0;
7703 static constexpr uint8_t UTF8_REJECT = 1;
7704
7705 public:
7710 serializer(output_adapter_t<char> s, const char ichar)
7711 : o(std::move(s)), loc(std::localeconv()), thousands_sep(loc->thousands_sep == nullptr ? '\0' : *(loc->thousands_sep)), decimal_point(loc->decimal_point == nullptr ? '\0' : *(loc->decimal_point)), indent_char(ichar), indent_string(512, indent_char)
7712 {
7713 }
7714
7715 // delete because of pointer members
7716 serializer(const serializer&) = delete;
7717 serializer& operator=(const serializer&) = delete;
7718
7736 void dump(const BasicJsonType& val, const bool pretty_print,
7737 const bool ensure_ascii,
7738 const unsigned int indent_step,
7739 const unsigned int current_indent = 0)
7740 {
7741 switch (val.m_type) {
7742 case value_t::object: {
7743 if (val.m_value.object->empty()) {
7744 o->write_characters("{}", 2);
7745 return;
7746 }
7747
7748 if (pretty_print) {
7749 o->write_characters("{\n", 2);
7750
7751 // variable to hold indentation for recursive calls
7752 const auto new_indent = current_indent + indent_step;
7753 if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
7754 indent_string.resize(indent_string.size() * 2, ' ');
7755 }
7756
7757 // first n-1 elements
7758 auto i = val.m_value.object->cbegin();
7759 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
7760 o->write_characters(indent_string.c_str(), new_indent);
7761 o->write_character('\"');
7762 dump_escaped(i->first, ensure_ascii);
7763 o->write_characters(R"(": )", 3);
7764 dump(i->second, true, ensure_ascii, indent_step, new_indent);
7765 o->write_characters(",\n", 2);
7766 }
7767
7768 // last element
7769 assert(i != val.m_value.object->cend());
7770 assert(std::next(i) == val.m_value.object->cend());
7771 o->write_characters(indent_string.c_str(), new_indent);
7772 o->write_character('\"');
7773 dump_escaped(i->first, ensure_ascii);
7774 o->write_characters(R"(": )", 3);
7775 dump(i->second, true, ensure_ascii, indent_step, new_indent);
7776
7777 o->write_character('\n');
7778 o->write_characters(indent_string.c_str(), current_indent);
7779 o->write_character('}');
7780 } else {
7781 o->write_character('{');
7782
7783 // first n-1 elements
7784 auto i = val.m_value.object->cbegin();
7785 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
7786 o->write_character('\"');
7787 dump_escaped(i->first, ensure_ascii);
7788 o->write_characters(R"(":)", 2);
7789 dump(i->second, false, ensure_ascii, indent_step, current_indent);
7790 o->write_character(',');
7791 }
7792
7793 // last element
7794 assert(i != val.m_value.object->cend());
7795 assert(std::next(i) == val.m_value.object->cend());
7796 o->write_character('\"');
7797 dump_escaped(i->first, ensure_ascii);
7798 o->write_characters(R"(":)", 2);
7799 dump(i->second, false, ensure_ascii, indent_step, current_indent);
7800
7801 o->write_character('}');
7802 }
7803
7804 return;
7805 }
7806
7807 case value_t::array: {
7808 if (val.m_value.array->empty()) {
7809 o->write_characters("[]", 2);
7810 return;
7811 }
7812
7813 if (pretty_print) {
7814 o->write_characters("[\n", 2);
7815
7816 // variable to hold indentation for recursive calls
7817 const auto new_indent = current_indent + indent_step;
7818 if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
7819 indent_string.resize(indent_string.size() * 2, ' ');
7820 }
7821
7822 // first n-1 elements
7823 for (auto i = val.m_value.array->cbegin();
7824 i != val.m_value.array->cend() - 1; ++i) {
7825 o->write_characters(indent_string.c_str(), new_indent);
7826 dump(*i, true, ensure_ascii, indent_step, new_indent);
7827 o->write_characters(",\n", 2);
7828 }
7829
7830 // last element
7831 assert(not val.m_value.array->empty());
7832 o->write_characters(indent_string.c_str(), new_indent);
7833 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
7834
7835 o->write_character('\n');
7836 o->write_characters(indent_string.c_str(), current_indent);
7837 o->write_character(']');
7838 } else {
7839 o->write_character('[');
7840
7841 // first n-1 elements
7842 for (auto i = val.m_value.array->cbegin();
7843 i != val.m_value.array->cend() - 1; ++i) {
7844 dump(*i, false, ensure_ascii, indent_step, current_indent);
7845 o->write_character(',');
7846 }
7847
7848 // last element
7849 assert(not val.m_value.array->empty());
7850 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
7851
7852 o->write_character(']');
7853 }
7854
7855 return;
7856 }
7857
7858 case value_t::string: {
7859 o->write_character('\"');
7860 dump_escaped(*val.m_value.string, ensure_ascii);
7861 o->write_character('\"');
7862 return;
7863 }
7864
7865 case value_t::boolean: {
7866 if (val.m_value.boolean) {
7867 o->write_characters("true", 4);
7868 } else {
7869 o->write_characters("false", 5);
7870 }
7871 return;
7872 }
7873
7874 case value_t::number_integer: {
7875 dump_integer(val.m_value.number_integer);
7876 return;
7877 }
7878
7879 case value_t::number_unsigned: {
7880 dump_integer(val.m_value.number_unsigned);
7881 return;
7882 }
7883
7884 case value_t::number_float: {
7885 dump_float(val.m_value.number_float);
7886 return;
7887 }
7888
7889 case value_t::discarded: {
7890 o->write_characters("<discarded>", 11);
7891 return;
7892 }
7893
7894 case value_t::null: {
7895 o->write_characters("null", 4);
7896 return;
7897 }
7898 }
7899 }
7900
7901 private:
7916 void dump_escaped(const string_t& s, const bool ensure_ascii)
7917 {
7918 uint32_t codepoint;
7919 uint8_t state = UTF8_ACCEPT;
7920 std::size_t bytes = 0; // number of bytes written to string_buffer
7921
7922 for (std::size_t i = 0; i < s.size(); ++i) {
7923 const auto byte = static_cast<uint8_t>(s[i]);
7924
7925 switch (decode(state, codepoint, byte)) {
7926 case UTF8_ACCEPT: // decode found a new code point
7927 {
7928 switch (codepoint) {
7929 case 0x08: // backspace
7930 {
7931 string_buffer[bytes++] = '\\';
7932 string_buffer[bytes++] = 'b';
7933 break;
7934 }
7935
7936 case 0x09: // horizontal tab
7937 {
7938 string_buffer[bytes++] = '\\';
7939 string_buffer[bytes++] = 't';
7940 break;
7941 }
7942
7943 case 0x0A: // newline
7944 {
7945 string_buffer[bytes++] = '\\';
7946 string_buffer[bytes++] = 'n';
7947 break;
7948 }
7949
7950 case 0x0C: // formfeed
7951 {
7952 string_buffer[bytes++] = '\\';
7953 string_buffer[bytes++] = 'f';
7954 break;
7955 }
7956
7957 case 0x0D: // carriage return
7958 {
7959 string_buffer[bytes++] = '\\';
7960 string_buffer[bytes++] = 'r';
7961 break;
7962 }
7963
7964 case 0x22: // quotation mark
7965 {
7966 string_buffer[bytes++] = '\\';
7967 string_buffer[bytes++] = '\"';
7968 break;
7969 }
7970
7971 case 0x5C: // reverse solidus
7972 {
7973 string_buffer[bytes++] = '\\';
7974 string_buffer[bytes++] = '\\';
7975 break;
7976 }
7977
7978 default: {
7979 // escape control characters (0x00..0x1F) or, if
7980 // ensure_ascii parameter is used, non-ASCII characters
7981 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
7982 if (codepoint <= 0xFFFF) {
7983 std::snprintf(string_buffer.data() + bytes, 7, R"(\u%04x)",
7984 static_cast<uint16_t>(codepoint));
7985 bytes += 6;
7986 } else {
7987 std::snprintf(string_buffer.data() + bytes, 13, R"(\u%04x\u%04x)",
7988 static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
7989 static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
7990 bytes += 12;
7991 }
7992 } else {
7993 // copy byte to buffer (all previous bytes
7994 // been copied have in default case above)
7995 string_buffer[bytes++] = s[i];
7996 }
7997 break;
7998 }
7999 }
8000
8001 // write buffer and reset index; there must be 13 bytes
8002 // left, as this is the maximal number of bytes to be
8003 // written ("\uxxxx\uxxxx\0") for one code point
8004 if (string_buffer.size() - bytes < 13) {
8005 o->write_characters(string_buffer.data(), bytes);
8006 bytes = 0;
8007 }
8008 break;
8009 }
8010
8011 case UTF8_REJECT: // decode found invalid UTF-8 byte
8012 {
8013 std::stringstream ss;
8014 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
8015 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str()));
8016 }
8017
8018 default: // decode found yet incomplete multi-byte code point
8019 {
8020 if (not ensure_ascii) {
8021 // code point will not be escaped - copy byte to buffer
8022 string_buffer[bytes++] = s[i];
8023 }
8024 break;
8025 }
8026 }
8027 }
8028
8029 if (JSON_LIKELY(state == UTF8_ACCEPT)) {
8030 // write buffer
8031 if (bytes > 0) {
8032 o->write_characters(string_buffer.data(), bytes);
8033 }
8034 } else {
8035 // we finish reading, but do not accept: string was incomplete
8036 std::stringstream ss;
8037 ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(static_cast<uint8_t>(s.back()));
8038 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str()));
8039 }
8040 }
8041
8051 template <typename NumberType, detail::enable_if_t<
8052 std::is_same<NumberType, number_unsigned_t>::value or
8053 std::is_same<NumberType, number_integer_t>::value,
8054 int> = 0>
8055 void dump_integer(NumberType x)
8056 {
8057 // special case for "0"
8058 if (x == 0) {
8059 o->write_character('0');
8060 return;
8061 }
8062
8063 const bool is_negative = (x <= 0) and (x != 0); // see issue #755
8064 std::size_t i = 0;
8065
8066 while (x != 0) {
8067 // spare 1 byte for '\0'
8068 assert(i < number_buffer.size() - 1);
8069
8070 const auto digit = std::labs(static_cast<long>(x % 10));
8071 number_buffer[i++] = static_cast<char>('0' + digit);
8072 x /= 10;
8073 }
8074
8075 if (is_negative) {
8076 // make sure there is capacity for the '-'
8077 assert(i < number_buffer.size() - 2);
8078 number_buffer[i++] = '-';
8079 }
8080
8081 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8082 o->write_characters(number_buffer.data(), i);
8083 }
8084
8093 void dump_float(number_float_t x)
8094 {
8095 // NaN / inf
8096 if (not std::isfinite(x)) {
8097 o->write_characters("null", 4);
8098 return;
8099 }
8100
8101 // If number_float_t is an IEEE-754 single or double precision number,
8102 // use the Grisu2 algorithm to produce short numbers which are
8103 // guaranteed to round-trip, using strtof and strtod, resp.
8104 //
8105 // NB: The test below works if <long double> == <double>.
8106 static constexpr bool is_ieee_single_or_double = (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
8107 (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);
8108
8109 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
8110 }
8111
8112 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
8113 {
8114 char* begin = number_buffer.data();
8115 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
8116
8117 o->write_characters(begin, static_cast<size_t>(end - begin));
8118 }
8119
8120 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
8121 {
8122 // get number of digits for a float -> text -> float round-trip
8123 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
8124
8125 // the actual conversion
8126 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
8127
8128 // negative value indicates an error
8129 assert(len > 0);
8130 // check if buffer was large enough
8131 assert(static_cast<std::size_t>(len) < number_buffer.size());
8132
8133 // erase thousands separator
8134 if (thousands_sep != '\0') {
8135 const auto end = std::remove(number_buffer.begin(),
8136 number_buffer.begin() + len, thousands_sep);
8137 std::fill(end, number_buffer.end(), '\0');
8138 assert((end - number_buffer.begin()) <= len);
8139 len = (end - number_buffer.begin());
8140 }
8141
8142 // convert decimal point to '.'
8143 if (decimal_point != '\0' and decimal_point != '.') {
8144 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8145 if (dec_pos != number_buffer.end()) {
8146 *dec_pos = '.';
8147 }
8148 }
8149
8150 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
8151
8152 // determine if need to append ".0"
8153 const bool value_is_int_like =
8154 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8155 [](char c) {
8156 return (c == '.' or c == 'e');
8157 });
8158
8159 if (value_is_int_like) {
8160 o->write_characters(".0", 2);
8161 }
8162 }
8163
8185 static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
8186 {
8187 static const std::array<uint8_t, 400> utf8d =
8188 {
8189 {
8190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
8191 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
8192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
8193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
8194 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
8195 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
8196 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
8197 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
8198 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
8199 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
8200 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
8201 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
8202 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
8203 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
8204 }};
8205
8206 const uint8_t type = utf8d[byte];
8207
8208 codep = (state != UTF8_ACCEPT)
8209 ? (byte & 0x3fu) | (codep << 6)
8210 : static_cast<uint32_t>(0xff >> type) & (byte);
8211
8212 state = utf8d[256u + state * 16u + type];
8213 return state;
8214 }
8215
8216 private:
8218 output_adapter_t<char> o = nullptr;
8219
8221 std::array<char, 64> number_buffer{{}};
8222
8224 const std::lconv* loc = nullptr;
8226 const char thousands_sep = '\0';
8228 const char decimal_point = '\0';
8229
8231 std::array<char, 512> string_buffer{{}};
8232
8234 const char indent_char;
8236 string_t indent_string;
8237};
8238} // namespace detail
8239} // namespace nlohmann
8240
8241// #include <nlohmann/detail/json_ref.hpp>
8242
8243#include <initializer_list>
8244#include <utility>
8245
8246namespace nlohmann
8247{
8248namespace detail
8249{
8250template <typename BasicJsonType>
8251class json_ref
8252{
8253 public:
8254 using value_type = BasicJsonType;
8255
8256 json_ref(value_type&& value)
8257 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
8258 {
8259 }
8260
8261 json_ref(const value_type& value)
8262 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
8263 {
8264 }
8265
8266 json_ref(std::initializer_list<json_ref> init)
8267 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
8268 {
8269 }
8270
8271 template <class... Args>
8272 json_ref(Args&&... args)
8273 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
8274 {
8275 }
8276
8277 // class should be movable only
8278 json_ref(json_ref&&) = default;
8279 json_ref(const json_ref&) = delete;
8280 json_ref& operator=(const json_ref&) = delete;
8281
8282 value_type moved_or_copied() const
8283 {
8284 if (is_rvalue) {
8285 return std::move(*value_ref);
8286 }
8287 return *value_ref;
8288 }
8289
8290 value_type const& operator*() const
8291 {
8292 return *static_cast<value_type const*>(value_ref);
8293 }
8294
8295 value_type const* operator->() const
8296 {
8297 return static_cast<value_type const*>(value_ref);
8298 }
8299
8300 private:
8301 mutable value_type owned_value = nullptr;
8302 value_type* value_ref = nullptr;
8303 const bool is_rvalue;
8304};
8305} // namespace detail
8306} // namespace nlohmann
8307
8308// #include <nlohmann/detail/json_pointer.hpp>
8309
8310#include <cassert> // assert
8311#include <numeric> // accumulate
8312#include <string> // string
8313#include <vector> // vector
8314
8315// #include <nlohmann/detail/macro_scope.hpp>
8316
8317// #include <nlohmann/detail/exceptions.hpp>
8318
8319// #include <nlohmann/detail/value_t.hpp>
8320
8321namespace nlohmann
8322{
8323template <typename BasicJsonType>
8324class json_pointer
8325{
8326 // allow basic_json to access private members
8328 friend class basic_json;
8329
8330 public:
8352 explicit json_pointer(const std::string& s = "")
8353 : reference_tokens(split(s))
8354 {
8355 }
8356
8372 std::string to_string() const noexcept
8373 {
8374 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8375 std::string{},
8376 [](const std::string& a, const std::string& b) {
8377 return a + "/" + escape(b);
8378 });
8379 }
8380
8382 operator std::string() const
8383 {
8384 return to_string();
8385 }
8386
8394 static int array_index(const std::string& s)
8395 {
8396 std::size_t processed_chars = 0;
8397 const int res = std::stoi(s, &processed_chars);
8398
8399 // check if the string was completely read
8400 if (JSON_UNLIKELY(processed_chars != s.size())) {
8401 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
8402 }
8403
8404 return res;
8405 }
8406
8407 private:
8412 std::string pop_back()
8413 {
8414 if (JSON_UNLIKELY(is_root())) {
8415 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8416 }
8417
8418 auto last = reference_tokens.back();
8419 reference_tokens.pop_back();
8420 return last;
8421 }
8422
8424 bool is_root() const
8425 {
8426 return reference_tokens.empty();
8427 }
8428
8429 json_pointer top() const
8430 {
8431 if (JSON_UNLIKELY(is_root())) {
8432 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8433 }
8434
8435 json_pointer result = *this;
8436 result.reference_tokens = {reference_tokens[0]};
8437 return result;
8438 }
8439
8448 BasicJsonType& get_and_create(BasicJsonType& j) const
8449 {
8450 using size_type = typename BasicJsonType::size_type;
8451 auto result = &j;
8452
8453 // in case no reference tokens exist, return a reference to the JSON value
8454 // j which will be overwritten by a primitive value
8455 for (const auto& reference_token : reference_tokens) {
8456 switch (result->m_type) {
8457 case detail::value_t::null: {
8458 if (reference_token == "0") {
8459 // start a new array if reference token is 0
8460 result = &result->operator[](0);
8461 } else {
8462 // start a new object otherwise
8463 result = &result->operator[](reference_token);
8464 }
8465 break;
8466 }
8467
8468 case detail::value_t::object: {
8469 // create an entry in the object
8470 result = &result->operator[](reference_token);
8471 break;
8472 }
8473
8474 case detail::value_t::array: {
8475 // create an entry in the array
8476 JSON_TRY
8477 {
8478 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
8479 }
8480 JSON_CATCH(std::invalid_argument&)
8481 {
8482 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8483 }
8484 break;
8485 }
8486
8487 /*
8488 The following code is only reached if there exists a reference
8489 token _and_ the current value is primitive. In this case, we have
8490 an error situation, because primitive values may only occur as
8491 single value; that is, with an empty list of reference tokens.
8492 */
8493 default:
8494 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
8495 }
8496 }
8497
8498 return *result;
8499 }
8500
8520 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
8521 {
8522 using size_type = typename BasicJsonType::size_type;
8523 for (const auto& reference_token : reference_tokens) {
8524 // convert null values to arrays or objects before continuing
8525 if (ptr->m_type == detail::value_t::null) {
8526 // check if reference token is a number
8527 const bool nums =
8528 std::all_of(reference_token.begin(), reference_token.end(),
8529 [](const char x) {
8530 return (x >= '0' and x <= '9');
8531 });
8532
8533 // change value to array for numbers or "-" or to object otherwise
8534 *ptr = (nums or reference_token == "-")
8535 ? detail::value_t::array
8536 : detail::value_t::object;
8537 }
8538
8539 switch (ptr->m_type) {
8540 case detail::value_t::object: {
8541 // use unchecked object access
8542 ptr = &ptr->operator[](reference_token);
8543 break;
8544 }
8545
8546 case detail::value_t::array: {
8547 // error condition (cf. RFC 6901, Sect. 4)
8548 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8550 "array index '" + reference_token +
8551 "' must not begin with '0'"));
8552 }
8553
8554 if (reference_token == "-") {
8555 // explicitly treat "-" as index beyond the end
8556 ptr = &ptr->operator[](ptr->m_value.array->size());
8557 } else {
8558 // convert array index to number; unchecked access
8559 JSON_TRY
8560 {
8561 ptr = &ptr->operator[](
8562 static_cast<size_type>(array_index(reference_token)));
8563 }
8564 JSON_CATCH(std::invalid_argument&)
8565 {
8566 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8567 }
8568 }
8569 break;
8570 }
8571
8572 default:
8573 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8574 }
8575 }
8576
8577 return *ptr;
8578 }
8579
8586 BasicJsonType& get_checked(BasicJsonType* ptr) const
8587 {
8588 using size_type = typename BasicJsonType::size_type;
8589 for (const auto& reference_token : reference_tokens) {
8590 switch (ptr->m_type) {
8591 case detail::value_t::object: {
8592 // note: at performs range check
8593 ptr = &ptr->at(reference_token);
8594 break;
8595 }
8596
8597 case detail::value_t::array: {
8598 if (JSON_UNLIKELY(reference_token == "-")) {
8599 // "-" always fails the range check
8601 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8602 ") is out of range"));
8603 }
8604
8605 // error condition (cf. RFC 6901, Sect. 4)
8606 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8608 "array index '" + reference_token +
8609 "' must not begin with '0'"));
8610 }
8611
8612 // note: at performs range check
8613 JSON_TRY
8614 {
8615 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8616 }
8617 JSON_CATCH(std::invalid_argument&)
8618 {
8619 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8620 }
8621 break;
8622 }
8623
8624 default:
8625 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8626 }
8627 }
8628
8629 return *ptr;
8630 }
8631
8645 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
8646 {
8647 using size_type = typename BasicJsonType::size_type;
8648 for (const auto& reference_token : reference_tokens) {
8649 switch (ptr->m_type) {
8650 case detail::value_t::object: {
8651 // use unchecked object access
8652 ptr = &ptr->operator[](reference_token);
8653 break;
8654 }
8655
8656 case detail::value_t::array: {
8657 if (JSON_UNLIKELY(reference_token == "-")) {
8658 // "-" cannot be used for const access
8660 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8661 ") is out of range"));
8662 }
8663
8664 // error condition (cf. RFC 6901, Sect. 4)
8665 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8667 "array index '" + reference_token +
8668 "' must not begin with '0'"));
8669 }
8670
8671 // use unchecked array access
8672 JSON_TRY
8673 {
8674 ptr = &ptr->operator[](
8675 static_cast<size_type>(array_index(reference_token)));
8676 }
8677 JSON_CATCH(std::invalid_argument&)
8678 {
8679 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8680 }
8681 break;
8682 }
8683
8684 default:
8685 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8686 }
8687 }
8688
8689 return *ptr;
8690 }
8691
8698 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
8699 {
8700 using size_type = typename BasicJsonType::size_type;
8701 for (const auto& reference_token : reference_tokens) {
8702 switch (ptr->m_type) {
8703 case detail::value_t::object: {
8704 // note: at performs range check
8705 ptr = &ptr->at(reference_token);
8706 break;
8707 }
8708
8709 case detail::value_t::array: {
8710 if (JSON_UNLIKELY(reference_token == "-")) {
8711 // "-" always fails the range check
8713 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8714 ") is out of range"));
8715 }
8716
8717 // error condition (cf. RFC 6901, Sect. 4)
8718 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8720 "array index '" + reference_token +
8721 "' must not begin with '0'"));
8722 }
8723
8724 // note: at performs range check
8725 JSON_TRY
8726 {
8727 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8728 }
8729 JSON_CATCH(std::invalid_argument&)
8730 {
8731 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8732 }
8733 break;
8734 }
8735
8736 default:
8737 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8738 }
8739 }
8740
8741 return *ptr;
8742 }
8743
8753 static std::vector<std::string> split(const std::string& reference_string)
8754 {
8755 std::vector<std::string> result;
8756
8757 // special case: empty reference string -> no reference tokens
8758 if (reference_string.empty()) {
8759 return result;
8760 }
8761
8762 // check if nonempty reference string begins with slash
8763 if (JSON_UNLIKELY(reference_string[0] != '/')) {
8765 "JSON pointer must be empty or begin with '/' - was: '" +
8766 reference_string + "'"));
8767 }
8768
8769 // extract the reference tokens:
8770 // - slash: position of the last read slash (or end of string)
8771 // - start: position after the previous slash
8772 for (
8773 // search for the first slash after the first character
8774 std::size_t slash = reference_string.find_first_of('/', 1),
8775 // set the beginning of the first reference token
8776 start = 1;
8777 // we can stop if start == string::npos+1 = 0
8778 start != 0;
8779 // set the beginning of the next reference token
8780 // (will eventually be 0 if slash == std::string::npos)
8781 start = slash + 1,
8782 // find next slash
8783 slash = reference_string.find_first_of('/', start)) {
8784 // use the text between the beginning of the reference token
8785 // (start) and the last slash (slash).
8786 auto reference_token = reference_string.substr(start, slash - start);
8787
8788 // check reference tokens are properly escaped
8789 for (std::size_t pos = reference_token.find_first_of('~');
8790 pos != std::string::npos;
8791 pos = reference_token.find_first_of('~', pos + 1)) {
8792 assert(reference_token[pos] == '~');
8793
8794 // ~ must be followed by 0 or 1
8795 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
8796 (reference_token[pos + 1] != '0' and
8797 reference_token[pos + 1] != '1'))) {
8798 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
8799 }
8800 }
8801
8802 // finally, store the reference token
8803 unescape(reference_token);
8804 result.push_back(reference_token);
8805 }
8806
8807 return result;
8808 }
8809
8823 static void replace_substring(std::string& s, const std::string& f,
8824 const std::string& t)
8825 {
8826 assert(not f.empty());
8827 for (auto pos = s.find(f); // find first occurrence of f
8828 pos != std::string::npos; // make sure f was found
8829 s.replace(pos, f.size(), t), // replace with t, and
8830 pos = s.find(f, pos + t.size())) // find next occurrence of f
8831 {
8832 }
8833 }
8834
8836 static std::string escape(std::string s)
8837 {
8838 replace_substring(s, "~", "~0");
8839 replace_substring(s, "/", "~1");
8840 return s;
8841 }
8842
8844 static void unescape(std::string& s)
8845 {
8846 replace_substring(s, "~1", "/");
8847 replace_substring(s, "~0", "~");
8848 }
8849
8857 static void flatten(const std::string& reference_string,
8858 const BasicJsonType& value,
8859 BasicJsonType& result)
8860 {
8861 switch (value.m_type) {
8862 case detail::value_t::array: {
8863 if (value.m_value.array->empty()) {
8864 // flatten empty array as null
8865 result[reference_string] = nullptr;
8866 } else {
8867 // iterate array and use index as reference string
8868 for (std::size_t i = 0; i < value.m_value.array->size(); ++i) {
8869 flatten(reference_string + "/" + std::to_string(i),
8870 value.m_value.array->operator[](i), result);
8871 }
8872 }
8873 break;
8874 }
8875
8876 case detail::value_t::object: {
8877 if (value.m_value.object->empty()) {
8878 // flatten empty object as null
8879 result[reference_string] = nullptr;
8880 } else {
8881 // iterate object and use keys as reference string
8882 for (const auto& element : *value.m_value.object) {
8883 flatten(reference_string + "/" + escape(element.first), element.second, result);
8884 }
8885 }
8886 break;
8887 }
8888
8889 default: {
8890 // add primitive value with its reference string
8891 result[reference_string] = value;
8892 break;
8893 }
8894 }
8895 }
8896
8907 static BasicJsonType
8908 unflatten(const BasicJsonType& value)
8909 {
8910 if (JSON_UNLIKELY(not value.is_object())) {
8911 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
8912 }
8913
8914 BasicJsonType result;
8915
8916 // iterate the JSON object values
8917 for (const auto& element : *value.m_value.object) {
8918 if (JSON_UNLIKELY(not element.second.is_primitive())) {
8919 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
8920 }
8921
8922 // assign value to reference pointed to by JSON pointer; Note that if
8923 // the JSON pointer is "" (i.e., points to the whole value), function
8924 // get_and_create returns a reference to result itself. An assignment
8925 // will then create a primitive value.
8926 json_pointer(element.first).get_and_create(result) = element.second;
8927 }
8928
8929 return result;
8930 }
8931
8932 friend bool operator==(json_pointer const& lhs,
8933 json_pointer const& rhs) noexcept
8934 {
8935 return (lhs.reference_tokens == rhs.reference_tokens);
8936 }
8937
8938 friend bool operator!=(json_pointer const& lhs,
8939 json_pointer const& rhs) noexcept
8940 {
8941 return not(lhs == rhs);
8942 }
8943
8945 std::vector<std::string> reference_tokens;
8946};
8947} // namespace nlohmann
8948
8949// #include <nlohmann/adl_serializer.hpp>
8950
8951#include <utility>
8952
8953// #include <nlohmann/detail/conversions/from_json.hpp>
8954
8955// #include <nlohmann/detail/conversions/to_json.hpp>
8956
8957namespace nlohmann
8958{
8959template <typename, typename>
8960struct adl_serializer {
8970 template <typename BasicJsonType, typename ValueType>
8971 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
8972 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
8973 {
8974 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
8975 }
8976
8986 template <typename BasicJsonType, typename ValueType>
8987 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
8988 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
8989 {
8990 ::nlohmann::to_json(j, std::forward<ValueType>(val));
8991 }
8992};
8993} // namespace nlohmann
8994
9000namespace nlohmann
9001{
9002
9085class basic_json
9086{
9087 private:
9088 template <detail::value_t>
9089 friend struct detail::external_constructor;
9090 friend ::nlohmann::json_pointer<basic_json>;
9091 friend ::nlohmann::detail::parser<basic_json>;
9092 friend ::nlohmann::detail::serializer<basic_json>;
9093 template <typename BasicJsonType>
9094 friend class ::nlohmann::detail::iter_impl;
9095 template <typename BasicJsonType, typename CharType>
9096 friend class ::nlohmann::detail::binary_writer;
9097 template <typename BasicJsonType>
9098 friend class ::nlohmann::detail::binary_reader;
9099
9101 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
9102
9103 // convenience aliases for types residing in namespace detail;
9104 using lexer = ::nlohmann::detail::lexer<basic_json>;
9106
9107 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
9108 template <typename BasicJsonType>
9110 template <typename BasicJsonType>
9112 template <typename Iterator>
9113 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
9114 template <typename Base>
9115 using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
9116
9117 template <typename CharType>
9119
9120 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
9121 template <typename CharType>
9122 using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
9123
9124 using serializer = ::nlohmann::detail::serializer<basic_json>;
9125
9126 public:
9127 using value_t = detail::value_t;
9129 using json_pointer = ::nlohmann::json_pointer<basic_json>;
9130 template <typename T, typename SFINAE>
9131 using json_serializer = JSONSerializer<T, SFINAE>;
9133 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
9134
9136 // exceptions //
9138
9142
9144 using exception = detail::exception;
9146 using parse_error = detail::parse_error;
9148 using invalid_iterator = detail::invalid_iterator;
9150 using type_error = detail::type_error;
9152 using out_of_range = detail::out_of_range;
9154 using other_error = detail::other_error;
9155
9157
9159 // container types //
9161
9166
9168 using value_type = basic_json;
9169
9171 using reference = value_type&;
9173 using const_reference = const value_type&;
9174
9176 using difference_type = std::ptrdiff_t;
9178 using size_type = std::size_t;
9179
9181 using allocator_type = AllocatorType<basic_json>;
9182
9184 using pointer = typename std::allocator_traits<allocator_type>::pointer;
9186 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
9187
9189 using iterator = iter_impl<basic_json>;
9191 using const_iterator = iter_impl<const basic_json>;
9193 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
9195 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
9196
9198
9202 static allocator_type get_allocator()
9203 {
9204 return allocator_type();
9205 }
9206
9233 static basic_json meta()
9234 {
9235 basic_json result;
9236
9237 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
9238 result["name"] = "JSON for Modern C++";
9239 result["url"] = "https://github.com/nlohmann/json";
9240 result["version"]["string"] =
9244 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
9245 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
9246 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
9247
9248#ifdef _WIN32
9249 result["platform"] = "win32";
9250#elif defined __linux__
9251 result["platform"] = "linux";
9252#elif defined __APPLE__
9253 result["platform"] = "apple";
9254#elif defined __unix__
9255 result["platform"] = "unix";
9256#else
9257 result["platform"] = "unknown";
9258#endif
9259
9260#if defined(__ICC) || defined(__INTEL_COMPILER)
9261 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
9262#elif defined(__clang__)
9263 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
9264#elif defined(__GNUC__) || defined(__GNUG__)
9265 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
9266#elif defined(__HP_cc) || defined(__HP_aCC)
9267 result["compiler"] = "hp"
9268#elif defined(__IBMCPP__)
9269 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
9270#elif defined(_MSC_VER)
9271 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
9272#elif defined(__PGI)
9273 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
9274#elif defined(__SUNPRO_CC)
9275 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
9276#else
9277 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
9278#endif
9279
9280#ifdef __cplusplus
9281 result["compiler"]["c++"] = std::to_string(__cplusplus);
9282#else
9283 result["compiler"]["c++"] = "unknown";
9284#endif
9285 return result;
9286 }
9287
9289 // JSON value data types //
9291
9296
9297#if defined(JSON_HAS_CPP_14)
9298 // Use transparent comparator if possible, combined with perfect forwarding
9299 // on find() and count() calls prevents unnecessary string construction.
9300 using object_comparator_t = std::less<>;
9301#else
9302 using object_comparator_t = std::less<StringType>;
9303#endif
9304
9388 using object_t = ObjectType<StringType,
9389 basic_json,
9390 object_comparator_t,
9391 AllocatorType<std::pair<const StringType,
9392 basic_json>>>;
9393
9438 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
9439
9491 using string_t = StringType;
9492
9517 using boolean_t = BooleanType;
9518
9589 using number_integer_t = NumberIntegerType;
9590
9660 using number_unsigned_t = NumberUnsignedType;
9661
9728 using number_float_t = NumberFloatType;
9729
9731
9732 private:
9734 template <typename T, typename... Args>
9735 static T* create(Args&&... args)
9736 {
9737 AllocatorType<T> alloc;
9738 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
9739
9740 auto deleter = [&](T* object) {
9741 AllocatorTraits::deallocate(alloc, object, 1);
9742 };
9743 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
9744 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
9745 assert(object != nullptr);
9746 return object.release();
9747 }
9748
9750 // JSON value storage //
9752
9777 union json_value {
9779 object_t* object;
9781 array_t* array;
9783 string_t* string;
9785 boolean_t boolean;
9787 number_integer_t number_integer;
9789 number_unsigned_t number_unsigned;
9791 number_float_t number_float;
9792
9794 json_value() = default;
9796 json_value(boolean_t v) noexcept : boolean(v) {}
9798 json_value(number_integer_t v) noexcept : number_integer(v) {}
9800 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
9802 json_value(number_float_t v) noexcept : number_float(v) {}
9804 json_value(value_t t)
9805 {
9806 switch (t) {
9807 case value_t::object: {
9808 object = create<object_t>();
9809 break;
9810 }
9811
9812 case value_t::array: {
9813 array = create<array_t>();
9814 break;
9815 }
9816
9817 case value_t::string: {
9818 string = create<string_t>("");
9819 break;
9820 }
9821
9822 case value_t::boolean: {
9823 boolean = boolean_t(false);
9824 break;
9825 }
9826
9827 case value_t::number_integer: {
9828 number_integer = number_integer_t(0);
9829 break;
9830 }
9831
9832 case value_t::number_unsigned: {
9833 number_unsigned = number_unsigned_t(0);
9834 break;
9835 }
9836
9837 case value_t::number_float: {
9838 number_float = number_float_t(0.0);
9839 break;
9840 }
9841
9842 case value_t::null: {
9843 object = nullptr; // silence warning, see #821
9844 break;
9845 }
9846
9847 default: {
9848 object = nullptr; // silence warning, see #821
9849 if (JSON_UNLIKELY(t == value_t::null)) {
9850 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
9851 }
9852 break;
9853 }
9854 }
9855 }
9856
9858 json_value(const string_t& value)
9859 {
9860 string = create<string_t>(value);
9861 }
9862
9864 json_value(string_t&& value)
9865 {
9866 string = create<string_t>(std::move(value));
9867 }
9868
9870 json_value(const object_t& value)
9871 {
9872 object = create<object_t>(value);
9873 }
9874
9876 json_value(object_t&& value)
9877 {
9878 object = create<object_t>(std::move(value));
9879 }
9880
9882 json_value(const array_t& value)
9883 {
9884 array = create<array_t>(value);
9885 }
9886
9888 json_value(array_t&& value)
9889 {
9890 array = create<array_t>(std::move(value));
9891 }
9892
9893 void destroy(value_t t) noexcept
9894 {
9895 switch (t) {
9896 case value_t::object: {
9897 AllocatorType<object_t> alloc;
9898 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
9899 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
9900 break;
9901 }
9902
9903 case value_t::array: {
9904 AllocatorType<array_t> alloc;
9905 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
9906 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
9907 break;
9908 }
9909
9910 case value_t::string: {
9911 AllocatorType<string_t> alloc;
9912 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
9913 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
9914 break;
9915 }
9916
9917 default: {
9918 break;
9919 }
9920 }
9921 }
9922 };
9923
9933 void assert_invariant() const noexcept
9934 {
9935 assert(m_type != value_t::object or m_value.object != nullptr);
9936 assert(m_type != value_t::array or m_value.array != nullptr);
9937 assert(m_type != value_t::string or m_value.string != nullptr);
9938 }
9939
9940 public:
9942 // JSON parser callback //
9944
9960 using parse_event_t = typename parser::parse_event_t;
9961
10011 using parser_callback_t = typename parser::parser_callback_t;
10012
10014 // constructors //
10016
10021
10051 basic_json(const value_t v)
10052 : m_type(v), m_value(v)
10053 {
10054 assert_invariant();
10055 }
10056
10075 basic_json(std::nullptr_t = nullptr) noexcept
10076 : basic_json(value_t::null)
10077 {
10078 assert_invariant();
10079 }
10080
10138 template <typename CompatibleType,
10139 typename U = detail::uncvref_t<CompatibleType>,
10141 detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
10142 basic_json(CompatibleType&& val) noexcept(noexcept(
10143 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
10144 std::forward<CompatibleType>(val))))
10145 {
10146 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
10147 assert_invariant();
10148 }
10149
10176 template <typename BasicJsonType,
10178 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
10179 basic_json(const BasicJsonType& val)
10180 {
10181 using other_boolean_t = typename BasicJsonType::boolean_t;
10182 using other_number_float_t = typename BasicJsonType::number_float_t;
10183 using other_number_integer_t = typename BasicJsonType::number_integer_t;
10184 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10185 using other_string_t = typename BasicJsonType::string_t;
10186 using other_object_t = typename BasicJsonType::object_t;
10187 using other_array_t = typename BasicJsonType::array_t;
10188
10189 switch (val.type()) {
10190 case value_t::boolean:
10191 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
10192 break;
10193 case value_t::number_float:
10194 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
10195 break;
10196 case value_t::number_integer:
10197 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
10198 break;
10199 case value_t::number_unsigned:
10200 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
10201 break;
10202 case value_t::string:
10203 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
10204 break;
10205 case value_t::object:
10206 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
10207 break;
10208 case value_t::array:
10209 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
10210 break;
10211 case value_t::null:
10212 *this = nullptr;
10213 break;
10214 case value_t::discarded:
10215 m_type = value_t::discarded;
10216 break;
10217 }
10218 assert_invariant();
10219 }
10220
10295 basic_json(initializer_list_t init,
10296 bool type_deduction = true,
10297 value_t manual_type = value_t::array)
10298 {
10299 // check if each element is an array with two elements whose first
10300 // element is a string
10301 bool is_an_object = std::all_of(init.begin(), init.end(),
10302 [](const detail::json_ref<basic_json>& element_ref) {
10303 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
10304 });
10305
10306 // adjust type if type deduction is not wanted
10307 if (not type_deduction) {
10308 // if array is wanted, do not create an object though possible
10309 if (manual_type == value_t::array) {
10310 is_an_object = false;
10311 }
10312
10313 // if object is wanted but impossible, throw an exception
10314 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
10315 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
10316 }
10317 }
10318
10319 if (is_an_object) {
10320 // the initializer list is a list of pairs -> create object
10321 m_type = value_t::object;
10322 m_value = value_t::object;
10323
10324 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref) {
10325 auto element = element_ref.moved_or_copied();
10326 m_value.object->emplace(
10327 std::move(*((*element.m_value.array)[0].m_value.string)),
10328 std::move((*element.m_value.array)[1]));
10329 });
10330 } else {
10331 // the initializer list describes an array -> create array
10332 m_type = value_t::array;
10333 m_value.array = create<array_t>(init.begin(), init.end());
10334 }
10335
10336 assert_invariant();
10337 }
10338
10376 static basic_json array(initializer_list_t init = {})
10377 {
10378 return basic_json(init, false, value_t::array);
10379 }
10380
10419 static basic_json object(initializer_list_t init = {})
10420 {
10421 return basic_json(init, false, value_t::object);
10422 }
10423
10446 basic_json(size_type cnt, const basic_json& val)
10447 : m_type(value_t::array)
10448 {
10449 m_value.array = create<array_t>(cnt, val);
10450 assert_invariant();
10451 }
10452
10508 template <class InputIT, typename std::enable_if<
10509 std::is_same<InputIT, typename basic_json_t::iterator>::value or
10510 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
10511 int>::type = 0>
10512 basic_json(InputIT first, InputIT last)
10513 {
10514 assert(first.m_object != nullptr);
10515 assert(last.m_object != nullptr);
10516
10517 // make sure iterator fits the current value
10518 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
10519 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
10520 }
10521
10522 // copy type from first iterator
10523 m_type = first.m_object->m_type;
10524
10525 // check if iterator range is complete for primitive values
10526 switch (m_type) {
10527 case value_t::boolean:
10528 case value_t::number_float:
10529 case value_t::number_integer:
10530 case value_t::number_unsigned:
10531 case value_t::string: {
10532 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())) {
10533 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
10534 }
10535 break;
10536 }
10537
10538 default:
10539 break;
10540 }
10541
10542 switch (m_type) {
10543 case value_t::number_integer: {
10544 m_value.number_integer = first.m_object->m_value.number_integer;
10545 break;
10546 }
10547
10548 case value_t::number_unsigned: {
10549 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
10550 break;
10551 }
10552
10553 case value_t::number_float: {
10554 m_value.number_float = first.m_object->m_value.number_float;
10555 break;
10556 }
10557
10558 case value_t::boolean: {
10559 m_value.boolean = first.m_object->m_value.boolean;
10560 break;
10561 }
10562
10563 case value_t::string: {
10564 m_value = *first.m_object->m_value.string;
10565 break;
10566 }
10567
10568 case value_t::object: {
10569 m_value.object = create<object_t>(first.m_it.object_iterator,
10570 last.m_it.object_iterator);
10571 break;
10572 }
10573
10574 case value_t::array: {
10575 m_value.array = create<array_t>(first.m_it.array_iterator,
10576 last.m_it.array_iterator);
10577 break;
10578 }
10579
10580 default:
10581 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
10582 std::string(first.m_object->type_name())));
10583 }
10584
10585 assert_invariant();
10586 }
10587
10589 // other constructors and destructor //
10591
10593 basic_json(const detail::json_ref<basic_json>& ref)
10594 : basic_json(ref.moved_or_copied())
10595 {
10596 }
10597
10623 basic_json(const basic_json& other)
10624 : m_type(other.m_type)
10625 {
10626 // check of passed value is valid
10627 other.assert_invariant();
10628
10629 switch (m_type) {
10630 case value_t::object: {
10631 m_value = *other.m_value.object;
10632 break;
10633 }
10634
10635 case value_t::array: {
10636 m_value = *other.m_value.array;
10637 break;
10638 }
10639
10640 case value_t::string: {
10641 m_value = *other.m_value.string;
10642 break;
10643 }
10644
10645 case value_t::boolean: {
10646 m_value = other.m_value.boolean;
10647 break;
10648 }
10649
10650 case value_t::number_integer: {
10651 m_value = other.m_value.number_integer;
10652 break;
10653 }
10654
10655 case value_t::number_unsigned: {
10656 m_value = other.m_value.number_unsigned;
10657 break;
10658 }
10659
10660 case value_t::number_float: {
10661 m_value = other.m_value.number_float;
10662 break;
10663 }
10664
10665 default:
10666 break;
10667 }
10668
10669 assert_invariant();
10670 }
10671
10698 basic_json(basic_json&& other) noexcept
10699 : m_type(std::move(other.m_type)),
10700 m_value(std::move(other.m_value))
10701 {
10702 // check that passed value is valid
10703 other.assert_invariant();
10704
10705 // invalidate payload
10706 other.m_type = value_t::null;
10707 other.m_value = {};
10708
10709 assert_invariant();
10710 }
10711
10735 reference& operator=(basic_json other) noexcept(
10736 std::is_nothrow_move_constructible<value_t>::value and
10737 std::is_nothrow_move_assignable<value_t>::value and
10738 std::is_nothrow_move_constructible<json_value>::value and
10739 std::is_nothrow_move_assignable<json_value>::value)
10740 {
10741 // check that passed value is valid
10742 other.assert_invariant();
10743
10744 using std::swap;
10745 swap(m_type, other.m_type);
10746 swap(m_value, other.m_value);
10747
10748 assert_invariant();
10749 return *this;
10750 }
10751
10767 ~basic_json() noexcept
10768 {
10769 assert_invariant();
10770 m_value.destroy(m_type);
10771 }
10772
10774
10775 public:
10777 // object inspection //
10779
10783
10820 string_t dump(const int indent = -1, const char indent_char = ' ',
10821 const bool ensure_ascii = false) const
10822 {
10823 string_t result;
10824 serializer s(detail::output_adapter<char, string_t>(result), indent_char);
10825
10826 if (indent >= 0) {
10827 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
10828 } else {
10829 s.dump(*this, false, ensure_ascii, 0);
10830 }
10831
10832 return result;
10833 }
10834
10867 constexpr value_t type() const noexcept
10868 {
10869 return m_type;
10870 }
10871
10897 constexpr bool is_primitive() const noexcept
10898 {
10899 return is_null() or is_string() or is_boolean() or is_number();
10900 }
10901
10924 constexpr bool is_structured() const noexcept
10925 {
10926 return is_array() or is_object();
10927 }
10928
10946 constexpr bool is_null() const noexcept
10947 {
10948 return (m_type == value_t::null);
10949 }
10950
10968 constexpr bool is_boolean() const noexcept
10969 {
10970 return (m_type == value_t::boolean);
10971 }
10972
10998 constexpr bool is_number() const noexcept
10999 {
11000 return is_number_integer() or is_number_float();
11001 }
11002
11027 constexpr bool is_number_integer() const noexcept
11028 {
11029 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
11030 }
11031
11055 constexpr bool is_number_unsigned() const noexcept
11056 {
11057 return (m_type == value_t::number_unsigned);
11058 }
11059
11083 constexpr bool is_number_float() const noexcept
11084 {
11085 return (m_type == value_t::number_float);
11086 }
11087
11105 constexpr bool is_object() const noexcept
11106 {
11107 return (m_type == value_t::object);
11108 }
11109
11127 constexpr bool is_array() const noexcept
11128 {
11129 return (m_type == value_t::array);
11130 }
11131
11149 constexpr bool is_string() const noexcept
11150 {
11151 return (m_type == value_t::string);
11152 }
11153
11176 constexpr bool is_discarded() const noexcept
11177 {
11178 return (m_type == value_t::discarded);
11179 }
11180
11202 constexpr operator value_t() const noexcept
11203 {
11204 return m_type;
11205 }
11206
11208
11209 private:
11211 // value access //
11213
11215 boolean_t get_impl(boolean_t* /*unused*/) const
11216 {
11217 if (JSON_LIKELY(is_boolean())) {
11218 return m_value.boolean;
11219 }
11220
11221 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
11222 }
11223
11225 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
11226 {
11227 return is_object() ? m_value.object : nullptr;
11228 }
11229
11231 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
11232 {
11233 return is_object() ? m_value.object : nullptr;
11234 }
11235
11237 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
11238 {
11239 return is_array() ? m_value.array : nullptr;
11240 }
11241
11243 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
11244 {
11245 return is_array() ? m_value.array : nullptr;
11246 }
11247
11249 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
11250 {
11251 return is_string() ? m_value.string : nullptr;
11252 }
11253
11255 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
11256 {
11257 return is_string() ? m_value.string : nullptr;
11258 }
11259
11261 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
11262 {
11263 return is_boolean() ? &m_value.boolean : nullptr;
11264 }
11265
11267 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
11268 {
11269 return is_boolean() ? &m_value.boolean : nullptr;
11270 }
11271
11273 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
11274 {
11275 return is_number_integer() ? &m_value.number_integer : nullptr;
11276 }
11277
11279 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
11280 {
11281 return is_number_integer() ? &m_value.number_integer : nullptr;
11282 }
11283
11285 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
11286 {
11287 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
11288 }
11289
11291 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
11292 {
11293 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
11294 }
11295
11297 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
11298 {
11299 return is_number_float() ? &m_value.number_float : nullptr;
11300 }
11301
11303 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
11304 {
11305 return is_number_float() ? &m_value.number_float : nullptr;
11306 }
11307
11319 template <typename ReferenceType, typename ThisType>
11320 static ReferenceType get_ref_impl(ThisType& obj)
11321 {
11322 // delegate the call to get_ptr<>()
11323 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
11324
11325 if (JSON_LIKELY(ptr != nullptr)) {
11326 return *ptr;
11327 }
11328
11329 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
11330 }
11331
11332 public:
11336
11351 template <typename BasicJsonType, detail::enable_if_t<
11352 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
11353 int> = 0>
11354 basic_json get() const
11355 {
11356 return *this;
11357 }
11358
11374 template <typename BasicJsonType, detail::enable_if_t<
11375 not std::is_same<BasicJsonType, basic_json>::value and
11376 detail::is_basic_json<BasicJsonType>::value,
11377 int> = 0>
11378 BasicJsonType get() const
11379 {
11380 return *this;
11381 }
11382
11422 template <typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
11423 detail::enable_if_t<
11424 not detail::is_basic_json<ValueType>::value and
11425 detail::has_from_json<basic_json_t, ValueType>::value and
11426 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11427 int> = 0>
11428 ValueType get() const noexcept(noexcept(
11429 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
11430 {
11431 // we cannot static_assert on ValueTypeCV being non-const, because
11432 // there is support for get<const basic_json_t>(), which is why we
11433 // still need the uncvref
11434 static_assert(not std::is_reference<ValueTypeCV>::value,
11435 "get() cannot be used with reference types, you might want to use get_ref()");
11436 static_assert(std::is_default_constructible<ValueType>::value,
11437 "types must be DefaultConstructible when used with get()");
11438
11439 ValueType ret;
11440 JSONSerializer<ValueType>::from_json(*this, ret);
11441 return ret;
11442 }
11443
11475 template <typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
11476 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
11477 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11478 int> = 0>
11479 ValueType get() const noexcept(noexcept(
11480 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
11481 {
11482 static_assert(not std::is_reference<ValueTypeCV>::value,
11483 "get() cannot be used with reference types, you might want to use get_ref()");
11484 return JSONSerializer<ValueTypeCV>::from_json(*this);
11485 }
11486
11514 template <typename PointerType, typename std::enable_if<
11515 std::is_pointer<PointerType>::value, int>::type = 0>
11516 PointerType get() noexcept
11517 {
11518 // delegate the call to get_ptr
11519 return get_ptr<PointerType>();
11520 }
11521
11526 template <typename PointerType, typename std::enable_if<
11527 std::is_pointer<PointerType>::value, int>::type = 0>
11528 constexpr const PointerType get() const noexcept
11529 {
11530 // delegate the call to get_ptr
11531 return get_ptr<PointerType>();
11532 }
11533
11560 template <typename PointerType, typename std::enable_if<
11561 std::is_pointer<PointerType>::value, int>::type = 0>
11562 PointerType get_ptr() noexcept
11563 {
11564 // get the type of the PointerType (remove pointer and const)
11565 using pointee_t = typename std::remove_const<typename std::remove_pointer<typename std::remove_const<PointerType>::type>::type>::type;
11566 // make sure the type matches the allowed types
11567 static_assert(
11568 std::is_same<object_t, pointee_t>::value or std::is_same<array_t, pointee_t>::value or std::is_same<string_t, pointee_t>::value or std::is_same<boolean_t, pointee_t>::value or std::is_same<number_integer_t, pointee_t>::value or std::is_same<number_unsigned_t, pointee_t>::value or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
11569
11570 // delegate the call to get_impl_ptr<>()
11571 return get_impl_ptr(static_cast<PointerType>(nullptr));
11572 }
11573
11578 template <typename PointerType, typename std::enable_if<
11579 std::is_pointer<PointerType>::value and
11580 std::is_const<typename std::remove_pointer<PointerType>::type>::value,
11581 int>::type = 0>
11582 constexpr const PointerType get_ptr() const noexcept
11583 {
11584 // get the type of the PointerType (remove pointer and const)
11585 using pointee_t = typename std::remove_const<typename std::remove_pointer<typename std::remove_const<PointerType>::type>::type>::type;
11586 // make sure the type matches the allowed types
11587 static_assert(
11588 std::is_same<object_t, pointee_t>::value or std::is_same<array_t, pointee_t>::value or std::is_same<string_t, pointee_t>::value or std::is_same<boolean_t, pointee_t>::value or std::is_same<number_integer_t, pointee_t>::value or std::is_same<number_unsigned_t, pointee_t>::value or std::is_same<number_float_t, pointee_t>::value, "incompatible pointer type");
11589
11590 // delegate the call to get_impl_ptr<>() const
11591 return get_impl_ptr(static_cast<PointerType>(nullptr));
11592 }
11593
11620 template <typename ReferenceType, typename std::enable_if<
11621 std::is_reference<ReferenceType>::value, int>::type = 0>
11622 ReferenceType get_ref()
11623 {
11624 // delegate call to get_ref_impl
11625 return get_ref_impl<ReferenceType>(*this);
11626 }
11627
11632 template <typename ReferenceType, typename std::enable_if<
11633 std::is_reference<ReferenceType>::value and
11634 std::is_const<typename std::remove_reference<ReferenceType>::type>::value,
11635 int>::type = 0>
11636 ReferenceType get_ref() const
11637 {
11638 // delegate call to get_ref_impl
11639 return get_ref_impl<ReferenceType>(*this);
11640 }
11641
11671 template <typename ValueType, typename std::enable_if<
11672 not std::is_pointer<ValueType>::value and
11673 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
11674 not std::is_same<ValueType, typename string_t::value_type>::value and
11675 not detail::is_basic_json<ValueType>::value
11676#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
11677 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
11678#endif
11679#if defined(JSON_HAS_CPP_17)
11680 and not std::is_same<ValueType, typename std::string_view>::value
11681#endif
11682 ,
11683 int>::type = 0>
11684 operator ValueType() const
11685 {
11686 // delegate the call to get<>() const
11687 return get<ValueType>();
11688 }
11689
11691
11693 // element access //
11695
11699
11726 reference at(size_type idx)
11727 {
11728 // at only works for arrays
11729 if (JSON_LIKELY(is_array())) {
11730 JSON_TRY
11731 {
11732 return m_value.array->at(idx);
11733 }
11734 JSON_CATCH(std::out_of_range&)
11735 {
11736 // create better exception explanation
11737 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
11738 }
11739 } else {
11740 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
11741 }
11742 }
11743
11770 const_reference at(size_type idx) const
11771 {
11772 // at only works for arrays
11773 if (JSON_LIKELY(is_array())) {
11774 JSON_TRY
11775 {
11776 return m_value.array->at(idx);
11777 }
11778 JSON_CATCH(std::out_of_range&)
11779 {
11780 // create better exception explanation
11781 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
11782 }
11783 } else {
11784 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
11785 }
11786 }
11787
11818 reference at(const typename object_t::key_type& key)
11819 {
11820 // at only works for objects
11821 if (JSON_LIKELY(is_object())) {
11822 JSON_TRY
11823 {
11824 return m_value.object->at(key);
11825 }
11826 JSON_CATCH(std::out_of_range&)
11827 {
11828 // create better exception explanation
11829 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
11830 }
11831 } else {
11832 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
11833 }
11834 }
11835
11866 const_reference at(const typename object_t::key_type& key) const
11867 {
11868 // at only works for objects
11869 if (JSON_LIKELY(is_object())) {
11870 JSON_TRY
11871 {
11872 return m_value.object->at(key);
11873 }
11874 JSON_CATCH(std::out_of_range&)
11875 {
11876 // create better exception explanation
11877 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
11878 }
11879 } else {
11880 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
11881 }
11882 }
11883
11909 reference operator[](size_type idx)
11910 {
11911 // implicitly convert null value to an empty array
11912 if (is_null()) {
11913 m_type = value_t::array;
11914 m_value.array = create<array_t>();
11915 assert_invariant();
11916 }
11917
11918 // operator[] only works for arrays
11919 if (JSON_LIKELY(is_array())) {
11920 // fill up array with null values if given idx is outside range
11921 if (idx >= m_value.array->size()) {
11922 m_value.array->insert(m_value.array->end(),
11923 idx - m_value.array->size() + 1,
11924 basic_json());
11925 }
11926
11927 return m_value.array->operator[](idx);
11928 }
11929
11930 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
11931 }
11932
11952 const_reference operator[](size_type idx) const
11953 {
11954 // const operator[] only works for arrays
11955 if (JSON_LIKELY(is_array())) {
11956 return m_value.array->operator[](idx);
11957 }
11958
11959 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
11960 }
11961
11989 reference operator[](const typename object_t::key_type& key)
11990 {
11991 // implicitly convert null value to an empty object
11992 if (is_null()) {
11993 m_type = value_t::object;
11994 m_value.object = create<object_t>();
11995 assert_invariant();
11996 }
11997
11998 // operator[] only works for objects
11999 if (JSON_LIKELY(is_object())) {
12000 return m_value.object->operator[](key);
12001 }
12002
12003 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12004 }
12005
12036 const_reference operator[](const typename object_t::key_type& key) const
12037 {
12038 // const operator[] only works for objects
12039 if (JSON_LIKELY(is_object())) {
12040 assert(m_value.object->find(key) != m_value.object->end());
12041 return m_value.object->find(key)->second;
12042 }
12043
12044 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12045 }
12046
12074 template <typename T>
12075 reference operator[](T* key)
12076 {
12077 // implicitly convert null to object
12078 if (is_null()) {
12079 m_type = value_t::object;
12080 m_value = value_t::object;
12081 assert_invariant();
12082 }
12083
12084 // at only works for objects
12085 if (JSON_LIKELY(is_object())) {
12086 return m_value.object->operator[](key);
12087 }
12088
12089 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12090 }
12091
12122 template <typename T>
12123 const_reference operator[](T* key) const
12124 {
12125 // at only works for objects
12126 if (JSON_LIKELY(is_object())) {
12127 assert(m_value.object->find(key) != m_value.object->end());
12128 return m_value.object->find(key)->second;
12129 }
12130
12131 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12132 }
12133
12182 template <class ValueType, typename std::enable_if<
12183 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
12184 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
12185 {
12186 // at only works for objects
12187 if (JSON_LIKELY(is_object())) {
12188 // if key is found, return value and given default value otherwise
12189 const auto it = find(key);
12190 if (it != end()) {
12191 return *it;
12192 }
12193
12194 return default_value;
12195 }
12196
12197 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
12198 }
12199
12204 string_t value(const typename object_t::key_type& key, const char* default_value) const
12205 {
12206 return value(key, string_t(default_value));
12207 }
12208
12250 template <class ValueType, typename std::enable_if<
12251 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
12252 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
12253 {
12254 // at only works for objects
12255 if (JSON_LIKELY(is_object())) {
12256 // if pointer resolves a value, return it or use default value
12257 JSON_TRY
12258 {
12259 return ptr.get_checked(this);
12260 }
12261 JSON_CATCH(out_of_range&)
12262 {
12263 return default_value;
12264 }
12265 }
12266
12267 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
12268 }
12269
12274 string_t value(const json_pointer& ptr, const char* default_value) const
12275 {
12276 return value(ptr, string_t(default_value));
12277 }
12278
12304 reference front()
12305 {
12306 return *begin();
12307 }
12308
12312 const_reference front() const
12313 {
12314 return *cbegin();
12315 }
12316
12348 reference back()
12349 {
12350 auto tmp = end();
12351 --tmp;
12352 return *tmp;
12353 }
12354
12358 const_reference back() const
12359 {
12360 auto tmp = cend();
12361 --tmp;
12362 return *tmp;
12363 }
12364
12411 template <class IteratorType, typename std::enable_if<
12412 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12413 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
12414 int>::type = 0>
12415 IteratorType erase(IteratorType pos)
12416 {
12417 // make sure iterator fits the current value
12418 if (JSON_UNLIKELY(this != pos.m_object)) {
12419 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
12420 }
12421
12422 IteratorType result = end();
12423
12424 switch (m_type) {
12425 case value_t::boolean:
12426 case value_t::number_float:
12427 case value_t::number_integer:
12428 case value_t::number_unsigned:
12429 case value_t::string: {
12430 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
12431 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
12432 }
12433
12434 if (is_string()) {
12435 AllocatorType<string_t> alloc;
12436 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12437 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12438 m_value.string = nullptr;
12439 }
12440
12441 m_type = value_t::null;
12442 assert_invariant();
12443 break;
12444 }
12445
12446 case value_t::object: {
12447 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
12448 break;
12449 }
12450
12451 case value_t::array: {
12452 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
12453 break;
12454 }
12455
12456 default:
12457 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12458 }
12459
12460 return result;
12461 }
12462
12509 template <class IteratorType, typename std::enable_if<
12510 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12511 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
12512 int>::type = 0>
12513 IteratorType erase(IteratorType first, IteratorType last)
12514 {
12515 // make sure iterator fits the current value
12516 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object)) {
12517 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
12518 }
12519
12520 IteratorType result = end();
12521
12522 switch (m_type) {
12523 case value_t::boolean:
12524 case value_t::number_float:
12525 case value_t::number_integer:
12526 case value_t::number_unsigned:
12527 case value_t::string: {
12528 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())) {
12529 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
12530 }
12531
12532 if (is_string()) {
12533 AllocatorType<string_t> alloc;
12534 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12535 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12536 m_value.string = nullptr;
12537 }
12538
12539 m_type = value_t::null;
12540 assert_invariant();
12541 break;
12542 }
12543
12544 case value_t::object: {
12545 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
12546 last.m_it.object_iterator);
12547 break;
12548 }
12549
12550 case value_t::array: {
12551 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
12552 last.m_it.array_iterator);
12553 break;
12554 }
12555
12556 default:
12557 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12558 }
12559
12560 return result;
12561 }
12562
12592 size_type erase(const typename object_t::key_type& key)
12593 {
12594 // this erase only works for objects
12595 if (JSON_LIKELY(is_object())) {
12596 return m_value.object->erase(key);
12597 }
12598
12599 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12600 }
12601
12626 void erase(const size_type idx)
12627 {
12628 // this erase only works for arrays
12629 if (JSON_LIKELY(is_array())) {
12630 if (JSON_UNLIKELY(idx >= size())) {
12631 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
12632 }
12633
12634 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
12635 } else {
12636 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12637 }
12638 }
12639
12641
12643 // lookup //
12645
12648
12671 template <typename KeyT>
12672 iterator find(KeyT&& key)
12673 {
12674 auto result = end();
12675
12676 if (is_object()) {
12677 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
12678 }
12679
12680 return result;
12681 }
12682
12687 template <typename KeyT>
12688 const_iterator find(KeyT&& key) const
12689 {
12690 auto result = cend();
12691
12692 if (is_object()) {
12693 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
12694 }
12695
12696 return result;
12697 }
12698
12720 template <typename KeyT>
12721 size_type count(KeyT&& key) const
12722 {
12723 // return 0 for all nonobject types
12724 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
12725 }
12726
12728
12730 // iterators //
12732
12735
12760 iterator begin() noexcept
12761 {
12762 iterator result(this);
12763 result.set_begin();
12764 return result;
12765 }
12766
12770 const_iterator begin() const noexcept
12771 {
12772 return cbegin();
12773 }
12774
12800 const_iterator cbegin() const noexcept
12801 {
12802 const_iterator result(this);
12803 result.set_begin();
12804 return result;
12805 }
12806
12831 iterator end() noexcept
12832 {
12833 iterator result(this);
12834 result.set_end();
12835 return result;
12836 }
12837
12841 const_iterator end() const noexcept
12842 {
12843 return cend();
12844 }
12845
12871 const_iterator cend() const noexcept
12872 {
12873 const_iterator result(this);
12874 result.set_end();
12875 return result;
12876 }
12877
12901 reverse_iterator rbegin() noexcept
12902 {
12903 return reverse_iterator(end());
12904 }
12905
12909 const_reverse_iterator rbegin() const noexcept
12910 {
12911 return crbegin();
12912 }
12913
12938 reverse_iterator rend() noexcept
12939 {
12940 return reverse_iterator(begin());
12941 }
12942
12946 const_reverse_iterator rend() const noexcept
12947 {
12948 return crend();
12949 }
12950
12975 const_reverse_iterator crbegin() const noexcept
12976 {
12977 return const_reverse_iterator(cend());
12978 }
12979
13004 const_reverse_iterator crend() const noexcept
13005 {
13006 return const_reverse_iterator(cbegin());
13007 }
13008
13009 public:
13068 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
13069 {
13070 return ref.items();
13071 }
13072
13077 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
13078 {
13079 return ref.items();
13080 }
13081
13134 iteration_proxy<iterator> items() noexcept
13135 {
13136 return iteration_proxy<iterator>(*this);
13137 }
13138
13142 iteration_proxy<const_iterator> items() const noexcept
13143 {
13144 return iteration_proxy<const_iterator>(*this);
13145 }
13146
13148
13150 // capacity //
13152
13155
13197 bool empty() const noexcept
13198 {
13199 switch (m_type) {
13200 case value_t::null: {
13201 // null values are empty
13202 return true;
13203 }
13204
13205 case value_t::array: {
13206 // delegate call to array_t::empty()
13207 return m_value.array->empty();
13208 }
13209
13210 case value_t::object: {
13211 // delegate call to object_t::empty()
13212 return m_value.object->empty();
13213 }
13214
13215 default: {
13216 // all other types are nonempty
13217 return false;
13218 }
13219 }
13220 }
13221
13264 size_type size() const noexcept
13265 {
13266 switch (m_type) {
13267 case value_t::null: {
13268 // null values are empty
13269 return 0;
13270 }
13271
13272 case value_t::array: {
13273 // delegate call to array_t::size()
13274 return m_value.array->size();
13275 }
13276
13277 case value_t::object: {
13278 // delegate call to object_t::size()
13279 return m_value.object->size();
13280 }
13281
13282 default: {
13283 // all other types have size 1
13284 return 1;
13285 }
13286 }
13287 }
13288
13329 size_type max_size() const noexcept
13330 {
13331 switch (m_type) {
13332 case value_t::array: {
13333 // delegate call to array_t::max_size()
13334 return m_value.array->max_size();
13335 }
13336
13337 case value_t::object: {
13338 // delegate call to object_t::max_size()
13339 return m_value.object->max_size();
13340 }
13341
13342 default: {
13343 // all other types have max_size() == size()
13344 return size();
13345 }
13346 }
13347 }
13348
13350
13352 // modifiers //
13354
13357
13394 void clear() noexcept
13395 {
13396 switch (m_type) {
13397 case value_t::number_integer: {
13398 m_value.number_integer = 0;
13399 break;
13400 }
13401
13402 case value_t::number_unsigned: {
13403 m_value.number_unsigned = 0;
13404 break;
13405 }
13406
13407 case value_t::number_float: {
13408 m_value.number_float = 0.0;
13409 break;
13410 }
13411
13412 case value_t::boolean: {
13413 m_value.boolean = false;
13414 break;
13415 }
13416
13417 case value_t::string: {
13418 m_value.string->clear();
13419 break;
13420 }
13421
13422 case value_t::array: {
13423 m_value.array->clear();
13424 break;
13425 }
13426
13427 case value_t::object: {
13428 m_value.object->clear();
13429 break;
13430 }
13431
13432 default:
13433 break;
13434 }
13435 }
13436
13457 void push_back(basic_json&& val)
13458 {
13459 // push_back only works for null objects or arrays
13460 if (JSON_UNLIKELY(not(is_null() or is_array()))) {
13461 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13462 }
13463
13464 // transform null object into an array
13465 if (is_null()) {
13466 m_type = value_t::array;
13467 m_value = value_t::array;
13468 assert_invariant();
13469 }
13470
13471 // add element to array (move semantics)
13472 m_value.array->push_back(std::move(val));
13473 // invalidate object
13474 val.m_type = value_t::null;
13475 }
13476
13481 reference operator+=(basic_json&& val)
13482 {
13483 push_back(std::move(val));
13484 return *this;
13485 }
13486
13491 void push_back(const basic_json& val)
13492 {
13493 // push_back only works for null objects or arrays
13494 if (JSON_UNLIKELY(not(is_null() or is_array()))) {
13495 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13496 }
13497
13498 // transform null object into an array
13499 if (is_null()) {
13500 m_type = value_t::array;
13501 m_value = value_t::array;
13502 assert_invariant();
13503 }
13504
13505 // add element to array
13506 m_value.array->push_back(val);
13507 }
13508
13513 reference operator+=(const basic_json& val)
13514 {
13515 push_back(val);
13516 return *this;
13517 }
13518
13539 void push_back(const typename object_t::value_type& val)
13540 {
13541 // push_back only works for null objects or objects
13542 if (JSON_UNLIKELY(not(is_null() or is_object()))) {
13543 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13544 }
13545
13546 // transform null object into an object
13547 if (is_null()) {
13548 m_type = value_t::object;
13549 m_value = value_t::object;
13550 assert_invariant();
13551 }
13552
13553 // add element to array
13554 m_value.object->insert(val);
13555 }
13556
13561 reference operator+=(const typename object_t::value_type& val)
13562 {
13563 push_back(val);
13564 return *this;
13565 }
13566
13592 void push_back(initializer_list_t init)
13593 {
13594 if (is_object() and init.size() == 2 and (*init.begin())->is_string()) {
13595 basic_json&& key = init.begin()->moved_or_copied();
13596 push_back(typename object_t::value_type(
13597 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
13598 } else {
13599 push_back(basic_json(init));
13600 }
13601 }
13602
13607 reference operator+=(initializer_list_t init)
13608 {
13609 push_back(init);
13610 return *this;
13611 }
13612
13634 template <class... Args>
13635 void emplace_back(Args&&... args)
13636 {
13637 // emplace_back only works for null objects or arrays
13638 if (JSON_UNLIKELY(not(is_null() or is_array()))) {
13639 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
13640 }
13641
13642 // transform null object into an array
13643 if (is_null()) {
13644 m_type = value_t::array;
13645 m_value = value_t::array;
13646 assert_invariant();
13647 }
13648
13649 // add element to array (perfect forwarding)
13650 m_value.array->emplace_back(std::forward<Args>(args)...);
13651 }
13652
13680 template <class... Args>
13681 std::pair<iterator, bool> emplace(Args&&... args)
13682 {
13683 // emplace only works for null objects or arrays
13684 if (JSON_UNLIKELY(not(is_null() or is_object()))) {
13685 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
13686 }
13687
13688 // transform null object into an object
13689 if (is_null()) {
13690 m_type = value_t::object;
13691 m_value = value_t::object;
13692 assert_invariant();
13693 }
13694
13695 // add element to array (perfect forwarding)
13696 auto res = m_value.object->emplace(std::forward<Args>(args)...);
13697 // create result iterator and set iterator to the result of emplace
13698 auto it = begin();
13699 it.m_it.object_iterator = res.first;
13700
13701 // return pair of iterator and boolean
13702 return {it, res.second};
13703 }
13704
13727 iterator insert(const_iterator pos, const basic_json& val)
13728 {
13729 // insert only works for arrays
13730 if (JSON_LIKELY(is_array())) {
13731 // check if iterator pos fits to this JSON value
13732 if (JSON_UNLIKELY(pos.m_object != this)) {
13733 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
13734 }
13735
13736 // insert to array and return iterator
13737 iterator result(this);
13738 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
13739 return result;
13740 }
13741
13742 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
13743 }
13744
13749 iterator insert(const_iterator pos, basic_json&& val)
13750 {
13751 return insert(pos, val);
13752 }
13753
13778 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
13779 {
13780 // insert only works for arrays
13781 if (JSON_LIKELY(is_array())) {
13782 // check if iterator pos fits to this JSON value
13783 if (JSON_UNLIKELY(pos.m_object != this)) {
13784 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
13785 }
13786
13787 // insert to array and return iterator
13788 iterator result(this);
13789 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
13790 return result;
13791 }
13792
13793 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
13794 }
13795
13826 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
13827 {
13828 // insert only works for arrays
13829 if (JSON_UNLIKELY(not is_array())) {
13830 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
13831 }
13832
13833 // check if iterator pos fits to this JSON value
13834 if (JSON_UNLIKELY(pos.m_object != this)) {
13835 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
13836 }
13837
13838 // check if range iterators belong to the same JSON object
13839 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
13840 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
13841 }
13842
13843 if (JSON_UNLIKELY(first.m_object == this)) {
13844 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
13845 }
13846
13847 // insert to array and return iterator
13848 iterator result(this);
13849 result.m_it.array_iterator = m_value.array->insert(
13850 pos.m_it.array_iterator,
13851 first.m_it.array_iterator,
13852 last.m_it.array_iterator);
13853 return result;
13854 }
13855
13880 iterator insert(const_iterator pos, initializer_list_t ilist)
13881 {
13882 // insert only works for arrays
13883 if (JSON_UNLIKELY(not is_array())) {
13884 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
13885 }
13886
13887 // check if iterator pos fits to this JSON value
13888 if (JSON_UNLIKELY(pos.m_object != this)) {
13889 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
13890 }
13891
13892 // insert to array and return iterator
13893 iterator result(this);
13894 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
13895 return result;
13896 }
13897
13921 void insert(const_iterator first, const_iterator last)
13922 {
13923 // insert only works for objects
13924 if (JSON_UNLIKELY(not is_object())) {
13925 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
13926 }
13927
13928 // check if range iterators belong to the same JSON object
13929 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
13930 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
13931 }
13932
13933 // passed iterators must belong to objects
13934 if (JSON_UNLIKELY(not first.m_object->is_object())) {
13935 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
13936 }
13937
13938 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
13939 }
13940
13960 void update(const_reference j)
13961 {
13962 // implicitly convert null value to an empty object
13963 if (is_null()) {
13964 m_type = value_t::object;
13965 m_value.object = create<object_t>();
13966 assert_invariant();
13967 }
13968
13969 if (JSON_UNLIKELY(not is_object())) {
13970 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
13971 }
13972 if (JSON_UNLIKELY(not j.is_object())) {
13973 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
13974 }
13975
13976 for (auto it = j.cbegin(); it != j.cend(); ++it) {
13977 m_value.object->operator[](it.key()) = it.value();
13978 }
13979 }
13980
14007 void update(const_iterator first, const_iterator last)
14008 {
14009 // implicitly convert null value to an empty object
14010 if (is_null()) {
14011 m_type = value_t::object;
14012 m_value.object = create<object_t>();
14013 assert_invariant();
14014 }
14015
14016 if (JSON_UNLIKELY(not is_object())) {
14017 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
14018 }
14019
14020 // check if range iterators belong to the same JSON object
14021 if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14022 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14023 }
14024
14025 // passed iterators must belong to objects
14026 if (JSON_UNLIKELY(not first.m_object->is_object() or not last.m_object->is_object())) {
14027 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
14028 }
14029
14030 for (auto it = first; it != last; ++it) {
14031 m_value.object->operator[](it.key()) = it.value();
14032 }
14033 }
14034
14052 void swap(reference other) noexcept(
14053 std::is_nothrow_move_constructible<value_t>::value and
14054 std::is_nothrow_move_assignable<value_t>::value and
14055 std::is_nothrow_move_constructible<json_value>::value and
14056 std::is_nothrow_move_assignable<json_value>::value)
14057 {
14058 std::swap(m_type, other.m_type);
14059 std::swap(m_value, other.m_value);
14060 assert_invariant();
14061 }
14062
14083 void swap(array_t& other)
14084 {
14085 // swap only works for arrays
14086 if (JSON_LIKELY(is_array())) {
14087 std::swap(*(m_value.array), other);
14088 } else {
14089 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14090 }
14091 }
14092
14113 void swap(object_t& other)
14114 {
14115 // swap only works for objects
14116 if (JSON_LIKELY(is_object())) {
14117 std::swap(*(m_value.object), other);
14118 } else {
14119 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14120 }
14121 }
14122
14143 void swap(string_t& other)
14144 {
14145 // swap only works for strings
14146 if (JSON_LIKELY(is_string())) {
14147 std::swap(*(m_value.string), other);
14148 } else {
14149 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14150 }
14151 }
14152
14154
14155 public:
14157 // lexicographical comparison operators //
14159
14162
14202 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
14203 {
14204 const auto lhs_type = lhs.type();
14205 const auto rhs_type = rhs.type();
14206
14207 if (lhs_type == rhs_type) {
14208 switch (lhs_type) {
14209 case value_t::array:
14210 return (*lhs.m_value.array == *rhs.m_value.array);
14211
14212 case value_t::object:
14213 return (*lhs.m_value.object == *rhs.m_value.object);
14214
14215 case value_t::null:
14216 return true;
14217
14218 case value_t::string:
14219 return (*lhs.m_value.string == *rhs.m_value.string);
14220
14221 case value_t::boolean:
14222 return (lhs.m_value.boolean == rhs.m_value.boolean);
14223
14224 case value_t::number_integer:
14225 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
14226
14227 case value_t::number_unsigned:
14228 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
14229
14230 case value_t::number_float:
14231 return (lhs.m_value.number_float == rhs.m_value.number_float);
14232
14233 default:
14234 return false;
14235 }
14236 } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14237 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
14238 } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14239 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
14240 } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14241 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
14242 } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14243 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
14244 } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14245 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
14246 } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14247 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
14248 }
14249
14250 return false;
14251 }
14252
14257 template <typename ScalarType, typename std::enable_if<
14258 std::is_scalar<ScalarType>::value, int>::type = 0>
14259 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
14260 {
14261 return (lhs == basic_json(rhs));
14262 }
14263
14268 template <typename ScalarType, typename std::enable_if<
14269 std::is_scalar<ScalarType>::value, int>::type = 0>
14270 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
14271 {
14272 return (basic_json(lhs) == rhs);
14273 }
14274
14293 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
14294 {
14295 return not(lhs == rhs);
14296 }
14297
14302 template <typename ScalarType, typename std::enable_if<
14303 std::is_scalar<ScalarType>::value, int>::type = 0>
14304 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
14305 {
14306 return (lhs != basic_json(rhs));
14307 }
14308
14313 template <typename ScalarType, typename std::enable_if<
14314 std::is_scalar<ScalarType>::value, int>::type = 0>
14315 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
14316 {
14317 return (basic_json(lhs) != rhs);
14318 }
14319
14346 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
14347 {
14348 const auto lhs_type = lhs.type();
14349 const auto rhs_type = rhs.type();
14350
14351 if (lhs_type == rhs_type) {
14352 switch (lhs_type) {
14353 case value_t::array:
14354 return (*lhs.m_value.array) < (*rhs.m_value.array);
14355
14356 case value_t::object:
14357 return *lhs.m_value.object < *rhs.m_value.object;
14358
14359 case value_t::null:
14360 return false;
14361
14362 case value_t::string:
14363 return *lhs.m_value.string < *rhs.m_value.string;
14364
14365 case value_t::boolean:
14366 return lhs.m_value.boolean < rhs.m_value.boolean;
14367
14368 case value_t::number_integer:
14369 return lhs.m_value.number_integer < rhs.m_value.number_integer;
14370
14371 case value_t::number_unsigned:
14372 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
14373
14374 case value_t::number_float:
14375 return lhs.m_value.number_float < rhs.m_value.number_float;
14376
14377 default:
14378 return false;
14379 }
14380 } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14381 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
14382 } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14383 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
14384 } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14385 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
14386 } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14387 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
14388 } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14389 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
14390 } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14391 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
14392 }
14393
14394 // We only reach this line if we cannot compare values. In that case,
14395 // we compare types. Note we have to call the operator explicitly,
14396 // because MSVC has problems otherwise.
14397 return operator<(lhs_type, rhs_type);
14398 }
14399
14404 template <typename ScalarType, typename std::enable_if<
14405 std::is_scalar<ScalarType>::value, int>::type = 0>
14406 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
14407 {
14408 return (lhs < basic_json(rhs));
14409 }
14410
14415 template <typename ScalarType, typename std::enable_if<
14416 std::is_scalar<ScalarType>::value, int>::type = 0>
14417 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
14418 {
14419 return (basic_json(lhs) < rhs);
14420 }
14421
14441 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
14442 {
14443 return not(rhs < lhs);
14444 }
14445
14450 template <typename ScalarType, typename std::enable_if<
14451 std::is_scalar<ScalarType>::value, int>::type = 0>
14452 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
14453 {
14454 return (lhs <= basic_json(rhs));
14455 }
14456
14461 template <typename ScalarType, typename std::enable_if<
14462 std::is_scalar<ScalarType>::value, int>::type = 0>
14463 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
14464 {
14465 return (basic_json(lhs) <= rhs);
14466 }
14467
14487 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
14488 {
14489 return not(lhs <= rhs);
14490 }
14491
14496 template <typename ScalarType, typename std::enable_if<
14497 std::is_scalar<ScalarType>::value, int>::type = 0>
14498 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
14499 {
14500 return (lhs > basic_json(rhs));
14501 }
14502
14507 template <typename ScalarType, typename std::enable_if<
14508 std::is_scalar<ScalarType>::value, int>::type = 0>
14509 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
14510 {
14511 return (basic_json(lhs) > rhs);
14512 }
14513
14533 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
14534 {
14535 return not(lhs < rhs);
14536 }
14537
14542 template <typename ScalarType, typename std::enable_if<
14543 std::is_scalar<ScalarType>::value, int>::type = 0>
14544 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
14545 {
14546 return (lhs >= basic_json(rhs));
14547 }
14548
14553 template <typename ScalarType, typename std::enable_if<
14554 std::is_scalar<ScalarType>::value, int>::type = 0>
14555 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
14556 {
14557 return (basic_json(lhs) >= rhs);
14558 }
14559
14561
14563 // serialization //
14565
14568
14600 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
14601 {
14602 // read width member and use it as indentation parameter if nonzero
14603 const bool pretty_print = (o.width() > 0);
14604 const auto indentation = (pretty_print ? o.width() : 0);
14605
14606 // reset width to 0 for subsequent calls to this stream
14607 o.width(0);
14608
14609 // do the actual serialization
14610 serializer s(detail::output_adapter<char>(o), o.fill());
14611 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
14612 return o;
14613 }
14614
14624 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
14625 {
14626 return o << j;
14627 }
14628
14630
14632 // deserialization //
14634
14637
14700 static basic_json parse(detail::input_adapter i,
14701 const parser_callback_t cb = nullptr,
14702 const bool allow_exceptions = true)
14703 {
14704 basic_json result;
14705 parser(i, cb, allow_exceptions).parse(true, result);
14706 return result;
14707 }
14708
14712 static basic_json parse(detail::input_adapter& i,
14713 const parser_callback_t cb = nullptr,
14714 const bool allow_exceptions = true)
14715 {
14716 basic_json result;
14717 parser(i, cb, allow_exceptions).parse(true, result);
14718 return result;
14719 }
14720
14721 static bool accept(detail::input_adapter i)
14722 {
14723 return parser(i).accept(true);
14724 }
14725
14726 static bool accept(detail::input_adapter& i)
14727 {
14728 return parser(i).accept(true);
14729 }
14730
14778 template <class IteratorType, typename std::enable_if<
14779 std::is_base_of<
14780 std::random_access_iterator_tag,
14781 typename std::iterator_traits<IteratorType>::iterator_category>::value,
14782 int>::type = 0>
14783 static basic_json parse(IteratorType first, IteratorType last,
14784 const parser_callback_t cb = nullptr,
14785 const bool allow_exceptions = true)
14786 {
14787 basic_json result;
14788 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
14789 return result;
14790 }
14791
14792 template <class IteratorType, typename std::enable_if<
14793 std::is_base_of<
14794 std::random_access_iterator_tag,
14795 typename std::iterator_traits<IteratorType>::iterator_category>::value,
14796 int>::type = 0>
14797 static bool accept(IteratorType first, IteratorType last)
14798 {
14799 return parser(detail::input_adapter(first, last)).accept(true);
14800 }
14801
14811 friend std::istream& operator<<(basic_json& j, std::istream& i)
14812 {
14813 return operator>>(i, j);
14814 }
14815
14841 friend std::istream& operator>>(std::istream& i, basic_json& j)
14842 {
14843 parser(detail::input_adapter(i)).parse(false, j);
14844 return i;
14845 }
14846
14848
14850 // convenience functions //
14852
14883 const char* type_name() const noexcept
14884 {
14885 {
14886 switch (m_type) {
14887 case value_t::null:
14888 return "null";
14889 case value_t::object:
14890 return "object";
14891 case value_t::array:
14892 return "array";
14893 case value_t::string:
14894 return "string";
14895 case value_t::boolean:
14896 return "boolean";
14897 case value_t::discarded:
14898 return "discarded";
14899 default:
14900 return "number";
14901 }
14902 }
14903 }
14904
14905 private:
14907 // member variables //
14909
14911 value_t m_type = value_t::null;
14912
14914 json_value m_value = {};
14915
14917 // binary serialization/deserialization //
14919
14922
14923 public:
15012 static std::vector<uint8_t> to_cbor(const basic_json& j)
15013 {
15014 std::vector<uint8_t> result;
15015 to_cbor(j, result);
15016 return result;
15017 }
15018
15019 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
15020 {
15021 binary_writer<uint8_t>(o).write_cbor(j);
15022 }
15023
15024 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
15025 {
15026 binary_writer<char>(o).write_cbor(j);
15027 }
15028
15109 static std::vector<uint8_t> to_msgpack(const basic_json& j)
15110 {
15111 std::vector<uint8_t> result;
15112 to_msgpack(j, result);
15113 return result;
15114 }
15115
15116 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
15117 {
15118 binary_writer<uint8_t>(o).write_msgpack(j);
15119 }
15120
15121 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
15122 {
15123 binary_writer<char>(o).write_msgpack(j);
15124 }
15125
15206 static std::vector<uint8_t> to_ubjson(const basic_json& j,
15207 const bool use_size = false,
15208 const bool use_type = false)
15209 {
15210 std::vector<uint8_t> result;
15211 to_ubjson(j, result, use_size, use_type);
15212 return result;
15213 }
15214
15215 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
15216 const bool use_size = false, const bool use_type = false)
15217 {
15218 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
15219 }
15220
15221 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
15222 const bool use_size = false, const bool use_type = false)
15223 {
15224 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
15225 }
15226
15320 static basic_json from_cbor(detail::input_adapter i,
15321 const bool strict = true)
15322 {
15323 return binary_reader(i).parse_cbor(strict);
15324 }
15325
15329 template <typename A1, typename A2,
15330 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15331 static basic_json from_cbor(A1&& a1, A2&& a2, const bool strict = true)
15332 {
15333 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
15334 }
15335
15409 static basic_json from_msgpack(detail::input_adapter i,
15410 const bool strict = true)
15411 {
15412 return binary_reader(i).parse_msgpack(strict);
15413 }
15414
15418 template <typename A1, typename A2,
15419 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15420 static basic_json from_msgpack(A1&& a1, A2&& a2, const bool strict = true)
15421 {
15422 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
15423 }
15424
15478 static basic_json from_ubjson(detail::input_adapter i,
15479 const bool strict = true)
15480 {
15481 return binary_reader(i).parse_ubjson(strict);
15482 }
15483
15484 template <typename A1, typename A2,
15485 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15486 static basic_json from_ubjson(A1&& a1, A2&& a2, const bool strict = true)
15487 {
15488 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
15489 }
15490
15492
15494 // JSON Pointer support //
15496
15499
15533 reference operator[](const json_pointer& ptr)
15534 {
15535 return ptr.get_unchecked(this);
15536 }
15537
15561 const_reference operator[](const json_pointer& ptr) const
15562 {
15563 return ptr.get_unchecked(this);
15564 }
15565
15604 reference at(const json_pointer& ptr)
15605 {
15606 return ptr.get_checked(this);
15607 }
15608
15647 const_reference at(const json_pointer& ptr) const
15648 {
15649 return ptr.get_checked(this);
15650 }
15651
15674 basic_json flatten() const
15675 {
15676 basic_json result(value_t::object);
15677 json_pointer::flatten("", *this, result);
15678 return result;
15679 }
15680
15711 basic_json unflatten() const
15712 {
15713 return json_pointer::unflatten(*this);
15714 }
15715
15717
15719 // JSON Patch functions //
15721
15724
15772 basic_json patch(const basic_json& json_patch) const
15773 {
15774 // make a working copy to apply the patch to
15775 basic_json result = *this;
15776
15777 // the valid JSON Patch operations
15778 enum class patch_operations { add,
15779 remove,
15780 replace,
15781 move,
15782 copy,
15783 test,
15784 invalid };
15785
15786 const auto get_op = [](const std::string& op) {
15787 if (op == "add") {
15788 return patch_operations::add;
15789 }
15790 if (op == "remove") {
15791 return patch_operations::remove;
15792 }
15793 if (op == "replace") {
15794 return patch_operations::replace;
15795 }
15796 if (op == "move") {
15797 return patch_operations::move;
15798 }
15799 if (op == "copy") {
15800 return patch_operations::copy;
15801 }
15802 if (op == "test") {
15803 return patch_operations::test;
15804 }
15805
15806 return patch_operations::invalid;
15807 };
15808
15809 // wrapper for "add" operation; add value at ptr
15810 const auto operation_add = [&result](json_pointer& ptr, basic_json val) {
15811 // adding to the root of the target document means replacing it
15812 if (ptr.is_root()) {
15813 result = val;
15814 } else {
15815 // make sure the top element of the pointer exists
15816 json_pointer top_pointer = ptr.top();
15817 if (top_pointer != ptr) {
15818 result.at(top_pointer);
15819 }
15820
15821 // get reference to parent of JSON pointer ptr
15822 const auto last_path = ptr.pop_back();
15823 basic_json& parent = result[ptr];
15824
15825 switch (parent.m_type) {
15826 case value_t::null:
15827 case value_t::object: {
15828 // use operator[] to add value
15829 parent[last_path] = val;
15830 break;
15831 }
15832
15833 case value_t::array: {
15834 if (last_path == "-") {
15835 // special case: append to back
15836 parent.push_back(val);
15837 } else {
15838 const auto idx = json_pointer::array_index(last_path);
15839 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size())) {
15840 // avoid undefined behavior
15841 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15842 } else {
15843 // default case: insert add offset
15844 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
15845 }
15846 }
15847 break;
15848 }
15849
15850 default: {
15851 // if there exists a parent it cannot be primitive
15852 assert(false); // LCOV_EXCL_LINE
15853 }
15854 }
15855 }
15856 };
15857
15858 // wrapper for "remove" operation; remove value at ptr
15859 const auto operation_remove = [&result](json_pointer& ptr) {
15860 // get reference to parent of JSON pointer ptr
15861 const auto last_path = ptr.pop_back();
15862 basic_json& parent = result.at(ptr);
15863
15864 // remove child
15865 if (parent.is_object()) {
15866 // perform range check
15867 auto it = parent.find(last_path);
15868 if (JSON_LIKELY(it != parent.end())) {
15869 parent.erase(it);
15870 } else {
15871 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
15872 }
15873 } else if (parent.is_array()) {
15874 // note erase performs range check
15875 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
15876 }
15877 };
15878
15879 // type check: top level value must be an array
15880 if (JSON_UNLIKELY(not json_patch.is_array())) {
15881 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
15882 }
15883
15884 // iterate and apply the operations
15885 for (const auto& val : json_patch) {
15886 // wrapper to get a value for an operation
15887 const auto get_value = [&val](const std::string& op,
15888 const std::string& member,
15889 bool string_type) -> basic_json& {
15890 // find value
15891 auto it = val.m_value.object->find(member);
15892
15893 // context-sensitive error message
15894 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
15895
15896 // check if desired value is present
15897 if (JSON_UNLIKELY(it == val.m_value.object->end())) {
15898 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
15899 }
15900
15901 // check if result is of type string
15902 if (JSON_UNLIKELY(string_type and not it->second.is_string())) {
15903 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
15904 }
15905
15906 // no error: return value
15907 return it->second;
15908 };
15909
15910 // type check: every element of the array must be an object
15911 if (JSON_UNLIKELY(not val.is_object())) {
15912 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
15913 }
15914
15915 // collect mandatory members
15916 const std::string op = get_value("op", "op", true);
15917 const std::string path = get_value(op, "path", true);
15918 json_pointer ptr(path);
15919
15920 switch (get_op(op)) {
15921 case patch_operations::add: {
15922 operation_add(ptr, get_value("add", "value", false));
15923 break;
15924 }
15925
15926 case patch_operations::remove: {
15927 operation_remove(ptr);
15928 break;
15929 }
15930
15931 case patch_operations::replace: {
15932 // the "path" location must exist - use at()
15933 result.at(ptr) = get_value("replace", "value", false);
15934 break;
15935 }
15936
15937 case patch_operations::move: {
15938 const std::string from_path = get_value("move", "from", true);
15939 json_pointer from_ptr(from_path);
15940
15941 // the "from" location must exist - use at()
15942 basic_json v = result.at(from_ptr);
15943
15944 // The move operation is functionally identical to a
15945 // "remove" operation on the "from" location, followed
15946 // immediately by an "add" operation at the target
15947 // location with the value that was just removed.
15948 operation_remove(from_ptr);
15949 operation_add(ptr, v);
15950 break;
15951 }
15952
15953 case patch_operations::copy: {
15954 const std::string from_path = get_value("copy", "from", true);
15955 const json_pointer from_ptr(from_path);
15956
15957 // the "from" location must exist - use at()
15958 basic_json v = result.at(from_ptr);
15959
15960 // The copy is functionally identical to an "add"
15961 // operation at the target location using the value
15962 // specified in the "from" member.
15963 operation_add(ptr, v);
15964 break;
15965 }
15966
15967 case patch_operations::test: {
15968 bool success = false;
15969 JSON_TRY
15970 {
15971 // check if "value" matches the one at "path"
15972 // the "path" location must exist - use at()
15973 success = (result.at(ptr) == get_value("test", "value", false));
15974 }
15975 JSON_CATCH(out_of_range&)
15976 {
15977 // ignore out of range errors: success remains false
15978 }
15979
15980 // throw an exception if test fails
15981 if (JSON_UNLIKELY(not success)) {
15982 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
15983 }
15984
15985 break;
15986 }
15987
15988 case patch_operations::invalid: {
15989 // op must be "add", "remove", "replace", "move", "copy", or
15990 // "test"
15991 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
15992 }
15993 }
15994 }
15995
15996 return result;
15997 }
15998
16032 static basic_json diff(const basic_json& source, const basic_json& target,
16033 const std::string& path = "")
16034 {
16035 // the patch
16036 basic_json result(value_t::array);
16037
16038 // if the values are the same, return empty patch
16039 if (source == target) {
16040 return result;
16041 }
16042
16043 if (source.type() != target.type()) {
16044 // different types: replace value
16045 result.push_back(
16046 {{"op", "replace"}, {"path", path}, {"value", target}});
16047 } else {
16048 switch (source.type()) {
16049 case value_t::array: {
16050 // first pass: traverse common elements
16051 std::size_t i = 0;
16052 while (i < source.size() and i < target.size()) {
16053 // recursive call to compare array values at index i
16054 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
16055 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
16056 ++i;
16057 }
16058
16059 // i now reached the end of at least one array
16060 // in a second pass, traverse the remaining elements
16061
16062 // remove my remaining elements
16063 const auto end_index = static_cast<difference_type>(result.size());
16064 while (i < source.size()) {
16065 // add operations in reverse order to avoid invalid
16066 // indices
16067 result.insert(result.begin() + end_index, object(
16068 {{"op", "remove"},
16069 {"path", path + "/" + std::to_string(i)}}));
16070 ++i;
16071 }
16072
16073 // add other remaining elements
16074 while (i < target.size()) {
16075 result.push_back(
16076 {{"op", "add"},
16077 {"path", path + "/" + std::to_string(i)},
16078 {"value", target[i]}});
16079 ++i;
16080 }
16081
16082 break;
16083 }
16084
16085 case value_t::object: {
16086 // first pass: traverse this object's elements
16087 for (auto it = source.cbegin(); it != source.cend(); ++it) {
16088 // escape the key name to be used in a JSON patch
16089 const auto key = json_pointer::escape(it.key());
16090
16091 if (target.find(it.key()) != target.end()) {
16092 // recursive call to compare object values at key it
16093 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
16094 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
16095 } else {
16096 // found a key that is not in o -> remove it
16097 result.push_back(object(
16098 {{"op", "remove"}, {"path", path + "/" + key}}));
16099 }
16100 }
16101
16102 // second pass: traverse other object's elements
16103 for (auto it = target.cbegin(); it != target.cend(); ++it) {
16104 if (source.find(it.key()) == source.end()) {
16105 // found a key that is not in this -> add it
16106 const auto key = json_pointer::escape(it.key());
16107 result.push_back(
16108 {{"op", "add"}, {"path", path + "/" + key}, {"value", it.value()}});
16109 }
16110 }
16111
16112 break;
16113 }
16114
16115 default: {
16116 // both primitive type: replace value
16117 result.push_back(
16118 {{"op", "replace"}, {"path", path}, {"value", target}});
16119 break;
16120 }
16121 }
16122 }
16123
16124 return result;
16125 }
16126
16128
16130 // JSON Merge Patch functions //
16132
16135
16178 void merge_patch(const basic_json& patch)
16179 {
16180 if (patch.is_object()) {
16181 if (not is_object()) {
16182 *this = object();
16183 }
16184 for (auto it = patch.begin(); it != patch.end(); ++it) {
16185 if (it.value().is_null()) {
16186 erase(it.key());
16187 } else {
16188 operator[](it.key()).merge_patch(it.value());
16189 }
16190 }
16191 } else {
16192 *this = patch;
16193 }
16194 }
16195
16197};
16198} // namespace nlohmann
16199
16201// nonmember support //
16203
16204// specialization of std::swap, and std::hash
16205namespace std
16206{
16212template <>
16213inline void swap(nlohmann::json& j1,
16214 nlohmann::json& j2) noexcept(is_nothrow_move_constructible<nlohmann::json>::value and
16215 is_nothrow_move_assignable<nlohmann::json>::value)
16216{
16217 j1.swap(j2);
16218}
16219
16221template <>
16222struct hash<nlohmann::json> {
16228 std::size_t operator()(const nlohmann::json& j) const
16229 {
16230 // a naive hashing via the string representation
16231 const auto& h = hash<nlohmann::json::string_t>();
16232 return h(j.dump());
16233 }
16234};
16235
16239template <>
16240struct less<::nlohmann::detail::value_t> {
16245 bool operator()(nlohmann::detail::value_t lhs,
16246 nlohmann::detail::value_t rhs) const noexcept
16247 {
16248 return nlohmann::detail::operator<(lhs, rhs);
16249 }
16250};
16251
16252} // namespace std
16253
16267inline nlohmann::json operator"" _json(const char* s, std::size_t n)
16268{
16269 return nlohmann::json::parse(s, s + n);
16270}
16271
16285inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n)
16286{
16287 return nlohmann::json::json_pointer(std::string(s, n));
16288}
16289
16290// #include <nlohmann/detail/macro_unscope.hpp>
16291
16292// restore GCC/clang diagnostic settings
16293#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
16294#pragma GCC diagnostic pop
16295#endif
16296#if defined(__clang__)
16297#pragma GCC diagnostic pop
16298#endif
16299
16300// clean up
16301#undef JSON_CATCH
16302#undef JSON_THROW
16303#undef JSON_TRY
16304#undef JSON_LIKELY
16305#undef JSON_UNLIKELY
16306#undef JSON_DEPRECATED
16307#undef JSON_HAS_CPP_14
16308#undef JSON_HAS_CPP_17
16309#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
16310#undef NLOHMANN_BASIC_JSON_TPL
16311#undef NLOHMANN_JSON_HAS_HELPER
16312
16313#endif
benchmark::State & state
std::ostream & operator<<(std::ostream &os, const o2::math_utils::Rotation2Df_t &t)
Definition Cartesian.cxx:57
uint64_t exp(uint64_t base, uint8_t exp) noexcept
int32_t i
uint32_t op
bool o
const GPUTPCGMMerger::trackCluster & a1
constexpr int p2()
constexpr int p1()
constexpr to accelerate the coordinates changing
uint16_t pos
Definition RawData.h:3
uint32_t one
Definition RawData.h:4
uint32_t j
Definition RawData.h:0
uint32_t res
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
std::istream & operator>>(std::istream &input, DataType &data)
TBranch * ptr
double num
StringRef key
Class for time synchronization of RawReader instances.
general exception of the basic_json class
Definition json.h:557
const int id
the id of the exception
Definition json.h:566
static std::string name(const std::string &ename, int id_)
Definition json.h:571
const char * what() const noexcept override
returns the explanatory string
Definition json.h:560
exception(int id_, const char *what_arg)
Definition json.h:569
exception indicating errors with iterators
Definition json.h:697
static invalid_iterator create(int id_, const std::string &what_arg)
Definition json.h:699
a template for a bidirectional iterator for the basic_json class
Definition json.h:3702
bool operator<(const iter_impl &other) const
comparison: smaller
Definition json.h:4034
iter_impl operator-(difference_type i) const
subtract from iterator
Definition json.h:4143
iter_impl()=default
default constructor
Definition json.h:3704
iter_impl const operator--(int)
post-decrement (it–)
Definition json.h:3961
bool operator==(const iter_impl &other) const
comparison: equal
Definition json.h:4000
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition json.h:3725
object_t::key_type key() const
return the key of an object iterator
Definition json.h:4202
iter_impl & operator--()
pre-decrement (–it)
Definition json.h:3972
difference_type operator-(const iter_impl &other) const
return difference
Definition json.h:4154
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition json.h:3734
reference operator*() const
return a reference to the value pointed to by the iterator
Definition json.h:3861
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition json.h:4077
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition json.h:3729
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition json.h:3790
pointer operator->() const
dereference the iterator
Definition json.h:3893
iter_impl const operator++(int)
post-increment (it++)
Definition json.h:3922
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition json.h:3781
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition json.h:3745
iter_impl operator+(difference_type i) const
add to iterator
Definition json.h:4121
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition json.h:4132
bool operator>(const iter_impl &other) const
comparison: greater than
Definition json.h:4068
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition json.h:3723
reference value() const
return the value of an iterator
Definition json.h:4217
iter_impl & operator++()
pre-increment (++it)
Definition json.h:3933
reference operator[](difference_type n) const
access to successor
Definition json.h:4174
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition json.h:4059
std::bidirectional_iterator_tag iterator_category
Definition json.h:3720
iter_impl & operator+=(difference_type i)
add to iterator
Definition json.h:4086
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition json.h:4025
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition json.h:4112
proxy class for the items() function
Definition json.h:4245
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition json.h:4322
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition json.h:4316
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition json.h:4312
a template for a reverse iterator class
Definition json.h:4364
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition json.h:4373
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition json.h:4392
typename Base::reference reference
the reference type for the pointed-to element
Definition json.h:4370
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition json.h:4416
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition json.h:4404
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition json.h:4368
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition json.h:4377
reference operator[](difference_type n) const
access to successor
Definition json.h:4428
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition json.h:4422
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition json.h:4410
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition json.h:4380
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition json.h:4434
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition json.h:4398
reference value() const
return the value of an iterator
Definition json.h:4441
json_reverse_iterator & operator++()
pre-increment (++it)
Definition json.h:4386
exception indicating other library errors
Definition json.h:831
static other_error create(int id_, const std::string &what_arg)
Definition json.h:833
exception indicating access out of the defined range
Definition json.h:794
static out_of_range create(int id_, const std::string &what_arg)
Definition json.h:796
output_adapter(std::vector< CharType > &vec)
Definition json.h:4544
output_adapter(std::basic_ostream< CharType > &s)
Definition json.h:4547
output_adapter(StringType &s)
Definition json.h:4550
output adapter for output streams
Definition json.h:4501
output_stream_adapter(std::basic_ostream< CharType > &s)
Definition json.h:4503
void write_character(CharType c) override
Definition json.h:4505
void write_characters(const CharType *s, std::size_t length) override
Definition json.h:4510
output adapter for basic_string
Definition json.h:4522
void write_character(CharType c) override
Definition json.h:4526
void write_characters(const CharType *s, std::size_t length) override
Definition json.h:4531
output adapter for byte vectors
Definition json.h:4480
output_vector_adapter(std::vector< CharType > &vec)
Definition json.h:4482
void write_characters(const CharType *s, std::size_t length) override
Definition json.h:4489
void write_character(CharType c) override
Definition json.h:4484
exception indicating a parse error
Definition json.h:625
const std::size_t byte
byte index of the parse error
Definition json.h:652
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition json.h:635
syntax analysis
Definition json.h:3017
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition json.h:3062
bool accept(const bool strict=true)
public accept interface
Definition json.h:3095
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
parser(detail::input_adapter_t adapter, const parser_callback_t cb=nullptr, const bool allow_exceptions_=true)
a parser reading from an input adapter
Definition json.h:3045
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
Definition json.h:3042
primitive_iterator_t operator+(difference_type n) noexcept
Definition json.h:3575
primitive_iterator_t & operator++() noexcept
Definition json.h:3587
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition json.h:3560
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition json.h:3619
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition json.h:3554
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.h:3570
void set_begin() noexcept
set iterator to a defined beginning
Definition json.h:3542
primitive_iterator_t const operator++(int) noexcept
Definition json.h:3593
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.h:3565
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.h:3582
primitive_iterator_t & operator--() noexcept
Definition json.h:3600
void set_end() noexcept
set iterator to a defined past the end
Definition json.h:3548
constexpr difference_type get_value() const noexcept
Definition json.h:3536
primitive_iterator_t const operator--(int) noexcept
Definition json.h:3606
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition json.h:3613
exception indicating executing a member function with a wrong type
Definition json.h:749
static type_error create(int id_, const std::string &what_arg)
Definition json.h:751
JSON Pointer.
Definition json.h:110
void dump(const std::string what, DPMAP m, int verbose)
Definition dcs-ccdb.cxx:79
struct _cl_event * event
Definition glcorearb.h:2982
GLsizei const GLchar *const * string
Definition glcorearb.h:809
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLenum void ** pointer
Definition glcorearb.h:805
GLint GLsizei count
Definition glcorearb.h:399
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint buffer
Definition glcorearb.h:655
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
const GLdouble * v
Definition glcorearb.h:832
GLenum array
Definition glcorearb.h:4274
GLuint index
Definition glcorearb.h:781
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLint first
Definition glcorearb.h:399
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLenum GLint * range
Definition glcorearb.h:1899
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum target
Definition glcorearb.h:1641
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition glcorearb.h:4150
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat * val
Definition glcorearb.h:1582
GLint GLint GLsizei GLsizei GLsizei depth
Definition glcorearb.h:470
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLuint object
Definition glcorearb.h:4041
GLboolean r
Definition glcorearb.h:1233
GLuint start
Definition glcorearb.h:469
GLenum GLenum GLsizei len
Definition glcorearb.h:4232
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLuint stream
Definition glcorearb.h:1806
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glcorearb.h:2514
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLuint id
Definition glcorearb.h:650
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition json.h:207
#define NLOHMANN_JSON_VERSION_PATCH
Definition json.h:45
#define JSON_LIKELY(x)
Definition json.h:192
#define JSON_DEPRECATED
Definition json.h:159
#define JSON_CATCH(exception)
Definition json.h:170
#define JSON_THROW(exception)
Definition json.h:168
#define NLOHMANN_JSON_VERSION_MAJOR
Definition json.h:43
#define NLOHMANN_BASIC_JSON_TPL
Definition json.h:215
#define JSON_TRY
Definition json.h:169
#define NLOHMANN_JSON_VERSION_MINOR
Definition json.h:44
#define JSON_UNLIKELY(x)
Definition json.h:193
#define NLOHMANN_JSON_HAS_HELPER(type)
Helper to determine whether there's a key_type for T.
Definition json.h:230
auto operator+=(std::string &lhs, StringRef rhs) -> std::string &
typename std::enable_if< B, T >::type enable_if_t
Definition json.h:281
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition json.h:284
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition json.h:4475
namespace for Niels Lohmann
Definition json.h:75
uint8_t itsSharedClusterMap uint8_t
bool operator<(EntryPM const &entryPM1, EntryPM const &entryPM2)
Definition LookUpTable.h:89
ConcreteParserVariants< PageSize, BOUNDS_CHECKS > create(T const *buffer, size_t size)
create a raw parser depending on version of RAWDataHeader found at beginning of data
Definition RawParser.h:378
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:454
D const SVectorGPU< T, D > & rhs
Definition SMatrixGPU.h:191
MultPolicyGPU< T, R1, R2 >::RepType operator*(const SMatrixGPU< T, D1, D, R1 > &lhs, const SMatrixGPU< T, D, D2, R2 > &rhs)
Definition SMatrixGPU.h:748
Enum< T >::Iterator begin(Enum< T >)
Definition Defs.h:173
return(kp2 - aa - bb) *kp1/aa
bool operator!=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator<=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator>=(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
bool operator>(const observer_ptr< W1 > &p1, const observer_ptr< W2 > &p2)
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
FIXME: do not use data model tables.
void empty(int)
std::vector< std::string > split(const std::string &str, char delimiter=',')
default JSONSerializer template argument
Definition json.h:84
static constexpr std::size_t size() noexcept
Definition json.h:292
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition json.h:3649
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition json.h:3647
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition json.h:3645
abstract output adapter interface
Definition json.h:4467
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
static constexpr T value
Definition json.h:506
bool operator==(const CoarseLocation &a, const CoarseLocation &b)
VectorOfTObjectPtrs other
std::vector< o2::ctf::BufferType > vec
coder decode(ctfImage, triggersD, clustersD)
vec clear()
const std::string str