Libsaki
Core library of Pancake Mahjong
json.hpp
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.1.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28 
29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
31 
32 #define NLOHMANN_JSON_VERSION_MAJOR 3
33 #define NLOHMANN_JSON_VERSION_MINOR 1
34 #define NLOHMANN_JSON_VERSION_PATCH 1
35 
36 #include <algorithm> // all_of, find, for_each
37 #include <cassert> // assert
38 #include <ciso646> // and, not, or
39 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
40 #include <functional> // hash, less
41 #include <initializer_list> // initializer_list
42 #include <iosfwd> // istream, ostream
43 #include <iterator> // iterator_traits, random_access_iterator_tag
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 
48 // #include <nlohmann/json_fwd.hpp>
49 #ifndef NLOHMANN_JSON_FWD_HPP
50 #define NLOHMANN_JSON_FWD_HPP
51 
52 #include <cstdint> // int64_t, uint64_t
53 #include <map> // map
54 #include <memory> // allocator
55 #include <string> // string
56 #include <vector> // vector
57 
63 namespace nlohmann
64 {
72 template<typename = void, typename = void>
74 
75 template<template<typename U, typename V, typename... Args> class ObjectType =
76  std::map,
77  template<typename U, typename... Args> class ArrayType = std::vector,
78  class StringType = std::string, class BooleanType = bool,
79  class NumberIntegerType = std::int64_t,
80  class NumberUnsignedType = std::uint64_t,
81  class NumberFloatType = double,
82  template<typename U> class AllocatorType = std::allocator,
83  template<typename T, typename SFINAE = void> class JSONSerializer =
85 class basic_json;
86 
98 template<typename BasicJsonType>
100 
110 } // namespace nlohmann
111 
112 #endif
113 
114 // #include <nlohmann/detail/macro_scope.hpp>
115 
116 
117 // This file contains all internal macro definitions
118 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
119 
120 // exclude unsupported compilers
121 #if defined(__clang__)
122  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
123  #error "unsupported Clang version - see https:// github.com/nlohmann/json#supported-compilers"
124  #endif
125 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
126  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
127  #error "unsupported GCC version - see https:// github.com/nlohmann/json#supported-compilers"
128  #endif
129 #endif
130 
131 // disable float-equal warnings on GCC/clang
132 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
133  #pragma GCC diagnostic push
134  #pragma GCC diagnostic ignored "-Wfloat-equal"
135 #endif
136 
137 // disable documentation warnings on clang
138 #if defined(__clang__)
139  #pragma GCC diagnostic push
140  #pragma GCC diagnostic ignored "-Wdocumentation"
141 #endif
142 
143 // allow for portable deprecation warnings
144 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
145  #define JSON_DEPRECATED __attribute__ ((deprecated))
146 #elif defined(_MSC_VER)
147  #define JSON_DEPRECATED __declspec(deprecated)
148 #else
149  #define JSON_DEPRECATED
150 #endif
151 
152 // allow to disable exceptions
153 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
154  #define JSON_THROW(exception) throw exception
155  #define JSON_TRY try
156  #define JSON_CATCH(exception) catch (exception)
157 #else
158  #define JSON_THROW(exception) std::abort()
159  #define JSON_TRY if (true)
160  #define JSON_CATCH(exception) if (false)
161 #endif
162 
163 // override exception macros
164 #if defined(JSON_THROW_USER)
165  #undef JSON_THROW
166  #define JSON_THROW JSON_THROW_USER
167 #endif
168 #if defined(JSON_TRY_USER)
169  #undef JSON_TRY
170  #define JSON_TRY JSON_TRY_USER
171 #endif
172 #if defined(JSON_CATCH_USER)
173  #undef JSON_CATCH
174  #define JSON_CATCH JSON_CATCH_USER
175 #endif
176 
177 // manual branch prediction
178 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
179  #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
180  #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
181 #else
182  #define JSON_LIKELY(x) x
183  #define JSON_UNLIKELY(x) x
184 #endif
185 
186 // C++ language standard detection
187 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
188  #define JSON_HAS_CPP_17
189  #define JSON_HAS_CPP_14
190 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
191  #define JSON_HAS_CPP_14
192 #endif
193 
194 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
195 // may be removed in the future once the class is split.
196 
197 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
198  template<template<typename, typename, typename...> class ObjectType, \
199  template<typename, typename...> class ArrayType, \
200  class StringType, class BooleanType, class NumberIntegerType, \
201  class NumberUnsignedType, class NumberFloatType, \
202  template<typename> class AllocatorType, \
203  template<typename, typename = void> class JSONSerializer>
204 
205 #define NLOHMANN_BASIC_JSON_TPL \
206  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
207  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
208  AllocatorType, JSONSerializer>
209 
220 #define NLOHMANN_JSON_HAS_HELPER(type) \
221  template<typename T> struct has_ ## type { \
222  private: \
223  template<typename U, typename = typename U::type> \
224  static int detect(U &&); \
225  static void detect(...); \
226  public: \
227  static constexpr bool value = \
228  std::is_integral<decltype(detect(std::declval<T>()))>::value; \
229  }
230 
231 // #include <nlohmann/detail/meta.hpp>
232 
233 
234 #include <ciso646> // not
235 #include <cstddef> // size_t
236 #include <limits> // numeric_limits
237 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
238 #include <utility> // declval
239 
240 // #include <nlohmann/json_fwd.hpp>
241 
242 // #include <nlohmann/detail/macro_scope.hpp>
243 
244 
245 namespace nlohmann
246 {
255 namespace detail
256 {
258 // helpers //
260 
261 template<typename> struct is_basic_json : std::false_type {};
262 
263 NLOHMANN_BASIC_JSON_TPL_DECLARATION
264 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
265 
266 // alias templates to reduce boilerplate
267 template<bool B, typename T = void>
268 using enable_if_t = typename std::enable_if<B, T>::type;
269 
270 template<typename T>
271 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
272 
273 // implementation of C++14 index_sequence and affiliates
274 // source: https://stackoverflow.com/a/32223343
275 template<std::size_t... Ints>
277 {
278  using type = index_sequence;
279  using value_type = std::size_t;
280  static constexpr std::size_t size() noexcept
281  {
282  return sizeof ... (Ints);
283  }
284 };
285 
286 template<class Sequence1, class Sequence2>
288 
289 template<std::size_t... I1, std::size_t... I2>
291  : index_sequence<I1..., (sizeof ... (I1) +I2) ...> {};
292 
293 template<std::size_t N>
295  : merge_and_renumber<typename make_index_sequence<N / 2>::type,
296  typename make_index_sequence<N - N / 2>::type> {};
297 
298 template<> struct make_index_sequence<0> : index_sequence<> {};
299 
300 template<> struct make_index_sequence<1> : index_sequence<0> {};
301 
302 template<typename... Ts>
303 using index_sequence_for = make_index_sequence<sizeof ... (Ts)>;
304 
305 /*
306 Implementation of two C++17 constructs: conjunction, negation. This is needed
307 to avoid evaluating all the traits in a condition
308 
309 For example: not std::is_same<void, T>::value and has_value_type<T>::value
310 will not compile when T = void (on MSVC at least). Whereas
311 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
312 stop evaluating if negation<...>::value == false
313 
314 Please note that those constructs must be used with caution, since symbols can
315 become very long quickly (which can slow down compilation and cause MSVC
316 internal compiler errors). Only use it when you have to (see example ahead).
317 */
318 template<class...> struct conjunction : std::true_type {};
319 
320 template<class B1> struct conjunction<B1> : B1 {};
321 
322 template<class B1, class... Bn>
323 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
324 
325 template<class B> struct negation : std::integral_constant<bool, not B::value> {};
326 
327 // dispatch utility (taken from ranges-v3)
328 template<unsigned N> struct priority_tag : priority_tag<N - 1> {};
329 
330 template<> struct priority_tag<0> {};
331 
333 // has_/is_ functions //
335 
336 // source: https://stackoverflow.com/a/37193089/4116453
337 
338 template<typename T, typename = void>
339 struct is_complete_type : std::false_type {};
340 
341 template<typename T>
342 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
343 
344 NLOHMANN_JSON_HAS_HELPER(mapped_type);
345 NLOHMANN_JSON_HAS_HELPER(key_type);
346 NLOHMANN_JSON_HAS_HELPER(value_type);
347 NLOHMANN_JSON_HAS_HELPER(iterator);
348 
349 template<bool B, class RealType, class CompatibleObjectType>
350 struct is_compatible_object_type_impl : std::false_type {};
351 
352 template<class RealType, class CompatibleObjectType>
353 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
354 {
355  static constexpr auto value =
356  std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
357  std::is_constructible<typename RealType::mapped_type,
358  typename CompatibleObjectType::mapped_type>::value;
359 };
360 
361 template<class BasicJsonType, class CompatibleObjectType>
363 {
364  static auto constexpr value = is_compatible_object_type_impl<
366  has_mapped_type<CompatibleObjectType>,
367  has_key_type<CompatibleObjectType>>::value,
368  typename BasicJsonType::object_t, CompatibleObjectType>::value;
369 };
370 
371 template<typename BasicJsonType, typename T>
373 {
374  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
375  std::is_same<T, typename BasicJsonType::const_iterator>::value or
376  std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
377  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
378 };
379 
380 template<class BasicJsonType, class CompatibleArrayType>
382 {
383  static auto constexpr value =
386  BasicJsonType, CompatibleArrayType>>,
387  negation<std::is_constructible<typename BasicJsonType::string_t,
388  CompatibleArrayType>>,
390  has_value_type<CompatibleArrayType>,
391  has_iterator<CompatibleArrayType>>::value;
392 };
393 
394 template<bool, typename, typename>
395 struct is_compatible_integer_type_impl : std::false_type {};
396 
397 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
398 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
399 {
400  // is there an assert somewhere on overflows?
401  using RealLimits = std::numeric_limits<RealIntegerType>;
402  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
403 
404  static constexpr auto value =
405  std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
406  CompatibleLimits::is_integer and
407  RealLimits::is_signed == CompatibleLimits::is_signed;
408 };
409 
410 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
412 {
413  static constexpr auto value =
415  std::is_integral<CompatibleNumberIntegerType>::value and
416  not std::is_same<bool, CompatibleNumberIntegerType>::value,
417  RealIntegerType, CompatibleNumberIntegerType>::value;
418 };
419 
420 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
421 template<typename BasicJsonType, typename T>
423 {
424 private:
425  // also check the return type of from_json
426  template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
427  std::declval<BasicJsonType>(),
428  std::declval<T &>()))>::value>>
429  static int detect(U &&);
430  static void detect(...);
431 
432 public:
433  static constexpr bool value = std::is_integral<decltype(
434  detect(std::declval<typename BasicJsonType::template json_serializer<T,
435  void>>()))>
436  ::value;
437 };
438 
439 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
440 // this overload is used for non-default-constructible user-defined-types
441 template<typename BasicJsonType, typename T>
443 {
444 private:
445  template<
446  typename U,
447  typename = enable_if_t<std::is_same<
448  T,
449  decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value>>
450  static int detect(U &&);
451  static void detect(...);
452 
453 public:
454  static constexpr bool value = std::is_integral<decltype(detect(
455  std::declval<typename BasicJsonType::template json_serializer<T,
456  void>>()))>
457  ::value;
458 };
459 
460 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
461 template<typename BasicJsonType, typename T>
463 {
464 private:
465  template<typename U, typename = decltype(uncvref_t<U>::to_json(
466  std::declval<BasicJsonType &>(), std::declval<T>()))>
467  static int detect(U &&);
468  static void detect(...);
469 
470 public:
471  static constexpr bool value = std::is_integral<decltype(detect(
472  std::declval<typename BasicJsonType::template json_serializer<T,
473  void>>()))>
474  ::value;
475 };
476 
477 template<typename BasicJsonType, typename CompatibleCompleteType>
479 {
480  static constexpr bool value =
481  not std::is_base_of<std::istream, CompatibleCompleteType>::value and
482  not std::is_same<BasicJsonType, CompatibleCompleteType>::value and
485 };
486 
487 template<typename BasicJsonType, typename CompatibleType>
489  : conjunction<is_complete_type<CompatibleType>,
490  is_compatible_complete_type<BasicJsonType, CompatibleType>>
491 {
492 };
493 
494 // taken from ranges-v3
495 template<typename T>
497 {
498  static constexpr T value {};
499 };
500 
501 template<typename T>
502 constexpr T static_const<T>::value;
503 } // namespace detail
504 } // namespace nlohmann
505 
506 // #include <nlohmann/detail/exceptions.hpp>
507 
508 
509 #include <exception> // exception
510 #include <stdexcept> // runtime_error
511 #include <string> // to_string
512 
513 namespace nlohmann
514 {
515 namespace detail
516 {
518 // exceptions //
520 
549 class exception : public std::exception
550 {
551 public:
553  const char *what() const noexcept override
554  {
555  return m.what();
556  }
557 
559  const int id;
560 
561 protected:
562  exception(int id_, const char *what_arg) : id(id_), m(what_arg) {}
563 
564  static std::string name(const std::string &ename, int id_)
565  {
566  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
567  }
568 
569 private:
571  std::runtime_error m;
572 };
573 
617 class parse_error : public exception
618 {
619 public:
628  static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
629  {
630  std::string w = exception::name("parse_error", id_) + "parse error" +
631  (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
632  ": " + what_arg;
633  return parse_error(id_, byte_, w.c_str());
634  }
635 
645  const std::size_t byte;
646 
647 private:
648  parse_error(int id_, std::size_t byte_, const char *what_arg)
649  : exception(id_, what_arg), byte(byte_) {}
650 };
651 
690 {
691 public:
692  static invalid_iterator create(int id_, const std::string &what_arg)
693  {
694  std::string w = exception::name("invalid_iterator", id_) + what_arg;
695  return invalid_iterator(id_, w.c_str());
696  }
697 
698 private:
699  invalid_iterator(int id_, const char *what_arg)
700  : exception(id_, what_arg) {}
701 };
702 
741 class type_error : public exception
742 {
743 public:
744  static type_error create(int id_, const std::string &what_arg)
745  {
746  std::string w = exception::name("type_error", id_) + what_arg;
747  return type_error(id_, w.c_str());
748  }
749 
750 private:
751  type_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
752 };
753 
786 class out_of_range : public exception
787 {
788 public:
789  static out_of_range create(int id_, const std::string &what_arg)
790  {
791  std::string w = exception::name("out_of_range", id_) + what_arg;
792  return out_of_range(id_, w.c_str());
793  }
794 
795 private:
796  out_of_range(int id_, const char *what_arg) : exception(id_, what_arg) {}
797 };
798 
824 class other_error : public exception
825 {
826 public:
827  static other_error create(int id_, const std::string &what_arg)
828  {
829  std::string w = exception::name("other_error", id_) + what_arg;
830  return other_error(id_, w.c_str());
831  }
832 
833 private:
834  other_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
835 };
836 
837 } // namespace detail
838 } // namespace nlohmann
839 
840 // #include <nlohmann/detail/value_t.hpp>
841 
842 
843 #include <array> // array
844 #include <ciso646> // and
845 #include <cstddef> // size_t
846 #include <cstdint> // uint8_t
847 
848 namespace nlohmann
849 {
850 namespace detail
851 {
853 // JSON type enumeration //
855 
880 enum class value_t : std::uint8_t
881 {
882  null,
883  object,
884  array,
885  string,
886  boolean,
889  number_float,
890  discarded
891 };
892 
903 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
904 {
905  static constexpr std::array<std::uint8_t, 8> order = { {
906  0 /* null */, 3 /* object */, 4 /* array */,
907  5 /* string */,
908  1 /* boolean */, 2 /* integer */,
909  2 /* unsigned */, 2 /* float */
910  } };
911 
912  const auto l_index = static_cast<std::size_t>(lhs);
913  const auto r_index = static_cast<std::size_t>(rhs);
914  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
915 }
916 } // namespace detail
917 } // namespace nlohmann
918 
919 // #include <nlohmann/detail/conversions/from_json.hpp>
920 
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 
941 
942 namespace nlohmann
943 {
944 namespace detail
945 {
946 // overloads for basic_json template parameters
947 template<typename BasicJsonType, typename ArithmeticType,
948  enable_if_t<std::is_arithmetic<ArithmeticType>::value and
949  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
950  int> = 0>
951 void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
952 {
953  switch (static_cast<value_t>(j)) {
955  {
956  val =
957  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
958  break;
959  }
961  {
962  val =
963  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
964  break;
965  }
967  {
968  val =
969  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
970  break;
971  }
972 
973  default:
974  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
975  }
976 }
977 
978 template<typename BasicJsonType>
979 void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
980 {
981  if (JSON_UNLIKELY(not j.is_boolean())) {
982  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
983  }
984 
985  b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
986 }
987 
988 template<typename BasicJsonType>
989 void from_json(const BasicJsonType &j, typename BasicJsonType::string_t &s)
990 {
991  if (JSON_UNLIKELY(not j.is_string())) {
992  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
993  }
994 
995  s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
996 }
997 
998 template<typename BasicJsonType>
999 void from_json(const BasicJsonType &j, typename BasicJsonType::number_float_t &val)
1000 {
1001  get_arithmetic_value(j, val);
1002 }
1003 
1004 template<typename BasicJsonType>
1005 void from_json(const BasicJsonType &j, typename BasicJsonType::number_unsigned_t &val)
1006 {
1007  get_arithmetic_value(j, val);
1008 }
1009 
1010 template<typename BasicJsonType>
1011 void from_json(const BasicJsonType &j, typename BasicJsonType::number_integer_t &val)
1012 {
1013  get_arithmetic_value(j, val);
1014 }
1015 
1016 template<typename BasicJsonType, typename EnumType,
1017  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1018 void from_json(const BasicJsonType &j, EnumType &e)
1019 {
1020  typename std::underlying_type<EnumType>::type val;
1021  get_arithmetic_value(j, val);
1022  e = static_cast<EnumType>(val);
1023 }
1024 
1025 template<typename BasicJsonType>
1026 void from_json(const BasicJsonType &j, typename BasicJsonType::array_t &arr)
1027 {
1028  if (JSON_UNLIKELY(not j.is_array())) {
1029  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1030  }
1031 
1032  arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
1033 }
1034 
1035 // forward_list doesn't have an insert method
1036 template<typename BasicJsonType, typename T, typename Allocator,
1037  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1038 void from_json(const BasicJsonType &j, std::forward_list<T, Allocator> &l)
1039 {
1040  if (JSON_UNLIKELY(not j.is_array())) {
1041  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1042  }
1043 
1044  std::transform(j.rbegin(), j.rend(),
1045  std::front_inserter(l), [](const BasicJsonType &i) {
1046  return i.template get<T>();
1047  });
1048 }
1049 
1050 // valarray doesn't have an insert method
1051 template<typename BasicJsonType, typename T,
1052  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1053 void from_json(const BasicJsonType &j, std::valarray<T> &l)
1054 {
1055  if (JSON_UNLIKELY(not j.is_array())) {
1056  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1057  }
1058 
1059  l.resize(j.size());
1060  std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1061 }
1062 
1063 template<typename BasicJsonType, typename CompatibleArrayType>
1064 void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<0> /*unused*/)
1065 {
1066  using std::end;
1067 
1068  std::transform(j.begin(), j.end(),
1069  std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
1070  // get<BasicJsonType>() returns *this, this won't call a from_json
1071  // method when value_type is BasicJsonType
1072  return i.template get<typename CompatibleArrayType::value_type>();
1073  });
1074 }
1075 
1076 template<typename BasicJsonType, typename CompatibleArrayType>
1077 auto from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag<1> /*unused*/)
1078 ->decltype(
1079  arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1080  void ())
1081 {
1082  using std::end;
1083 
1084  arr.reserve(j.size());
1085  std::transform(j.begin(), j.end(),
1086  std::inserter(arr, end(arr)), [](const BasicJsonType &i) {
1087  // get<BasicJsonType>() returns *this, this won't call a from_json
1088  // method when value_type is BasicJsonType
1089  return i.template get<typename CompatibleArrayType::value_type>();
1090  });
1091 }
1092 
1093 template<typename BasicJsonType, typename T, std::size_t N>
1094 void from_json_array_impl(const BasicJsonType &j, std::array<T, N> &arr, priority_tag<2> /*unused*/)
1095 {
1096  for (std::size_t i = 0; i < N; ++i) {
1097  arr[i] = j.at(i).template get<T>();
1098  }
1099 }
1100 
1101 template<
1102  typename BasicJsonType, typename CompatibleArrayType,
1103  enable_if_t<
1105  not std::is_same<typename BasicJsonType::array_t,
1106  CompatibleArrayType>::value and
1107  std::is_constructible<
1108  BasicJsonType, typename CompatibleArrayType::value_type>::value,
1109  int> = 0>
1110 void from_json(const BasicJsonType &j, CompatibleArrayType &arr)
1111 {
1112  if (JSON_UNLIKELY(not j.is_array())) {
1113  JSON_THROW(type_error::create(302, "type must be array, but is " +
1114  std::string(j.type_name())));
1115  }
1116 
1117  from_json_array_impl(j, arr, priority_tag<2> {});
1118 }
1119 
1120 template<typename BasicJsonType, typename CompatibleObjectType,
1121  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1122 void from_json(const BasicJsonType &j, CompatibleObjectType &obj)
1123 {
1124  if (JSON_UNLIKELY(not j.is_object())) {
1125  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1126  }
1127 
1128  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
1129  using value_type = typename CompatibleObjectType::value_type;
1130  std::transform(
1131  inner_object->begin(), inner_object->end(),
1132  std::inserter(obj, obj.begin()),
1133  [](typename BasicJsonType::object_t::value_type const &p) {
1134  return value_type(p.first,
1135  p.second.template get<typename CompatibleObjectType::mapped_type>());
1136  });
1137 }
1138 
1139 // overload for arithmetic types, not chosen for basic_json template arguments
1140 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1141 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1142 // an arithmetic type?
1143 template<typename BasicJsonType, typename ArithmeticType,
1144  enable_if_t<
1145  std::is_arithmetic<ArithmeticType>::value and
1146  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1147  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1148  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1149  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1150  int> = 0>
1151 void from_json(const BasicJsonType &j, ArithmeticType &val)
1152 {
1153  switch (static_cast<value_t>(j)) {
1155  {
1156  val =
1157  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
1158  break;
1159  }
1161  {
1162  val =
1163  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
1164  break;
1165  }
1166  case value_t::number_float:
1167  {
1168  val =
1169  static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
1170  break;
1171  }
1172  case value_t::boolean:
1173  {
1174  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
1175  break;
1176  }
1177 
1178  default:
1179  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1180  }
1181 }
1182 
1183 template<typename BasicJsonType, typename A1, typename A2>
1184 void from_json(const BasicJsonType &j, std::pair<A1, A2> &p)
1185 {
1186  p = { j.at(0).template get<A1>(), j.at(1).template get<A2>() };
1187 }
1188 
1189 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1190 void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence<Idx...> )
1191 {
1192  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>() ...);
1193 }
1194 
1195 template<typename BasicJsonType, typename... Args>
1196 void from_json(const BasicJsonType &j, std::tuple<Args...> &t)
1197 {
1198  from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1199 }
1200 
1202 {
1203 private:
1204  template<typename BasicJsonType, typename T>
1205  auto call(const BasicJsonType &j, T &val, priority_tag<1> /*unused*/) const
1206  noexcept (noexcept (from_json(j, val)))
1207  ->decltype(from_json(j, val), void ())
1208  {
1209  return from_json(j, val);
1210  }
1211 
1212  template<typename BasicJsonType, typename T>
1213  void call(const BasicJsonType & /*unused*/, T & /*unused*/, priority_tag<0> /*unused*/) const noexcept
1214  {
1215  static_assert(sizeof(BasicJsonType) == 0,
1216  "could not find from_json() method in T's namespace");
1217 #ifdef _MSC_VER
1218  // MSVC does not show a stacktrace for the above assert
1219  using decayed = uncvref_t<T>;
1220  static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1221  "forcing MSVC stacktrace to show which T we're talking about.");
1222 #endif
1223  }
1224 
1225 public:
1226  template<typename BasicJsonType, typename T>
1227  void operator()(const BasicJsonType &j, T &val) const
1228  noexcept (noexcept (std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1229  {
1230  return call(j, val, priority_tag<1> {});
1231  }
1232 };
1233 
1234 } // namespace detail
1235 
1239 namespace
1240 {
1241 constexpr const auto &from_json = detail::static_const<detail::from_json_fn>::value;
1242 } // namespace
1243 } // namespace nlohmann
1244 
1245 // #include <nlohmann/detail/conversions/to_json.hpp>
1246 
1247 
1248 #include <ciso646> // or, and, not
1249 #include <iterator> // begin, end
1250 #include <tuple> // tuple, get
1251 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1252 #include <utility> // move, forward, declval, pair
1253 #include <valarray> // valarray
1254 #include <vector> // vector
1255 
1256 // #include <nlohmann/detail/meta.hpp>
1257 
1258 // #include <nlohmann/detail/value_t.hpp>
1259 
1260 
1261 namespace nlohmann
1262 {
1263 namespace detail
1264 {
1266 // constructors //
1268 
1269 template<value_t> struct external_constructor;
1270 
1271 template<>
1273 {
1274  template<typename BasicJsonType>
1275  static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
1276  {
1277  j.m_type = value_t::boolean;
1278  j.m_value = b;
1279  j.assert_invariant();
1280  }
1281 };
1282 
1283 template<>
1285 {
1286  template<typename BasicJsonType>
1287  static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
1288  {
1289  j.m_type = value_t::string;
1290  j.m_value = s;
1291  j.assert_invariant();
1292  }
1293 
1294  template<typename BasicJsonType>
1295  static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
1296  {
1297  j.m_type = value_t::string;
1298  j.m_value = std::move(s);
1299  j.assert_invariant();
1300  }
1301 };
1302 
1303 template<>
1305 {
1306  template<typename BasicJsonType>
1307  static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
1308  {
1309  j.m_type = value_t::number_float;
1310  j.m_value = val;
1311  j.assert_invariant();
1312  }
1313 };
1314 
1315 template<>
1317 {
1318  template<typename BasicJsonType>
1319  static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
1320  {
1321  j.m_type = value_t::number_unsigned;
1322  j.m_value = val;
1323  j.assert_invariant();
1324  }
1325 };
1326 
1327 template<>
1329 {
1330  template<typename BasicJsonType>
1331  static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
1332  {
1333  j.m_type = value_t::number_integer;
1334  j.m_value = val;
1335  j.assert_invariant();
1336  }
1337 };
1338 
1339 template<>
1341 {
1342  template<typename BasicJsonType>
1343  static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
1344  {
1345  j.m_type = value_t::array;
1346  j.m_value = arr;
1347  j.assert_invariant();
1348  }
1349 
1350  template<typename BasicJsonType>
1351  static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
1352  {
1353  j.m_type = value_t::array;
1354  j.m_value = std::move(arr);
1355  j.assert_invariant();
1356  }
1357 
1358  template<typename BasicJsonType, typename CompatibleArrayType,
1359  enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1360  int> = 0>
1361  static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
1362  {
1363  using std::begin;
1364  using std::end;
1365  j.m_type = value_t::array;
1366  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1367  j.assert_invariant();
1368  }
1369 
1370  template<typename BasicJsonType>
1371  static void construct(BasicJsonType &j, const std::vector<bool> &arr)
1372  {
1373  j.m_type = value_t::array;
1374  j.m_value = value_t::array;
1375  j.m_value.array->reserve(arr.size());
1376  for (const bool x : arr) {
1377  j.m_value.array->push_back(x);
1378  }
1379 
1380  j.assert_invariant();
1381  }
1382 
1383  template<typename BasicJsonType, typename T,
1384  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1385  static void construct(BasicJsonType &j, const std::valarray<T> &arr)
1386  {
1387  j.m_type = value_t::array;
1388  j.m_value = value_t::array;
1389  j.m_value.array->resize(arr.size());
1390  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1391  j.assert_invariant();
1392  }
1393 };
1394 
1395 template<>
1397 {
1398  template<typename BasicJsonType>
1399  static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
1400  {
1401  j.m_type = value_t::object;
1402  j.m_value = obj;
1403  j.assert_invariant();
1404  }
1405 
1406  template<typename BasicJsonType>
1407  static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
1408  {
1409  j.m_type = value_t::object;
1410  j.m_value = std::move(obj);
1411  j.assert_invariant();
1412  }
1413 
1414  template<typename BasicJsonType, typename CompatibleObjectType,
1415  enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
1416  int> = 0>
1417  static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
1418  {
1419  using std::begin;
1420  using std::end;
1421 
1422  j.m_type = value_t::object;
1423  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1424  j.assert_invariant();
1425  }
1426 };
1427 
1429 // to_json //
1431 
1432 template<typename BasicJsonType, typename T,
1433  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
1434 void to_json(BasicJsonType &j, T b) noexcept
1435 {
1437 }
1438 
1439 template<typename BasicJsonType, typename CompatibleString,
1440  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
1441  int> = 0>
1442 void to_json(BasicJsonType &j, const CompatibleString &s)
1443 {
1445 }
1446 
1447 template<typename BasicJsonType>
1448 void to_json(BasicJsonType &j, typename BasicJsonType::string_t &&s)
1449 {
1451 }
1452 
1453 template<typename BasicJsonType, typename FloatType,
1454  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
1455 void to_json(BasicJsonType &j, FloatType val) noexcept
1456 {
1458  static_cast<typename BasicJsonType::number_float_t>(
1459  val));
1460 }
1461 
1462 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1463  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
1464  CompatibleNumberUnsignedType>::value, int> = 0>
1465 void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept
1466 {
1468  static_cast<typename BasicJsonType::
1469  number_unsigned_t>(val));
1470 }
1471 
1472 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1473  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
1474  CompatibleNumberIntegerType>::value, int> = 0>
1475 void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept
1476 {
1478  static_cast<typename BasicJsonType::
1479  number_integer_t>(val));
1480 }
1481 
1482 template<typename BasicJsonType, typename EnumType,
1483  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1484 void to_json(BasicJsonType &j, EnumType e) noexcept
1485 {
1486  using underlying_type = typename std::underlying_type<EnumType>::type;
1487  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1488 }
1489 
1490 template<typename BasicJsonType>
1491 void to_json(BasicJsonType &j, const std::vector<bool> &e)
1492 {
1494 }
1495 
1496 template<typename BasicJsonType, typename CompatibleArrayType,
1497  enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1498  std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1499  int> = 0>
1500 void to_json(BasicJsonType &j, const CompatibleArrayType &arr)
1501 {
1503 }
1504 
1505 template<typename BasicJsonType, typename T,
1506  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
1507 void to_json(BasicJsonType &j, std::valarray<T> arr)
1508 {
1510 }
1511 
1512 template<typename BasicJsonType>
1513 void to_json(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
1514 {
1516 }
1517 
1518 template<typename BasicJsonType, typename CompatibleObjectType,
1519  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1520 void to_json(BasicJsonType &j, const CompatibleObjectType &obj)
1521 {
1523 }
1524 
1525 template<typename BasicJsonType>
1526 void to_json(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
1527 {
1529 }
1530 
1531 template<typename BasicJsonType, typename T, std::size_t N,
1532  enable_if_t<not std::is_constructible<typename BasicJsonType::string_t, T( &)[N]>::value, int> = 0>
1533 void to_json(BasicJsonType &j, T(&arr)[N])
1534 {
1536 }
1537 
1538 template<typename BasicJsonType, typename... Args>
1539 void to_json(BasicJsonType &j, const std::pair<Args...> &p)
1540 {
1541  j = { p.first, p.second };
1542 }
1543 
1544 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1545 void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence<Idx...> )
1546 {
1547  j = { std::get<Idx>(t) ... };
1548 }
1549 
1550 template<typename BasicJsonType, typename... Args>
1551 void to_json(BasicJsonType &j, const std::tuple<Args...> &t)
1552 {
1553  to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1554 }
1555 
1557 {
1558 private:
1559  template<typename BasicJsonType, typename T>
1560  auto call(BasicJsonType &j, T &&val,
1561  priority_tag<1> /*unused*/) const noexcept (noexcept (to_json(j, std::forward<T>(val))))
1562  ->decltype(to_json(j, std::forward<T>(val)), void ())
1563  {
1564  return to_json(j, std::forward<T>(val));
1565  }
1566 
1567  template<typename BasicJsonType, typename T>
1568  void call(BasicJsonType & /*unused*/, T && /*unused*/, priority_tag<0> /*unused*/) const noexcept
1569  {
1570  static_assert(sizeof(BasicJsonType) == 0,
1571  "could not find to_json() method in T's namespace");
1572 
1573 #ifdef _MSC_VER
1574  // MSVC does not show a stacktrace for the above assert
1575  using decayed = uncvref_t<T>;
1576  static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1577  "forcing MSVC stacktrace to show which T we're talking about.");
1578 #endif
1579  }
1580 
1581 public:
1582  template<typename BasicJsonType, typename T>
1583  void operator()(BasicJsonType &j, T &&val) const
1584  noexcept (noexcept (std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1585  {
1586  return call(j, std::forward<T>(val), priority_tag<1> {});
1587  }
1588 };
1589 
1590 } // namespace detail
1591 
1593 namespace
1594 {
1595 constexpr const auto &to_json = detail::static_const<detail::to_json_fn>::value;
1596 } // namespace
1597 } // namespace nlohmann
1598 
1599 // #include <nlohmann/detail/input/input_adapters.hpp>
1600 
1601 
1602 #include <algorithm> // min
1603 #include <array> // array
1604 #include <cassert> // assert
1605 #include <cstddef> // size_t
1606 #include <cstring> // strlen
1607 #include <ios> // streamsize, streamoff, streampos
1608 #include <istream> // istream
1609 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1610 #include <memory> // shared_ptr, make_shared, addressof
1611 #include <numeric> // accumulate
1612 #include <string> // string, char_traits
1613 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1614 #include <utility> // pair, declval
1615 
1616 // #include <nlohmann/detail/macro_scope.hpp>
1617 
1618 
1619 namespace nlohmann
1620 {
1621 namespace detail
1622 {
1624 // input adapters //
1626 
1639 {
1641  virtual std::char_traits<char>::int_type get_character() = 0;
1643  virtual void unget_character() = 0;
1644  virtual ~input_adapter_protocol() = default;
1645 };
1646 
1648 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1649 
1660 {
1661 public:
1662  ~input_stream_adapter() override
1663  {
1664  // clear stream flags; we use underlying streambuf I/O, do not
1665  // maintain ifstream flags
1666  is.clear();
1667  }
1668 
1669  explicit input_stream_adapter(std::istream &i)
1670  : is(i), sb(*i.rdbuf())
1671  {
1672  // skip byte order mark
1673  std::char_traits<char>::int_type c;
1674  if ((c = get_character()) == 0xEF) {
1675  if ((c = get_character()) == 0xBB) {
1676  if ((c = get_character()) == 0xBF) {
1677  return; // Ignore BOM
1678  } else if (c != std::char_traits<char>::eof()) {
1679  is.unget();
1680  }
1681 
1682  is.putback('\xBB');
1683  } else if (c != std::char_traits<char>::eof()) {
1684  is.unget();
1685  }
1686 
1687  is.putback('\xEF');
1688  } else if (c != std::char_traits<char>::eof()) {
1689  is.unget(); // no byte order mark; process as usual
1690  }
1691  }
1692 
1693  // delete because of pointer members
1694  input_stream_adapter(const input_stream_adapter &) = delete;
1695  input_stream_adapter &operator=(input_stream_adapter &) = delete;
1696 
1697  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1698  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
1699  // end up as the same value, eg. 0xFFFFFFFF.
1700  std::char_traits<char>::int_type get_character() override
1701  {
1702  return sb.sbumpc();
1703  }
1704 
1705  void unget_character() override
1706  {
1707  sb.sungetc(); // is.unget() avoided for performance
1708  }
1709 
1710 private:
1712  std::istream &is;
1713  std::streambuf &sb;
1714 };
1715 
1718 {
1719 public:
1720  input_buffer_adapter(const char *b, const std::size_t l)
1721  : cursor(b), limit(b + l), start(b)
1722  {
1723  // skip byte order mark
1724  if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF') {
1725  cursor += 3;
1726  }
1727  }
1728 
1729  // delete because of pointer members
1730  input_buffer_adapter(const input_buffer_adapter &) = delete;
1731  input_buffer_adapter &operator=(input_buffer_adapter &) = delete;
1732 
1733  std::char_traits<char>::int_type get_character() noexcept override
1734  {
1735  if (JSON_LIKELY(cursor < limit)) {
1736  return std::char_traits<char>::to_int_type(*(cursor++));
1737  }
1738 
1739  return std::char_traits<char>::eof();
1740  }
1741 
1742  void unget_character() noexcept override
1743  {
1744  if (JSON_LIKELY(cursor > start)) {
1745  --cursor;
1746  }
1747  }
1748 
1749 private:
1751  const char *cursor;
1753  const char *limit;
1755  const char *start;
1756 };
1757 
1759 {
1760 public:
1761  // native support
1762 
1764  input_adapter(std::istream &i)
1765  : ia(std::make_shared<input_stream_adapter>(i)) {}
1766 
1768  input_adapter(std::istream &&i)
1769  : ia(std::make_shared<input_stream_adapter>(i)) {}
1770 
1772  template<typename CharT,
1773  typename std::enable_if<
1774  std::is_pointer<CharT>::value and
1775  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1776  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1777  int>::type = 0>
1778  input_adapter(CharT b, std::size_t l)
1779  : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(b), l)) {}
1780 
1781  // derived support
1782 
1784  template<typename CharT,
1785  typename std::enable_if<
1786  std::is_pointer<CharT>::value and
1787  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1788  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1789  int>::type = 0>
1790  input_adapter(CharT b)
1791  : input_adapter(reinterpret_cast<const char *>(b),
1792  std::strlen(reinterpret_cast<const char *>(b))) {}
1793 
1795  template<class IteratorType,
1796  typename std::enable_if<
1797  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
1798  std::random_access_iterator_tag>::value,
1799  int>::type = 0>
1800  input_adapter(IteratorType first, IteratorType last)
1801  {
1802  // assertion to check that the iterator range is indeed contiguous,
1803  // see http://stackoverflow.com/a/35008842/266378 for more discussion
1804  assert(std::accumulate(
1805  first, last, std::pair<bool, int>(true, 0),
1806  [&first](std::pair<bool, int> res, decltype(*first) val) {
1807  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1808  return res;
1809  }).first);
1810 
1811  // assertion to check that each element is 1 byte long
1812  static_assert(
1813  sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1814  "each element in the iterator range must have the size of 1 byte");
1815 
1816  const auto len = static_cast<size_t>(std::distance(first, last));
1817  if (JSON_LIKELY(len > 0)) {
1818  // there is at least one element: use the address of first
1819  ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char *>(&(*first)), len);
1820  } else {
1821  // the address of first cannot be used: use nullptr
1822  ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1823  }
1824  }
1825 
1827  template<class T, std::size_t N>
1829  : input_adapter(std::begin(array), std::end(array)) {}
1830 
1832  template<class ContiguousContainer, typename
1833  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1834  std::is_base_of<std::random_access_iterator_tag,
1835  typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1836  int>::type = 0>
1837  input_adapter(const ContiguousContainer &c)
1838  : input_adapter(std::begin(c), std::end(c)) {}
1839 
1840  operator input_adapter_t()
1841  {
1842  return ia;
1843  }
1844 
1845 private:
1847  input_adapter_t ia = nullptr;
1848 };
1849 
1850 } // namespace detail
1851 } // namespace nlohmann
1852 
1853 // #include <nlohmann/detail/input/lexer.hpp>
1854 
1855 
1856 #include <clocale> // localeconv
1857 #include <cstddef> // size_t
1858 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
1859 #include <initializer_list> // initializer_list
1860 #include <ios> // hex, uppercase
1861 #include <iomanip> // setw, setfill
1862 #include <sstream> // stringstream
1863 #include <string> // char_traits, string
1864 #include <vector> // vector
1865 
1866 // #include <nlohmann/detail/macro_scope.hpp>
1867 
1868 // #include <nlohmann/detail/input/input_adapters.hpp>
1869 
1870 
1871 namespace nlohmann
1872 {
1873 namespace detail
1874 {
1876 // lexer //
1878 
1884 template<typename BasicJsonType>
1885 
1886 class lexer
1887 {
1888  using number_integer_t = typename BasicJsonType::number_integer_t;
1889  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1890  using number_float_t = typename BasicJsonType::number_float_t;
1891 
1892 public:
1894  enum class token_type
1895  {
1896  uninitialized,
1897  literal_true,
1898  literal_false,
1899  literal_null,
1900  value_string,
1901  value_unsigned,
1902  value_integer,
1903  value_float,
1904  begin_array,
1905  begin_object,
1906  end_array,
1907  end_object,
1908  name_separator,
1909  value_separator,
1910  parse_error,
1911  end_of_input,
1912  literal_or_value
1913  };
1914 
1916  static const char *token_type_name(const token_type t) noexcept
1917  {
1918  switch (t) {
1919  case token_type::uninitialized:
1920  return "<uninitialized>";
1921  case token_type::literal_true:
1922  return "true literal";
1923  case token_type::literal_false:
1924  return "false literal";
1925  case token_type::literal_null:
1926  return "null literal";
1927  case token_type::value_string:
1928  return "string literal";
1932  return "number literal";
1933  case token_type::begin_array:
1934  return "'['";
1935  case token_type::begin_object:
1936  return "'{'";
1937  case token_type::end_array:
1938  return "']'";
1939  case token_type::end_object:
1940  return "'}'";
1941  case token_type::name_separator:
1942  return "':'";
1943  case token_type::value_separator:
1944  return "','";
1945  case token_type::parse_error:
1946  return "<parse error>";
1947  case token_type::end_of_input:
1948  return "end of input";
1949  case token_type::literal_or_value:
1950  return "'[', '{', or a literal";
1951  default: // catch non-enum values
1952  return "unknown token"; // LCOV_EXCL_LINE
1953  }
1954  }
1955 
1956  explicit lexer(detail::input_adapter_t adapter)
1957  : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1958 
1959  // delete because of pointer members
1960  lexer(const lexer &) = delete;
1961  lexer &operator=(lexer &) = delete;
1962 
1963 private:
1965  // locales
1967 
1969  static char get_decimal_point() noexcept
1970  {
1971  const auto loc = localeconv();
1972  assert(loc != nullptr);
1973  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
1974  }
1975 
1977  // scan functions
1979 
1995  int get_codepoint()
1996  {
1997  // this function only makes sense after reading `\u`
1998  assert(current == 'u');
1999  int codepoint = 0;
2000 
2001  const auto factors = { 12, 8, 4, 0 };
2002  for (const auto factor : factors) {
2003  get();
2004 
2005  if (current >= '0' and current <= '9') {
2006  codepoint += ((current - 0x30) << factor);
2007  } else if (current >= 'A' and current <= 'F') {
2008  codepoint += ((current - 0x37) << factor);
2009  } else if (current >= 'a' and current <= 'f') {
2010  codepoint += ((current - 0x57) << factor);
2011  } else {
2012  return -1;
2013  }
2014  }
2015 
2016  assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2017  return codepoint;
2018  }
2019 
2035  bool next_byte_in_range(std::initializer_list<int> ranges)
2036  {
2037  assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2038  add(current);
2039 
2040  for (auto range = ranges.begin(); range != ranges.end(); ++range) {
2041  get();
2042  if (JSON_LIKELY(*range <= current and current <= *(++range))) {
2043  add(current);
2044  } else {
2045  error_message = "invalid string: ill-formed UTF-8 byte";
2046  return false;
2047  }
2048  }
2049 
2050  return true;
2051  }
2052 
2068  token_type scan_string()
2069  {
2070  // reset token_buffer (ignore opening quote)
2071  reset();
2072 
2073  // we entered the function by reading an open quote
2074  assert(current == '\"');
2075 
2076  while (true) {
2077  // get next character
2078  switch (get()) {
2079  // end of file while parsing string
2080  case std::char_traits<char>::eof():
2081  {
2082  error_message = "invalid string: missing closing quote";
2083  return token_type::parse_error;
2084  }
2085 
2086  // closing quote
2087  case '\"':
2088  {
2089  return token_type::value_string;
2090  }
2091 
2092  // escapes
2093  case '\\':
2094  {
2095  switch (get()) {
2096  // quotation mark
2097  case '\"':
2098  add('\"');
2099  break;
2100  // reverse solidus
2101  case '\\':
2102  add('\\');
2103  break;
2104  // solidus
2105  case '/':
2106  add('/');
2107  break;
2108  // backspace
2109  case 'b':
2110  add('\b');
2111  break;
2112  // form feed
2113  case 'f':
2114  add('\f');
2115  break;
2116  // line feed
2117  case 'n':
2118  add('\n');
2119  break;
2120  // carriage return
2121  case 'r':
2122  add('\r');
2123  break;
2124  // tab
2125  case 't':
2126  add('\t');
2127  break;
2128 
2129  // unicode escapes
2130  case 'u':
2131  {
2132  const int codepoint1 = get_codepoint();
2133  int codepoint = codepoint1; // start with codepoint1
2134 
2135  if (JSON_UNLIKELY(codepoint1 == -1)) {
2136  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2137  return token_type::parse_error;
2138  }
2139 
2140  // check if code point is a high surrogate
2141  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) {
2142  // expect next \uxxxx entry
2143  if (JSON_LIKELY(get() == '\\' and get() == 'u')) {
2144  const int codepoint2 = get_codepoint();
2145 
2146  if (JSON_UNLIKELY(codepoint2 == -1)) {
2147  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2148  return token_type::parse_error;
2149  }
2150 
2151  // check if codepoint2 is a low surrogate
2152  if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) {
2153  // overwrite codepoint
2154  codepoint =
2155  // high surrogate occupies the most significant 22 bits
2156  (codepoint1 << 10)
2157  // low surrogate occupies the least significant 15 bits
2158  + codepoint2
2159  // there is still the 0xD800, 0xDC00 and 0x10000 noise
2160  // in the result so we have to subtract with:
2161  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2162  - 0x35FDC00;
2163  } else {
2164  error_message =
2165  "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2166  return token_type::parse_error;
2167  }
2168  } else {
2169  error_message =
2170  "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2171  return token_type::parse_error;
2172  }
2173  } else {
2174  if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) {
2175  error_message =
2176  "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2177  return token_type::parse_error;
2178  }
2179  }
2180 
2181  // result of the above calculation yields a proper codepoint
2182  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2183 
2184  // translate codepoint into bytes
2185  if (codepoint < 0x80) {
2186  // 1-byte characters: 0xxxxxxx (ASCII)
2187  add(codepoint);
2188  } else if (codepoint <= 0x7FF) {
2189  // 2-byte characters: 110xxxxx 10xxxxxx
2190  add(0xC0 | (codepoint >> 6));
2191  add(0x80 | (codepoint & 0x3F));
2192  } else if (codepoint <= 0xFFFF) {
2193  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2194  add(0xE0 | (codepoint >> 12));
2195  add(0x80 | ((codepoint >> 6) & 0x3F));
2196  add(0x80 | (codepoint & 0x3F));
2197  } else {
2198  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2199  add(0xF0 | (codepoint >> 18));
2200  add(0x80 | ((codepoint >> 12) & 0x3F));
2201  add(0x80 | ((codepoint >> 6) & 0x3F));
2202  add(0x80 | (codepoint & 0x3F));
2203  }
2204 
2205  break;
2206  }
2207 
2208  // other characters after escape
2209  default:
2210  error_message = "invalid string: forbidden character after backslash";
2211  return token_type::parse_error;
2212  }
2213 
2214  break;
2215  }
2216 
2217  // invalid control characters
2218  case 0x00:
2219  case 0x01:
2220  case 0x02:
2221  case 0x03:
2222  case 0x04:
2223  case 0x05:
2224  case 0x06:
2225  case 0x07:
2226  case 0x08:
2227  case 0x09:
2228  case 0x0A:
2229  case 0x0B:
2230  case 0x0C:
2231  case 0x0D:
2232  case 0x0E:
2233  case 0x0F:
2234  case 0x10:
2235  case 0x11:
2236  case 0x12:
2237  case 0x13:
2238  case 0x14:
2239  case 0x15:
2240  case 0x16:
2241  case 0x17:
2242  case 0x18:
2243  case 0x19:
2244  case 0x1A:
2245  case 0x1B:
2246  case 0x1C:
2247  case 0x1D:
2248  case 0x1E:
2249  case 0x1F:
2250  {
2251  error_message = "invalid string: control character must be escaped";
2252  return token_type::parse_error;
2253  }
2254 
2255  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2256  case 0x20:
2257  case 0x21:
2258  case 0x23:
2259  case 0x24:
2260  case 0x25:
2261  case 0x26:
2262  case 0x27:
2263  case 0x28:
2264  case 0x29:
2265  case 0x2A:
2266  case 0x2B:
2267  case 0x2C:
2268  case 0x2D:
2269  case 0x2E:
2270  case 0x2F:
2271  case 0x30:
2272  case 0x31:
2273  case 0x32:
2274  case 0x33:
2275  case 0x34:
2276  case 0x35:
2277  case 0x36:
2278  case 0x37:
2279  case 0x38:
2280  case 0x39:
2281  case 0x3A:
2282  case 0x3B:
2283  case 0x3C:
2284  case 0x3D:
2285  case 0x3E:
2286  case 0x3F:
2287  case 0x40:
2288  case 0x41:
2289  case 0x42:
2290  case 0x43:
2291  case 0x44:
2292  case 0x45:
2293  case 0x46:
2294  case 0x47:
2295  case 0x48:
2296  case 0x49:
2297  case 0x4A:
2298  case 0x4B:
2299  case 0x4C:
2300  case 0x4D:
2301  case 0x4E:
2302  case 0x4F:
2303  case 0x50:
2304  case 0x51:
2305  case 0x52:
2306  case 0x53:
2307  case 0x54:
2308  case 0x55:
2309  case 0x56:
2310  case 0x57:
2311  case 0x58:
2312  case 0x59:
2313  case 0x5A:
2314  case 0x5B:
2315  case 0x5D:
2316  case 0x5E:
2317  case 0x5F:
2318  case 0x60:
2319  case 0x61:
2320  case 0x62:
2321  case 0x63:
2322  case 0x64:
2323  case 0x65:
2324  case 0x66:
2325  case 0x67:
2326  case 0x68:
2327  case 0x69:
2328  case 0x6A:
2329  case 0x6B:
2330  case 0x6C:
2331  case 0x6D:
2332  case 0x6E:
2333  case 0x6F:
2334  case 0x70:
2335  case 0x71:
2336  case 0x72:
2337  case 0x73:
2338  case 0x74:
2339  case 0x75:
2340  case 0x76:
2341  case 0x77:
2342  case 0x78:
2343  case 0x79:
2344  case 0x7A:
2345  case 0x7B:
2346  case 0x7C:
2347  case 0x7D:
2348  case 0x7E:
2349  case 0x7F:
2350  {
2351  add(current);
2352  break;
2353  }
2354 
2355  // U+0080..U+07FF: bytes C2..DF 80..BF
2356  case 0xC2:
2357  case 0xC3:
2358  case 0xC4:
2359  case 0xC5:
2360  case 0xC6:
2361  case 0xC7:
2362  case 0xC8:
2363  case 0xC9:
2364  case 0xCA:
2365  case 0xCB:
2366  case 0xCC:
2367  case 0xCD:
2368  case 0xCE:
2369  case 0xCF:
2370  case 0xD0:
2371  case 0xD1:
2372  case 0xD2:
2373  case 0xD3:
2374  case 0xD4:
2375  case 0xD5:
2376  case 0xD6:
2377  case 0xD7:
2378  case 0xD8:
2379  case 0xD9:
2380  case 0xDA:
2381  case 0xDB:
2382  case 0xDC:
2383  case 0xDD:
2384  case 0xDE:
2385  case 0xDF:
2386  {
2387  if (JSON_UNLIKELY(not next_byte_in_range({ 0x80, 0xBF }))) {
2388  return token_type::parse_error;
2389  }
2390 
2391  break;
2392  }
2393 
2394  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2395  case 0xE0:
2396  {
2397  if (JSON_UNLIKELY(not (next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF })))) {
2398  return token_type::parse_error;
2399  }
2400 
2401  break;
2402  }
2403 
2404  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2405  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2406  case 0xE1:
2407  case 0xE2:
2408  case 0xE3:
2409  case 0xE4:
2410  case 0xE5:
2411  case 0xE6:
2412  case 0xE7:
2413  case 0xE8:
2414  case 0xE9:
2415  case 0xEA:
2416  case 0xEB:
2417  case 0xEC:
2418  case 0xEE:
2419  case 0xEF:
2420  {
2421  if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF })))) {
2422  return token_type::parse_error;
2423  }
2424 
2425  break;
2426  }
2427 
2428  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2429  case 0xED:
2430  {
2431  if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF })))) {
2432  return token_type::parse_error;
2433  }
2434 
2435  break;
2436  }
2437 
2438  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2439  case 0xF0:
2440  {
2441  if (JSON_UNLIKELY(not (next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF })))) {
2442  return token_type::parse_error;
2443  }
2444 
2445  break;
2446  }
2447 
2448  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2449  case 0xF1:
2450  case 0xF2:
2451  case 0xF3:
2452  {
2453  if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF })))) {
2454  return token_type::parse_error;
2455  }
2456 
2457  break;
2458  }
2459 
2460  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2461  case 0xF4:
2462  {
2463  if (JSON_UNLIKELY(not (next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF })))) {
2464  return token_type::parse_error;
2465  }
2466 
2467  break;
2468  }
2469 
2470  // remaining bytes (80..C1 and F5..FF) are ill-formed
2471  default:
2472  {
2473  error_message = "invalid string: ill-formed UTF-8 byte";
2474  return token_type::parse_error;
2475  }
2476  }
2477  }
2478  }
2479 
2480  static void strtof(float &f, const char *str, char **endptr) noexcept
2481  {
2482  f = std::strtof(str, endptr);
2483  }
2484 
2485  static void strtof(double &f, const char *str, char **endptr) noexcept
2486  {
2487  f = std::strtod(str, endptr);
2488  }
2489 
2490  static void strtof(long double &f, const char *str, char **endptr) noexcept
2491  {
2492  f = std::strtold(str, endptr);
2493  }
2494 
2535  token_type scan_number()
2536  {
2537  // reset token_buffer to store the number's bytes
2538  reset();
2539 
2540  // the type of the parsed number; initially set to unsigned; will be
2541  // changed if minus sign, decimal point or exponent is read
2542  token_type number_type = token_type::value_unsigned;
2543 
2544  // state (init): we just found out we need to scan a number
2545  switch (current) {
2546  case '-':
2547  {
2548  add(current);
2549  goto scan_number_minus;
2550  }
2551 
2552  case '0':
2553  {
2554  add(current);
2555  goto scan_number_zero;
2556  }
2557 
2558  case '1':
2559  case '2':
2560  case '3':
2561  case '4':
2562  case '5':
2563  case '6':
2564  case '7':
2565  case '8':
2566  case '9':
2567  {
2568  add(current);
2569  goto scan_number_any1;
2570  }
2571 
2572  default:
2573  {
2574  // all other characters are rejected outside scan_number()
2575  assert(false); // LCOV_EXCL_LINE
2576  }
2577  }
2578 
2579  scan_number_minus:
2580  // state: we just parsed a leading minus sign
2581  number_type = token_type::value_integer;
2582  switch (get()) {
2583  case '0':
2584  {
2585  add(current);
2586  goto scan_number_zero;
2587  }
2588 
2589  case '1':
2590  case '2':
2591  case '3':
2592  case '4':
2593  case '5':
2594  case '6':
2595  case '7':
2596  case '8':
2597  case '9':
2598  {
2599  add(current);
2600  goto scan_number_any1;
2601  }
2602 
2603  default:
2604  {
2605  error_message = "invalid number; expected digit after '-'";
2606  return token_type::parse_error;
2607  }
2608  }
2609 
2610  scan_number_zero:
2611  // state: we just parse a zero (maybe with a leading minus sign)
2612  switch (get()) {
2613  case '.':
2614  {
2615  add(decimal_point_char);
2616  goto scan_number_decimal1;
2617  }
2618 
2619  case 'e':
2620  case 'E':
2621  {
2622  add(current);
2623  goto scan_number_exponent;
2624  }
2625 
2626  default:
2627  goto scan_number_done;
2628  }
2629 
2630  scan_number_any1:
2631  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2632  switch (get()) {
2633  case '0':
2634  case '1':
2635  case '2':
2636  case '3':
2637  case '4':
2638  case '5':
2639  case '6':
2640  case '7':
2641  case '8':
2642  case '9':
2643  {
2644  add(current);
2645  goto scan_number_any1;
2646  }
2647 
2648  case '.':
2649  {
2650  add(decimal_point_char);
2651  goto scan_number_decimal1;
2652  }
2653 
2654  case 'e':
2655  case 'E':
2656  {
2657  add(current);
2658  goto scan_number_exponent;
2659  }
2660 
2661  default:
2662  goto scan_number_done;
2663  }
2664 
2665  scan_number_decimal1:
2666  // state: we just parsed a decimal point
2667  number_type = token_type::value_float;
2668  switch (get()) {
2669  case '0':
2670  case '1':
2671  case '2':
2672  case '3':
2673  case '4':
2674  case '5':
2675  case '6':
2676  case '7':
2677  case '8':
2678  case '9':
2679  {
2680  add(current);
2681  goto scan_number_decimal2;
2682  }
2683 
2684  default:
2685  {
2686  error_message = "invalid number; expected digit after '.'";
2687  return token_type::parse_error;
2688  }
2689  }
2690 
2691  scan_number_decimal2:
2692  // we just parsed at least one number after a decimal point
2693  switch (get()) {
2694  case '0':
2695  case '1':
2696  case '2':
2697  case '3':
2698  case '4':
2699  case '5':
2700  case '6':
2701  case '7':
2702  case '8':
2703  case '9':
2704  {
2705  add(current);
2706  goto scan_number_decimal2;
2707  }
2708 
2709  case 'e':
2710  case 'E':
2711  {
2712  add(current);
2713  goto scan_number_exponent;
2714  }
2715 
2716  default:
2717  goto scan_number_done;
2718  }
2719 
2720  scan_number_exponent:
2721  // we just parsed an exponent
2722  number_type = token_type::value_float;
2723  switch (get()) {
2724  case '+':
2725  case '-':
2726  {
2727  add(current);
2728  goto scan_number_sign;
2729  }
2730 
2731  case '0':
2732  case '1':
2733  case '2':
2734  case '3':
2735  case '4':
2736  case '5':
2737  case '6':
2738  case '7':
2739  case '8':
2740  case '9':
2741  {
2742  add(current);
2743  goto scan_number_any2;
2744  }
2745 
2746  default:
2747  {
2748  error_message =
2749  "invalid number; expected '+', '-', or digit after exponent";
2750  return token_type::parse_error;
2751  }
2752  }
2753 
2754  scan_number_sign:
2755  // we just parsed an exponent sign
2756  switch (get()) {
2757  case '0':
2758  case '1':
2759  case '2':
2760  case '3':
2761  case '4':
2762  case '5':
2763  case '6':
2764  case '7':
2765  case '8':
2766  case '9':
2767  {
2768  add(current);
2769  goto scan_number_any2;
2770  }
2771 
2772  default:
2773  {
2774  error_message = "invalid number; expected digit after exponent sign";
2775  return token_type::parse_error;
2776  }
2777  }
2778 
2779  scan_number_any2:
2780  // we just parsed a number after the exponent or exponent sign
2781  switch (get()) {
2782  case '0':
2783  case '1':
2784  case '2':
2785  case '3':
2786  case '4':
2787  case '5':
2788  case '6':
2789  case '7':
2790  case '8':
2791  case '9':
2792  {
2793  add(current);
2794  goto scan_number_any2;
2795  }
2796 
2797  default:
2798  goto scan_number_done;
2799  }
2800 
2801  scan_number_done:
2802  // unget the character after the number (we only read it to know that
2803  // we are done scanning a number)
2804  unget();
2805 
2806  char *endptr = nullptr;
2807  errno = 0;
2808 
2809  // try to parse integers first and fall back to floats
2810  if (number_type == token_type::value_unsigned) {
2811  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2812 
2813  // we checked the number format before
2814  assert(endptr == token_buffer.data() + token_buffer.size());
2815 
2816  if (errno == 0) {
2817  value_unsigned = static_cast<number_unsigned_t>(x);
2818  if (value_unsigned == x) {
2819  return token_type::value_unsigned;
2820  }
2821  }
2822  } else if (number_type == token_type::value_integer) {
2823  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2824 
2825  // we checked the number format before
2826  assert(endptr == token_buffer.data() + token_buffer.size());
2827 
2828  if (errno == 0) {
2829  value_integer = static_cast<number_integer_t>(x);
2830  if (value_integer == x) {
2831  return token_type::value_integer;
2832  }
2833  }
2834  }
2835 
2836  // this code is reached if we parse a floating-point number or if an
2837  // integer conversion above failed
2838  strtof(value_float, token_buffer.data(), &endptr);
2839 
2840  // we checked the number format before
2841  assert(endptr == token_buffer.data() + token_buffer.size());
2842 
2843  return token_type::value_float;
2844  }
2845 
2851  token_type scan_literal(const char *literal_text, const std::size_t length,
2852  token_type return_type)
2853  {
2854  assert(current == literal_text[0]);
2855  for (std::size_t i = 1; i < length; ++i) {
2856  if (JSON_UNLIKELY(get() != literal_text[i])) {
2857  error_message = "invalid literal";
2858  return token_type::parse_error;
2859  }
2860  }
2861 
2862  return return_type;
2863  }
2864 
2866  // input management
2868 
2870  void reset() noexcept
2871  {
2872  token_buffer.clear();
2873  token_string.clear();
2874  token_string.push_back(std::char_traits<char>::to_char_type(current));
2875  }
2876 
2877  /*
2878  @brief get next character from the input
2879 
2880  This function provides the interface to the used input adapter. It does
2881  not throw in case the input reached EOF, but returns a
2882  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
2883  for use in error messages.
2884 
2885  @return character read from the input
2886  */
2887  std::char_traits<char>::int_type get()
2888  {
2889  ++chars_read;
2890  current = ia->get_character();
2891  if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2892  token_string.push_back(std::char_traits<char>::to_char_type(current));
2893  }
2894 
2895  return current;
2896  }
2897 
2899  void unget()
2900  {
2901  --chars_read;
2902  if (JSON_LIKELY(current != std::char_traits<char>::eof())) {
2903  ia->unget_character();
2904  assert(token_string.size() != 0);
2905  token_string.pop_back();
2906  }
2907  }
2908 
2910  void add(int c)
2911  {
2912  token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2913  }
2914 
2915 public:
2917  // value getters
2919 
2921  constexpr number_integer_t get_number_integer() const noexcept
2922  {
2923  return value_integer;
2924  }
2925 
2927  constexpr number_unsigned_t get_number_unsigned() const noexcept
2928  {
2929  return value_unsigned;
2930  }
2931 
2933  constexpr number_float_t get_number_float() const noexcept
2934  {
2935  return value_float;
2936  }
2937 
2940  {
2941  return std::move(token_buffer);
2942  }
2943 
2945  // diagnostics
2947 
2949  constexpr std::size_t get_position() const noexcept
2950  {
2951  return chars_read;
2952  }
2953 
2958  {
2959  // escape control characters
2960  std::string result;
2961  for (const auto c : token_string) {
2962  if ('\x00' <= c and c <= '\x1F') {
2963  // escape control characters
2964  std::stringstream ss;
2965  ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
2966  << std::hex << static_cast<int>(c) << ">";
2967  result += ss.str();
2968  } else {
2969  // add character as is
2970  result.push_back(c);
2971  }
2972  }
2973 
2974  return result;
2975  }
2976 
2978  constexpr const char *get_error_message() const noexcept
2979  {
2980  return error_message;
2981  }
2982 
2984  // actual scanner
2986 
2987  token_type scan()
2988  {
2989  // read next character and ignore whitespace
2990  do {
2991  get();
2992  } while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2993 
2994  switch (current) {
2995  // structural characters
2996  case '[':
2997  return token_type::begin_array;
2998  case ']':
2999  return token_type::end_array;
3000  case '{':
3001  return token_type::begin_object;
3002  case '}':
3003  return token_type::end_object;
3004  case ':':
3005  return token_type::name_separator;
3006  case ',':
3007  return token_type::value_separator;
3008 
3009  // literals
3010  case 't':
3011  return scan_literal("true", 4, token_type::literal_true);
3012  case 'f':
3013  return scan_literal("false", 5, token_type::literal_false);
3014  case 'n':
3015  return scan_literal("null", 4, token_type::literal_null);
3016 
3017  // string
3018  case '\"':
3019  return scan_string();
3020 
3021  // number
3022  case '-':
3023  case '0':
3024  case '1':
3025  case '2':
3026  case '3':
3027  case '4':
3028  case '5':
3029  case '6':
3030  case '7':
3031  case '8':
3032  case '9':
3033  return scan_number();
3034 
3035  // end of input (the null byte is needed when parsing from
3036  // string literals)
3037  case '\0':
3038  case std::char_traits<char>::eof():
3039  return token_type::end_of_input;
3040 
3041  // error
3042  default:
3043  error_message = "invalid literal";
3044  return token_type::parse_error;
3045  }
3046  }
3047 
3048 private:
3050  detail::input_adapter_t ia = nullptr;
3051 
3053  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3054 
3056  std::size_t chars_read = 0;
3057 
3059  std::vector<char> token_string {};
3060 
3062  std::string token_buffer {};
3063 
3065  const char *error_message = "";
3066 
3067  // number values
3068  number_integer_t value_integer = 0;
3069  number_unsigned_t value_unsigned = 0;
3070  number_float_t value_float = 0;
3071 
3073  const char decimal_point_char = '.';
3074 };
3075 
3076 } // namespace detail
3077 } // namespace nlohmann
3078 
3079 // #include <nlohmann/detail/input/parser.hpp>
3080 
3081 
3082 #include <cassert> // assert
3083 #include <cmath> // isfinite
3084 #include <cstdint> // uint8_t
3085 #include <functional> // function
3086 #include <string> // string
3087 #include <utility> // move
3088 
3089 // #include <nlohmann/detail/exceptions.hpp>
3090 
3091 // #include <nlohmann/detail/macro_scope.hpp>
3092 
3093 // #include <nlohmann/detail/input/input_adapters.hpp>
3094 
3095 // #include <nlohmann/detail/input/lexer.hpp>
3096 
3097 // #include <nlohmann/detail/value_t.hpp>
3098 
3099 
3100 namespace nlohmann
3101 {
3102 namespace detail
3103 {
3105 // parser //
3107 
3113 template<typename BasicJsonType>
3114 
3115 class parser
3116 {
3117  using number_integer_t = typename BasicJsonType::number_integer_t;
3118  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3119  using number_float_t = typename BasicJsonType::number_float_t;
3120  using lexer_t = lexer<BasicJsonType>;
3121  using token_type = typename lexer_t::token_type;
3122 
3123 public:
3124  enum class parse_event_t : uint8_t
3125  {
3127  object_start,
3129  object_end,
3131  array_start,
3133  array_end,
3135  key,
3137  value
3138  };
3139 
3140  using parser_callback_t =
3141  std::function<bool(int depth, parse_event_t event, BasicJsonType &parsed)>;
3142 
3145  const parser_callback_t cb = nullptr,
3146  const bool allow_exceptions_ = true)
3147  : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3148  {}
3149 
3160  void parse(const bool strict, BasicJsonType &result)
3161  {
3162  // read first token
3163  get_token();
3164 
3165  parse_internal(true, result);
3166  result.assert_invariant();
3167 
3168  // in strict mode, input must be completely read
3169  if (strict) {
3170  get_token();
3171  expect(token_type::end_of_input);
3172  }
3173 
3174  // in case of an error, return discarded value
3175  if (errored) {
3176  result = value_t::discarded;
3177  return;
3178  }
3179 
3180  // set top-level value to null if it was discarded by the callback
3181  // function
3182  if (result.is_discarded()) {
3183  result = nullptr;
3184  }
3185  }
3186 
3193  bool accept(const bool strict = true)
3194  {
3195  // read first token
3196  get_token();
3197 
3198  if (not accept_internal()) {
3199  return false;
3200  }
3201 
3202  // strict => last token must be EOF
3203  return not strict or (get_token() == token_type::end_of_input);
3204  }
3205 
3206 private:
3213  void parse_internal(bool keep, BasicJsonType &result)
3214  {
3215  // never parse after a parse error was detected
3216  assert(not errored);
3217 
3218  // start with a discarded value
3219  if (not result.is_discarded()) {
3220  result.m_value.destroy(result.m_type);
3221  result.m_type = value_t::discarded;
3222  }
3223 
3224  switch (last_token) {
3225  case token_type::begin_object:
3226  {
3227  if (keep) {
3228  if (callback) {
3229  keep = callback(depth++, parse_event_t::object_start, result);
3230  }
3231 
3232  if (not callback or keep) {
3233  // explicitly set result to object to cope with {}
3234  result.m_type = value_t::object;
3235  result.m_value = value_t::object;
3236  }
3237  }
3238 
3239  // read next token
3240  get_token();
3241 
3242  // closing } -> we are done
3243  if (last_token == token_type::end_object) {
3244  if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3245  result.m_value.destroy(result.m_type);
3246  result.m_type = value_t::discarded;
3247  }
3248 
3249  break;
3250  }
3251 
3252  // parse values
3253  std::string key;
3254  BasicJsonType value;
3255  while (true) {
3256  // store key
3257  if (not expect(token_type::value_string)) {
3258  return;
3259  }
3260 
3261  key = m_lexer.move_string();
3262 
3263  bool keep_tag = false;
3264  if (keep) {
3265  if (callback) {
3266  BasicJsonType k(key);
3267  keep_tag = callback(depth, parse_event_t::key, k);
3268  } else {
3269  keep_tag = true;
3270  }
3271  }
3272 
3273  // parse separator (:)
3274  get_token();
3275  if (not expect(token_type::name_separator)) {
3276  return;
3277  }
3278 
3279  // parse and add value
3280  get_token();
3281  value.m_value.destroy(value.m_type);
3282  value.m_type = value_t::discarded;
3283  parse_internal(keep, value);
3284 
3285  if (JSON_UNLIKELY(errored)) {
3286  return;
3287  }
3288 
3289  if (keep and keep_tag and not value.is_discarded()) {
3290  result.m_value.object->emplace(std::move(key), std::move(value));
3291  }
3292 
3293  // comma -> next value
3294  get_token();
3295  if (last_token == token_type::value_separator) {
3296  get_token();
3297  continue;
3298  }
3299 
3300  // closing }
3301  if (not expect(token_type::end_object)) {
3302  return;
3303  }
3304 
3305  break;
3306  }
3307 
3308  if (keep and callback and not callback(--depth, parse_event_t::object_end, result)) {
3309  result.m_value.destroy(result.m_type);
3310  result.m_type = value_t::discarded;
3311  }
3312 
3313  break;
3314  }
3315 
3316  case token_type::begin_array:
3317  {
3318  if (keep) {
3319  if (callback) {
3320  keep = callback(depth++, parse_event_t::array_start, result);
3321  }
3322 
3323  if (not callback or keep) {
3324  // explicitly set result to array to cope with []
3325  result.m_type = value_t::array;
3326  result.m_value = value_t::array;
3327  }
3328  }
3329 
3330  // read next token
3331  get_token();
3332 
3333  // closing ] -> we are done
3334  if (last_token == token_type::end_array) {
3335  if (callback and not callback(--depth, parse_event_t::array_end, result)) {
3336  result.m_value.destroy(result.m_type);
3337  result.m_type = value_t::discarded;
3338  }
3339 
3340  break;
3341  }
3342 
3343  // parse values
3344  BasicJsonType value;
3345  while (true) {
3346  // parse value
3347  value.m_value.destroy(value.m_type);
3348  value.m_type = value_t::discarded;
3349  parse_internal(keep, value);
3350 
3351  if (JSON_UNLIKELY(errored)) {
3352  return;
3353  }
3354 
3355  if (keep and not value.is_discarded()) {
3356  result.m_value.array->push_back(std::move(value));
3357  }
3358 
3359  // comma -> next value
3360  get_token();
3361  if (last_token == token_type::value_separator) {
3362  get_token();
3363  continue;
3364  }
3365 
3366  // closing ]
3367  if (not expect(token_type::end_array)) {
3368  return;
3369  }
3370 
3371  break;
3372  }
3373 
3374  if (keep and callback and not callback(--depth, parse_event_t::array_end, result)) {
3375  result.m_value.destroy(result.m_type);
3376  result.m_type = value_t::discarded;
3377  }
3378 
3379  break;
3380  }
3381 
3382  case token_type::literal_null:
3383  {
3384  result.m_type = value_t::null;
3385  break;
3386  }
3387 
3388  case token_type::value_string:
3389  {
3390  result.m_type = value_t::string;
3391  result.m_value = m_lexer.move_string();
3392  break;
3393  }
3394 
3395  case token_type::literal_true:
3396  {
3397  result.m_type = value_t::boolean;
3398  result.m_value = true;
3399  break;
3400  }
3401 
3402  case token_type::literal_false:
3403  {
3404  result.m_type = value_t::boolean;
3405  result.m_value = false;
3406  break;
3407  }
3408 
3409  case token_type::value_unsigned:
3410  {
3411  result.m_type = value_t::number_unsigned;
3412  result.m_value = m_lexer.get_number_unsigned();
3413  break;
3414  }
3415 
3416  case token_type::value_integer:
3417  {
3418  result.m_type = value_t::number_integer;
3419  result.m_value = m_lexer.get_number_integer();
3420  break;
3421  }
3422 
3423  case token_type::value_float:
3424  {
3425  result.m_type = value_t::number_float;
3426  result.m_value = m_lexer.get_number_float();
3427 
3428  // throw in case of infinity or NAN
3429  if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float))) {
3430  if (allow_exceptions) {
3431  JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3432  m_lexer.get_token_string() + "'"));
3433  }
3434 
3435  expect(token_type::uninitialized);
3436  }
3437 
3438  break;
3439  }
3440 
3441  case token_type::parse_error:
3442  {
3443  // using "uninitialized" to avoid "expected" message
3444  if (not expect(token_type::uninitialized)) {
3445  return;
3446  }
3447 
3448  break; // LCOV_EXCL_LINE
3449  }
3450 
3451  default:
3452  {
3453  // the last token was unexpected; we expected a value
3454  if (not expect(token_type::literal_or_value)) {
3455  return;
3456  }
3457 
3458  break; // LCOV_EXCL_LINE
3459  }
3460  }
3461 
3462  if (keep and callback and not callback(depth, parse_event_t::value, result)) {
3463  result.m_type = value_t::discarded;
3464  }
3465  }
3466 
3477  bool accept_internal()
3478  {
3479  switch (last_token) {
3480  case token_type::begin_object:
3481  {
3482  // read next token
3483  get_token();
3484 
3485  // closing } -> we are done
3486  if (last_token == token_type::end_object) {
3487  return true;
3488  }
3489 
3490  // parse values
3491  while (true) {
3492  // parse key
3493  if (last_token != token_type::value_string) {
3494  return false;
3495  }
3496 
3497  // parse separator (:)
3498  get_token();
3499  if (last_token != token_type::name_separator) {
3500  return false;
3501  }
3502 
3503  // parse value
3504  get_token();
3505  if (not accept_internal()) {
3506  return false;
3507  }
3508 
3509  // comma -> next value
3510  get_token();
3511  if (last_token == token_type::value_separator) {
3512  get_token();
3513  continue;
3514  }
3515 
3516  // closing }
3517  return (last_token == token_type::end_object);
3518  }
3519  }
3520 
3521  case token_type::begin_array:
3522  {
3523  // read next token
3524  get_token();
3525 
3526  // closing ] -> we are done
3527  if (last_token == token_type::end_array) {
3528  return true;
3529  }
3530 
3531  // parse values
3532  while (true) {
3533  // parse value
3534  if (not accept_internal()) {
3535  return false;
3536  }
3537 
3538  // comma -> next value
3539  get_token();
3540  if (last_token == token_type::value_separator) {
3541  get_token();
3542  continue;
3543  }
3544 
3545  // closing ]
3546  return (last_token == token_type::end_array);
3547  }
3548  }
3549 
3550  case token_type::value_float:
3551  {
3552  // reject infinity or NAN
3553  return std::isfinite(m_lexer.get_number_float());
3554  }
3555 
3556  case token_type::literal_false:
3557  case token_type::literal_null:
3558  case token_type::literal_true:
3559  case token_type::value_integer:
3560  case token_type::value_string:
3561  case token_type::value_unsigned:
3562  return true;
3563 
3564  default: // the last token was unexpected
3565  return false;
3566  }
3567  }
3568 
3570  token_type get_token()
3571  {
3572  return (last_token = m_lexer.scan());
3573  }
3574 
3578  bool expect(token_type t)
3579  {
3580  if (JSON_UNLIKELY(t != last_token)) {
3581  errored = true;
3582  expected = t;
3583  if (allow_exceptions) {
3584  throw_exception();
3585  } else {
3586  return false;
3587  }
3588  }
3589 
3590  return true;
3591  }
3592 
3593  [[noreturn]] void throw_exception() const
3594  {
3595  std::string error_msg = "syntax error - ";
3596  if (last_token == token_type::parse_error) {
3597  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3598  m_lexer.get_token_string() + "'";
3599  } else {
3600  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3601  }
3602 
3603  if (expected != token_type::uninitialized) {
3604  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3605  }
3606 
3607  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3608  }
3609 
3610 private:
3612  int depth = 0;
3614  const parser_callback_t callback = nullptr;
3616  token_type last_token = token_type::uninitialized;
3618  lexer_t m_lexer;
3620  bool errored = false;
3622  token_type expected = token_type::uninitialized;
3624  const bool allow_exceptions = true;
3625 };
3626 
3627 } // namespace detail
3628 } // namespace nlohmann
3629 
3630 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3631 
3632 
3633 #include <cstddef> // ptrdiff_t
3634 #include <limits> // numeric_limits
3635 
3636 namespace nlohmann
3637 {
3638 namespace detail
3639 {
3640 /*
3641 @brief an iterator for primitive JSON types
3642 
3643 This class models an iterator for primitive JSON types (boolean, number,
3644 string). It's only purpose is to allow the iterator/const_iterator classes
3645 to "iterate" over primitive values. Internally, the iterator is modeled by
3646 a `difference_type` variable. Value begin_value (`0`) models the begin,
3647 end_value (`1`) models past the end.
3648 */
3649 
3651 {
3652 private:
3653  using difference_type = std::ptrdiff_t;
3654  static constexpr difference_type begin_value = 0;
3655  static constexpr difference_type end_value = begin_value + 1;
3656 
3658  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3659 
3660 public:
3661  constexpr difference_type get_value() const noexcept
3662  {
3663  return m_it;
3664  }
3665 
3667  void set_begin() noexcept
3668  {
3669  m_it = begin_value;
3670  }
3671 
3673  void set_end() noexcept
3674  {
3675  m_it = end_value;
3676  }
3677 
3679  constexpr bool is_begin() const noexcept
3680  {
3681  return m_it == begin_value;
3682  }
3683 
3685  constexpr bool is_end() const noexcept
3686  {
3687  return m_it == end_value;
3688  }
3689 
3690  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3691  {
3692  return lhs.m_it == rhs.m_it;
3693  }
3694 
3695  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3696  {
3697  return lhs.m_it < rhs.m_it;
3698  }
3699 
3700  primitive_iterator_t operator+(difference_type n) noexcept
3701  {
3702  auto result = *this;
3703  result += n;
3704  return result;
3705  }
3706 
3707  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3708  {
3709  return lhs.m_it - rhs.m_it;
3710  }
3711 
3712  primitive_iterator_t &operator++() noexcept
3713  {
3714  ++m_it;
3715  return *this;
3716  }
3717 
3718  primitive_iterator_t const operator++(int) noexcept
3719  {
3720  auto result = *this;
3721  m_it++;
3722  return result;
3723  }
3724 
3725  primitive_iterator_t &operator--() noexcept
3726  {
3727  --m_it;
3728  return *this;
3729  }
3730 
3731  primitive_iterator_t const operator--(int) noexcept
3732  {
3733  auto result = *this;
3734  m_it--;
3735  return result;
3736  }
3737 
3738  primitive_iterator_t &operator+=(difference_type n) noexcept
3739  {
3740  m_it += n;
3741  return *this;
3742  }
3743 
3744  primitive_iterator_t &operator-=(difference_type n) noexcept
3745  {
3746  m_it -= n;
3747  return *this;
3748  }
3749 };
3750 
3751 } // namespace detail
3752 } // namespace nlohmann
3753 
3754 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
3755 
3756 
3757 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3758 
3759 
3760 namespace nlohmann
3761 {
3762 namespace detail
3763 {
3770 template<typename BasicJsonType> struct internal_iterator
3771 {
3773  typename BasicJsonType::object_t::iterator object_iterator {};
3775  typename BasicJsonType::array_t::iterator array_iterator {};
3777  primitive_iterator_t primitive_iterator {};
3778 };
3779 
3780 } // namespace detail
3781 } // namespace nlohmann
3782 
3783 // #include <nlohmann/detail/iterators/iter_impl.hpp>
3784 
3785 
3786 #include <ciso646> // not
3787 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
3788 #include <type_traits> // conditional, is_const, remove_const
3789 
3790 // #include <nlohmann/detail/exceptions.hpp>
3791 
3792 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
3793 
3794 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3795 
3796 // #include <nlohmann/detail/macro_scope.hpp>
3797 
3798 // #include <nlohmann/detail/meta.hpp>
3799 
3800 // #include <nlohmann/detail/value_t.hpp>
3801 
3802 
3803 namespace nlohmann
3804 {
3805 namespace detail
3806 {
3807 // forward declare, to be able to friend it later on
3808 template<typename IteratorType> class iteration_proxy;
3809 
3830 template<typename BasicJsonType>
3831 
3833 {
3836  typename std::remove_const<BasicJsonType>::type,
3837  const BasicJsonType>::type>;
3838  friend BasicJsonType;
3840 
3841  using object_t = typename BasicJsonType::object_t;
3842  using array_t = typename BasicJsonType::array_t;
3843  // make sure BasicJsonType is basic_json or const basic_json
3844  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
3845  "iter_impl only accepts (const) basic_json");
3846 
3847 public:
3848 
3854  using iterator_category = std::bidirectional_iterator_tag;
3855 
3857  using value_type = typename BasicJsonType::value_type;
3859  using difference_type = typename BasicJsonType::difference_type;
3861  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3862  typename BasicJsonType::const_pointer,
3863  typename BasicJsonType::pointer>::type;
3865  using reference =
3866  typename std::conditional<std::is_const<BasicJsonType>::value,
3867  typename BasicJsonType::const_reference,
3868  typename BasicJsonType::reference>::type;
3869 
3871  iter_impl() = default;
3872 
3879  explicit iter_impl(pointer object) noexcept : m_object(object)
3880  {
3881  assert(m_object != nullptr);
3882 
3883  switch (m_object->m_type) {
3884  case value_t::object:
3885  {
3886  m_it.object_iterator = typename object_t::iterator();
3887  break;
3888  }
3889 
3890  case value_t::array:
3891  {
3892  m_it.array_iterator = typename array_t::iterator();
3893  break;
3894  }
3895 
3896  default:
3897  {
3898  m_it.primitive_iterator = primitive_iterator_t();
3899  break;
3900  }
3901  }
3902  }
3903 
3918  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
3919  : m_object(other.m_object), m_it(other.m_it) {}
3920 
3927  iter_impl &operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
3928  {
3929  m_object = other.m_object;
3930  m_it = other.m_it;
3931  return *this;
3932  }
3933 
3934 private:
3939  void set_begin() noexcept
3940  {
3941  assert(m_object != nullptr);
3942 
3943  switch (m_object->m_type) {
3944  case value_t::object:
3945  {
3946  m_it.object_iterator = m_object->m_value.object->begin();
3947  break;
3948  }
3949 
3950  case value_t::array:
3951  {
3952  m_it.array_iterator = m_object->m_value.array->begin();
3953  break;
3954  }
3955 
3956  case value_t::null:
3957  {
3958  // set to end so begin()==end() is true: null is empty
3959  m_it.primitive_iterator.set_end();
3960  break;
3961  }
3962 
3963  default:
3964  {
3965  m_it.primitive_iterator.set_begin();
3966  break;
3967  }
3968  }
3969  }
3970 
3975  void set_end() noexcept
3976  {
3977  assert(m_object != nullptr);
3978 
3979  switch (m_object->m_type) {
3980  case value_t::object:
3981  {
3982  m_it.object_iterator = m_object->m_value.object->end();
3983  break;
3984  }
3985 
3986  case value_t::array:
3987  {
3988  m_it.array_iterator = m_object->m_value.array->end();
3989  break;
3990  }
3991 
3992  default:
3993  {
3994  m_it.primitive_iterator.set_end();
3995  break;
3996  }
3997  }
3998  }
3999 
4000 public:
4006  {
4007  assert(m_object != nullptr);
4008 
4009  switch (m_object->m_type) {
4010  case value_t::object:
4011  {
4012  assert(m_it.object_iterator != m_object->m_value.object->end());
4013  return m_it.object_iterator->second;
4014  }
4015 
4016  case value_t::array:
4017  {
4018  assert(m_it.array_iterator != m_object->m_value.array->end());
4019  return *m_it.array_iterator;
4020  }
4021 
4022  case value_t::null:
4023  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4024 
4025  default:
4026  {
4027  if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
4028  return *m_object;
4029  }
4030 
4031  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4032  }
4033  }
4034  }
4035 
4041  {
4042  assert(m_object != nullptr);
4043 
4044  switch (m_object->m_type) {
4045  case value_t::object:
4046  {
4047  assert(m_it.object_iterator != m_object->m_value.object->end());
4048  return &(m_it.object_iterator->second);
4049  }
4050 
4051  case value_t::array:
4052  {
4053  assert(m_it.array_iterator != m_object->m_value.array->end());
4054  return &*m_it.array_iterator;
4055  }
4056 
4057  default:
4058  {
4059  if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) {
4060  return m_object;
4061  }
4062 
4063  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4064  }
4065  }
4066  }
4067 
4073  {
4074  auto result = *this;
4075  ++(*this);
4076  return result;
4077  }
4078 
4084  {
4085  assert(m_object != nullptr);
4086 
4087  switch (m_object->m_type) {
4088  case value_t::object:
4089  {
4090  std::advance(m_it.object_iterator, 1);
4091  break;
4092  }
4093 
4094  case value_t::array:
4095  {
4096  std::advance(m_it.array_iterator, 1);
4097  break;
4098  }
4099 
4100  default:
4101  {
4102  ++m_it.primitive_iterator;
4103  break;
4104  }
4105  }
4106 
4107  return *this;
4108  }
4109 
4115  {
4116  auto result = *this;
4117  --(*this);
4118  return result;
4119  }
4120 
4126  {
4127  assert(m_object != nullptr);
4128 
4129  switch (m_object->m_type) {
4130  case value_t::object:
4131  {
4132  std::advance(m_it.object_iterator, -1);
4133  break;
4134  }
4135 
4136  case value_t::array:
4137  {
4138  std::advance(m_it.array_iterator, -1);
4139  break;
4140  }
4141 
4142  default:
4143  {
4144  --m_it.primitive_iterator;
4145  break;
4146  }
4147  }
4148 
4149  return *this;
4150  }
4151 
4156  bool operator==(const iter_impl &other) const
4157  {
4158  // if objects are not the same, the comparison is undefined
4159  if (JSON_UNLIKELY(m_object != other.m_object)) {
4160  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4161  }
4162 
4163  assert(m_object != nullptr);
4164 
4165  switch (m_object->m_type) {
4166  case value_t::object:
4167  return (m_it.object_iterator == other.m_it.object_iterator);
4168 
4169  case value_t::array:
4170  return (m_it.array_iterator == other.m_it.array_iterator);
4171 
4172  default:
4173  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
4174  }
4175  }
4176 
4181  bool operator!=(const iter_impl &other) const
4182  {
4183  return not operator==(other);
4184  }
4185 
4190  bool operator<(const iter_impl &other) const
4191  {
4192  // if objects are not the same, the comparison is undefined
4193  if (JSON_UNLIKELY(m_object != other.m_object)) {
4194  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4195  }
4196 
4197  assert(m_object != nullptr);
4198 
4199  switch (m_object->m_type) {
4200  case value_t::object:
4201  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
4202 
4203  case value_t::array:
4204  return (m_it.array_iterator < other.m_it.array_iterator);
4205 
4206  default:
4207  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4208  }
4209  }
4210 
4215  bool operator<=(const iter_impl &other) const
4216  {
4217  return not other.operator<(*this);
4218  }
4219 
4224  bool operator>(const iter_impl &other) const
4225  {
4226  return not operator<=(other);
4227  }
4228 
4233  bool operator>=(const iter_impl &other) const
4234  {
4235  return not operator<(other);
4236  }
4237 
4243  {
4244  assert(m_object != nullptr);
4245 
4246  switch (m_object->m_type) {
4247  case value_t::object:
4248  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4249 
4250  case value_t::array:
4251  {
4252  std::advance(m_it.array_iterator, i);
4253  break;
4254  }
4255 
4256  default:
4257  {
4258  m_it.primitive_iterator += i;
4259  break;
4260  }
4261  }
4262 
4263  return *this;
4264  }
4265 
4271  {
4272  return operator+=(-i);
4273  }
4274 
4280  {
4281  auto result = *this;
4282  result += i;
4283  return result;
4284  }
4285 
4291  {
4292  auto result = it;
4293  result += i;
4294  return result;
4295  }
4296 
4302  {
4303  auto result = *this;
4304  result -= i;
4305  return result;
4306  }
4307 
4313  {
4314  assert(m_object != nullptr);
4315 
4316  switch (m_object->m_type) {
4317  case value_t::object:
4318  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4319 
4320  case value_t::array:
4321  return m_it.array_iterator - other.m_it.array_iterator;
4322 
4323  default:
4324  return m_it.primitive_iterator - other.m_it.primitive_iterator;
4325  }
4326  }
4327 
4333  {
4334  assert(m_object != nullptr);
4335 
4336  switch (m_object->m_type) {
4337  case value_t::object:
4338  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4339 
4340  case value_t::array:
4341  return *std::next(m_it.array_iterator, n);
4342 
4343  case value_t::null:
4344  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4345 
4346  default:
4347  {
4348  if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) {
4349  return *m_object;
4350  }
4351 
4352  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4353  }
4354  }
4355  }
4356 
4361  typename object_t::key_type key() const
4362  {
4363  assert(m_object != nullptr);
4364 
4365  if (JSON_LIKELY(m_object->is_object())) {
4366  return m_it.object_iterator->first;
4367  }
4368 
4369  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4370  }
4371 
4377  {
4378  return operator*();
4379  }
4380 
4381 private:
4383  pointer m_object = nullptr;
4386 };
4387 
4388 } // namespace detail
4389 } // namespace nlohmann
4390 
4391 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4392 
4393 
4394 #include <cstddef> // size_t
4395 #include <string> // string, to_string
4396 
4397 // #include <nlohmann/detail/value_t.hpp>
4398 
4399 
4400 namespace nlohmann
4401 {
4402 namespace detail
4403 {
4405 template<typename IteratorType> class iteration_proxy
4406 {
4407 private:
4409  class iteration_proxy_internal
4410  {
4411  private:
4413  IteratorType anchor;
4415  std::size_t array_index = 0;
4416 
4417  public:
4418  explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4419 
4421  iteration_proxy_internal &operator*()
4422  {
4423  return *this;
4424  }
4425 
4427  iteration_proxy_internal &operator++()
4428  {
4429  ++anchor;
4430  ++array_index;
4431 
4432  return *this;
4433  }
4434 
4436  bool operator!=(const iteration_proxy_internal &o) const noexcept
4437  {
4438  return anchor != o.anchor;
4439  }
4440 
4442  std::string key() const
4443  {
4444  assert(anchor.m_object != nullptr);
4445 
4446  switch (anchor.m_object->type()) {
4447  // use integer array index as key
4448  case value_t::array:
4449  return std::to_string(array_index);
4450 
4451  // use key from the object
4452  case value_t::object:
4453  return anchor.key();
4454 
4455  // use an empty key for all primitive types
4456  default:
4457  return "";
4458  }
4459  }
4460 
4462  typename IteratorType::reference value() const
4463  {
4464  return anchor.value();
4465  }
4466  };
4467 
4469  typename IteratorType::reference container;
4470 
4471 public:
4473  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4474  : container(cont) {}
4475 
4477  iteration_proxy_internal begin() noexcept
4478  {
4479  return iteration_proxy_internal(container.begin());
4480  }
4481 
4483  iteration_proxy_internal end() noexcept
4484  {
4485  return iteration_proxy_internal(container.end());
4486  }
4487 };
4488 
4489 } // namespace detail
4490 } // namespace nlohmann
4491 
4492 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
4493 
4494 
4495 #include <cstddef> // ptrdiff_t
4496 #include <iterator> // reverse_iterator
4497 #include <utility> // declval
4498 
4499 namespace nlohmann
4500 {
4501 namespace detail
4502 {
4504 // reverse_iterator //
4506 
4525 template<typename Base>
4526 
4527 class json_reverse_iterator : public std::reverse_iterator<Base>
4528 {
4529 public:
4530  using difference_type = std::ptrdiff_t;
4532  using base_iterator = std::reverse_iterator<Base>;
4534  using reference = typename Base::reference;
4535 
4537  json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
4538  : base_iterator(it) {}
4539 
4542 
4545  {
4546  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4547  }
4548 
4551  {
4552  return static_cast<json_reverse_iterator &>(base_iterator::operator++());
4553  }
4554 
4557  {
4558  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4559  }
4560 
4563  {
4564  return static_cast<json_reverse_iterator &>(base_iterator::operator--());
4565  }
4566 
4568  json_reverse_iterator &operator+=(difference_type i)
4569  {
4570  return static_cast<json_reverse_iterator &>(base_iterator::operator+=(i));
4571  }
4572 
4574  json_reverse_iterator operator+(difference_type i) const
4575  {
4576  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4577  }
4578 
4580  json_reverse_iterator operator-(difference_type i) const
4581  {
4582  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4583  }
4584 
4586  difference_type operator-(const json_reverse_iterator &other) const
4587  {
4588  return base_iterator(*this) - base_iterator(other);
4589  }
4590 
4592  reference operator[](difference_type n) const
4593  {
4594  return *(this->operator+(n));
4595  }
4596 
4598  auto key() const->decltype(std::declval<Base>().key())
4599  {
4600  auto it = --this->base();
4601  return it.key();
4602  }
4603 
4606  {
4607  auto it = --this->base();
4608  return it.operator*();
4609  }
4610 };
4611 
4612 } // namespace detail
4613 } // namespace nlohmann
4614 
4615 // #include <nlohmann/detail/output/output_adapters.hpp>
4616 
4617 
4618 #include <algorithm> // copy
4619 #include <cstddef> // size_t
4620 #include <ios> // streamsize
4621 #include <iterator> // back_inserter
4622 #include <memory> // shared_ptr, make_shared
4623 #include <ostream> // basic_ostream
4624 #include <string> // basic_string
4625 #include <vector> // vector
4626 
4627 namespace nlohmann
4628 {
4629 namespace detail
4630 {
4632 template<typename CharType> struct output_adapter_protocol
4633 {
4634  virtual void write_character(CharType c) = 0;
4635  virtual void write_characters(const CharType *s, std::size_t length) = 0;
4636  virtual ~output_adapter_protocol() = default;
4637 };
4638 
4640 template<typename CharType>
4641 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4642 
4644 template<typename CharType>
4646 {
4647 public:
4648  explicit output_vector_adapter(std::vector<CharType> &vec) : v(vec) {}
4649 
4650  void write_character(CharType c) override
4651  {
4652  v.push_back(c);
4653  }
4654 
4655  void write_characters(const CharType *s, std::size_t length) override
4656  {
4657  std::copy(s, s + length, std::back_inserter(v));
4658  }
4659 
4660 private:
4661  std::vector<CharType> &v;
4662 };
4663 
4665 template<typename CharType>
4667 {
4668 public:
4669  explicit output_stream_adapter(std::basic_ostream<CharType> &s) : stream(s) {}
4670 
4671  void write_character(CharType c) override
4672  {
4673  stream.put(c);
4674  }
4675 
4676  void write_characters(const CharType *s, std::size_t length) override
4677  {
4678  stream.write(s, static_cast<std::streamsize>(length));
4679  }
4680 
4681 private:
4682  std::basic_ostream<CharType> &stream;
4683 };
4684 
4686 template<typename CharType>
4688 {
4689 public:
4690  explicit output_string_adapter(std::basic_string<CharType> &s) : str(s) {}
4691 
4692  void write_character(CharType c) override
4693  {
4694  str.push_back(c);
4695  }
4696 
4697  void write_characters(const CharType *s, std::size_t length) override
4698  {
4699  str.append(s, length);
4700  }
4701 
4702 private:
4703  std::basic_string<CharType> &str;
4704 };
4705 
4706 template<typename CharType>
4707 
4709 {
4710 public:
4711  output_adapter(std::vector<CharType> &vec)
4712  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4713 
4714  output_adapter(std::basic_ostream<CharType> &s)
4715  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4716 
4717  output_adapter(std::basic_string<CharType> &s)
4718  : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4719 
4720  operator output_adapter_t<CharType>()
4721  {
4722  return oa;
4723  }
4724 
4725 private:
4726  output_adapter_t<CharType> oa = nullptr;
4727 };
4728 
4729 } // namespace detail
4730 } // namespace nlohmann
4731 
4732 // #include <nlohmann/detail/input/binary_reader.hpp>
4733 
4734 
4735 #include <algorithm> // generate_n
4736 #include <array> // array
4737 #include <cassert> // assert
4738 #include <cmath> // ldexp
4739 #include <cstddef> // size_t
4740 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4741 #include <cstring> // memcpy
4742 #include <iomanip> // setw, setfill
4743 #include <ios> // hex
4744 #include <iterator> // back_inserter
4745 #include <limits> // numeric_limits
4746 #include <sstream> // stringstream
4747 #include <string> // char_traits, string
4748 #include <utility> // make_pair, move
4749 
4750 // #include <nlohmann/detail/input/input_adapters.hpp>
4751 
4752 // #include <nlohmann/detail/exceptions.hpp>
4753 
4754 // #include <nlohmann/detail/macro_scope.hpp>
4755 
4756 // #include <nlohmann/detail/value_t.hpp>
4757 
4758 
4759 namespace nlohmann
4760 {
4761 namespace detail
4762 {
4764 // binary reader //
4766 
4770 template<typename BasicJsonType>
4771 
4773 {
4774  using number_integer_t = typename BasicJsonType::number_integer_t;
4775  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4776  using string_t = typename BasicJsonType::string_t;
4777 
4778 public:
4784  explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4785  {
4786  assert(ia);
4787  }
4788 
4799  BasicJsonType parse_cbor(const bool strict)
4800  {
4801  const auto res = parse_cbor_internal();
4802  if (strict) {
4803  get();
4804  expect_eof();
4805  }
4806 
4807  return res;
4808  }
4809 
4820  BasicJsonType parse_msgpack(const bool strict)
4821  {
4822  const auto res = parse_msgpack_internal();
4823  if (strict) {
4824  get();
4825  expect_eof();
4826  }
4827 
4828  return res;
4829  }
4830 
4841  BasicJsonType parse_ubjson(const bool strict)
4842  {
4843  const auto res = parse_ubjson_internal();
4844  if (strict) {
4845  get_ignore_noop();
4846  expect_eof();
4847  }
4848 
4849  return res;
4850  }
4851 
4859  static constexpr bool little_endianess(int num = 1) noexcept
4860  {
4861  return (*reinterpret_cast<char *>(&num) == 1);
4862  }
4863 
4864 private:
4870  BasicJsonType parse_cbor_internal(const bool get_char = true)
4871  {
4872  switch (get_char ? get() : current) {
4873  // EOF
4874  case std::char_traits<char>::eof():
4875  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4876 
4877  // Integer 0x00..0x17 (0..23)
4878  case 0x00:
4879  case 0x01:
4880  case 0x02:
4881  case 0x03:
4882  case 0x04:
4883  case 0x05:
4884  case 0x06:
4885  case 0x07:
4886  case 0x08:
4887  case 0x09:
4888  case 0x0A:
4889  case 0x0B:
4890  case 0x0C:
4891  case 0x0D:
4892  case 0x0E:
4893  case 0x0F:
4894  case 0x10:
4895  case 0x11:
4896  case 0x12:
4897  case 0x13:
4898  case 0x14:
4899  case 0x15:
4900  case 0x16:
4901  case 0x17:
4902  return static_cast<number_unsigned_t>(current);
4903 
4904  case 0x18: // Unsigned integer (one-byte uint8_t follows)
4905  return get_number<uint8_t>();
4906 
4907  case 0x19: // Unsigned integer (two-byte uint16_t follows)
4908  return get_number<uint16_t>();
4909 
4910  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
4911  return get_number<uint32_t>();
4912 
4913  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
4914  return get_number<uint64_t>();
4915 
4916  // Negative integer -1-0x00..-1-0x17 (-1..-24)
4917  case 0x20:
4918  case 0x21:
4919  case 0x22:
4920  case 0x23:
4921  case 0x24:
4922  case 0x25:
4923  case 0x26:
4924  case 0x27:
4925  case 0x28:
4926  case 0x29:
4927  case 0x2A:
4928  case 0x2B:
4929  case 0x2C:
4930  case 0x2D:
4931  case 0x2E:
4932  case 0x2F:
4933  case 0x30:
4934  case 0x31:
4935  case 0x32:
4936  case 0x33:
4937  case 0x34:
4938  case 0x35:
4939  case 0x36:
4940  case 0x37:
4941  return static_cast<int8_t>(0x20 - 1 - current);
4942 
4943  case 0x38: // Negative integer (one-byte uint8_t follows)
4944  {
4945  return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4946  }
4947 
4948  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
4949  {
4950  return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4951  }
4952 
4953  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
4954  {
4955  return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4956  }
4957 
4958  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
4959  {
4960  return static_cast<number_integer_t>(-1) -
4961  static_cast<number_integer_t>(get_number<uint64_t>());
4962  }
4963 
4964  // UTF-8 string (0x00..0x17 bytes follow)
4965  case 0x60:
4966  case 0x61:
4967  case 0x62:
4968  case 0x63:
4969  case 0x64:
4970  case 0x65:
4971  case 0x66:
4972  case 0x67:
4973  case 0x68:
4974  case 0x69:
4975  case 0x6A:
4976  case 0x6B:
4977  case 0x6C:
4978  case 0x6D:
4979  case 0x6E:
4980  case 0x6F:
4981  case 0x70:
4982  case 0x71:
4983  case 0x72:
4984  case 0x73:
4985  case 0x74:
4986  case 0x75:
4987  case 0x76:
4988  case 0x77:
4989  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4990  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4991  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4992  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4993  case 0x7F: // UTF-8 string (indefinite length)
4994  {
4995  return get_cbor_string();
4996  }
4997 
4998  // array (0x00..0x17 data items follow)
4999  case 0x80:
5000  case 0x81:
5001  case 0x82:
5002  case 0x83:
5003  case 0x84:
5004  case 0x85:
5005  case 0x86:
5006  case 0x87:
5007  case 0x88:
5008  case 0x89:
5009  case 0x8A:
5010  case 0x8B:
5011  case 0x8C:
5012  case 0x8D:
5013  case 0x8E:
5014  case 0x8F:
5015  case 0x90:
5016  case 0x91:
5017  case 0x92:
5018  case 0x93:
5019  case 0x94:
5020  case 0x95:
5021  case 0x96:
5022  case 0x97:
5023  {
5024  return get_cbor_array(current & 0x1F);
5025  }
5026 
5027  case 0x98: // array (one-byte uint8_t for n follows)
5028  {
5029  return get_cbor_array(get_number<uint8_t>());
5030  }
5031 
5032  case 0x99: // array (two-byte uint16_t for n follow)
5033  {
5034  return get_cbor_array(get_number<uint16_t>());
5035  }
5036 
5037  case 0x9A: // array (four-byte uint32_t for n follow)
5038  {
5039  return get_cbor_array(get_number<uint32_t>());
5040  }
5041 
5042  case 0x9B: // array (eight-byte uint64_t for n follow)
5043  {
5044  return get_cbor_array(get_number<uint64_t>());
5045  }
5046 
5047  case 0x9F: // array (indefinite length)
5048  {
5049  BasicJsonType result = value_t::array;
5050  while (get() != 0xFF) {
5051  result.push_back(parse_cbor_internal(false));
5052  }
5053 
5054  return result;
5055  }
5056 
5057  // map (0x00..0x17 pairs of data items follow)
5058  case 0xA0:
5059  case 0xA1:
5060  case 0xA2:
5061  case 0xA3:
5062  case 0xA4:
5063  case 0xA5:
5064  case 0xA6:
5065  case 0xA7:
5066  case 0xA8:
5067  case 0xA9:
5068  case 0xAA:
5069  case 0xAB:
5070  case 0xAC:
5071  case 0xAD:
5072  case 0xAE:
5073  case 0xAF:
5074  case 0xB0:
5075  case 0xB1:
5076  case 0xB2:
5077  case 0xB3:
5078  case 0xB4:
5079  case 0xB5:
5080  case 0xB6:
5081  case 0xB7:
5082  {
5083  return get_cbor_object(current & 0x1F);
5084  }
5085 
5086  case 0xB8: // map (one-byte uint8_t for n follows)
5087  {
5088  return get_cbor_object(get_number<uint8_t>());
5089  }
5090 
5091  case 0xB9: // map (two-byte uint16_t for n follow)
5092  {
5093  return get_cbor_object(get_number<uint16_t>());
5094  }
5095 
5096  case 0xBA: // map (four-byte uint32_t for n follow)
5097  {
5098  return get_cbor_object(get_number<uint32_t>());
5099  }
5100 
5101  case 0xBB: // map (eight-byte uint64_t for n follow)
5102  {
5103  return get_cbor_object(get_number<uint64_t>());
5104  }
5105 
5106  case 0xBF: // map (indefinite length)
5107  {
5108  BasicJsonType result = value_t::object;
5109  while (get() != 0xFF) {
5110  auto key = get_cbor_string();
5111  result[key] = parse_cbor_internal();
5112  }
5113 
5114  return result;
5115  }
5116 
5117  case 0xF4: // false
5118  {
5119  return false;
5120  }
5121 
5122  case 0xF5: // true
5123  {
5124  return true;
5125  }
5126 
5127  case 0xF6: // null
5128  {
5129  return value_t::null;
5130  }
5131 
5132  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
5133  {
5134  const int byte1 = get();
5135  unexpect_eof();
5136  const int byte2 = get();
5137  unexpect_eof();
5138 
5139  // code from RFC 7049, Appendix D, Figure 3:
5140  // As half-precision floating-point numbers were only added
5141  // to IEEE 754 in 2008, today's programming platforms often
5142  // still only have limited support for them. It is very
5143  // easy to include at least decoding support for them even
5144  // without such support. An example of a small decoder for
5145  // half-precision floating-point numbers in the C language
5146  // is shown in Fig. 3.
5147  const int half = (byte1 << 8) + byte2;
5148  const int exp = (half >> 10) & 0x1F;
5149  const int mant = half & 0x3FF;
5150  double val;
5151  if (exp == 0) {
5152  val = std::ldexp(mant, -24);
5153  } else if (exp != 31) {
5154  val = std::ldexp(mant + 1024, exp - 25);
5155  } else {
5156  val = (mant == 0) ? std::numeric_limits<double>::infinity()
5157  : std::numeric_limits<double>::quiet_NaN();
5158  }
5159 
5160  return (half & 0x8000) != 0 ? -val : val;
5161  }
5162 
5163  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
5164  {
5165  return get_number<float>();
5166  }
5167 
5168  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
5169  {
5170  return get_number<double>();
5171  }
5172 
5173  default: // anything else (0xFF is handled inside the other types)
5174  {
5175  std::stringstream ss;
5176  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5177  JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
5178  }
5179  }
5180  }
5181 
5182  BasicJsonType parse_msgpack_internal()
5183  {
5184  switch (get()) {
5185  // EOF
5186  case std::char_traits<char>::eof():
5187  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5188 
5189  // positive fixint
5190  case 0x00:
5191  case 0x01:
5192  case 0x02:
5193  case 0x03:
5194  case 0x04:
5195  case 0x05:
5196  case 0x06:
5197  case 0x07:
5198  case 0x08:
5199  case 0x09:
5200  case 0x0A:
5201  case 0x0B:
5202  case 0x0C:
5203  case 0x0D:
5204  case 0x0E:
5205  case 0x0F:
5206  case 0x10:
5207  case 0x11:
5208  case 0x12:
5209  case 0x13:
5210  case 0x14:
5211  case 0x15:
5212  case 0x16:
5213  case 0x17:
5214  case 0x18:
5215  case 0x19:
5216  case 0x1A:
5217  case 0x1B:
5218  case 0x1C:
5219  case 0x1D:
5220  case 0x1E:
5221  case 0x1F:
5222  case 0x20:
5223  case 0x21:
5224  case 0x22:
5225  case 0x23:
5226  case 0x24:
5227  case 0x25:
5228  case 0x26:
5229  case 0x27:
5230  case 0x28:
5231  case 0x29:
5232  case 0x2A:
5233  case 0x2B:
5234  case 0x2C:
5235  case 0x2D:
5236  case 0x2E:
5237  case 0x2F:
5238  case 0x30:
5239  case 0x31:
5240  case 0x32:
5241  case 0x33:
5242  case 0x34:
5243  case 0x35:
5244  case 0x36:
5245  case 0x37:
5246  case 0x38:
5247  case 0x39:
5248  case 0x3A:
5249  case 0x3B:
5250  case 0x3C:
5251  case 0x3D:
5252  case 0x3E:
5253  case 0x3F:
5254  case 0x40:
5255  case 0x41:
5256  case 0x42:
5257  case 0x43:
5258  case 0x44:
5259  case 0x45:
5260  case 0x46:
5261  case 0x47:
5262  case 0x48:
5263  case 0x49:
5264  case 0x4A:
5265  case 0x4B:
5266  case 0x4C:
5267  case 0x4D:
5268  case 0x4E:
5269  case 0x4F:
5270  case 0x50:
5271  case 0x51:
5272  case 0x52:
5273  case 0x53:
5274  case 0x54:
5275  case 0x55:
5276  case 0x56:
5277  case 0x57:
5278  case 0x58:
5279  case 0x59:
5280  case 0x5A:
5281  case 0x5B:
5282  case 0x5C:
5283  case 0x5D:
5284  case 0x5E:
5285  case 0x5F:
5286  case 0x60:
5287  case 0x61:
5288  case 0x62:
5289  case 0x63:
5290  case 0x64:
5291  case 0x65:
5292  case 0x66:
5293  case 0x67:
5294  case 0x68:
5295  case 0x69:
5296  case 0x6A:
5297  case 0x6B:
5298  case 0x6C:
5299  case 0x6D:
5300  case 0x6E:
5301  case 0x6F:
5302  case 0x70:
5303  case 0x71:
5304  case 0x72:
5305  case 0x73:
5306  case 0x74:
5307  case 0x75:
5308  case 0x76:
5309  case 0x77:
5310  case 0x78:
5311  case 0x79:
5312  case 0x7A:
5313  case 0x7B:
5314  case 0x7C:
5315  case 0x7D:
5316  case 0x7E:
5317  case 0x7F:
5318  return static_cast<number_unsigned_t>(current);
5319 
5320  // fixmap
5321  case 0x80:
5322  case 0x81:
5323  case 0x82:
5324  case 0x83:
5325  case 0x84:
5326  case 0x85:
5327  case 0x86:
5328  case 0x87:
5329  case 0x88:
5330  case 0x89:
5331  case 0x8A:
5332  case 0x8B:
5333  case 0x8C:
5334  case 0x8D:
5335  case 0x8E:
5336  case 0x8F:
5337  {
5338  return get_msgpack_object(current & 0x0F);
5339  }
5340 
5341  // fixarray
5342  case 0x90:
5343  case 0x91:
5344  case 0x92:
5345  case 0x93:
5346  case 0x94:
5347  case 0x95:
5348  case 0x96:
5349  case 0x97:
5350  case 0x98:
5351  case 0x99:
5352  case 0x9A:
5353  case 0x9B:
5354  case 0x9C:
5355  case 0x9D:
5356  case 0x9E:
5357  case 0x9F:
5358  {
5359  return get_msgpack_array(current & 0x0F);
5360  }
5361 
5362  // fixstr
5363  case 0xA0:
5364  case 0xA1:
5365  case 0xA2:
5366  case 0xA3:
5367  case 0xA4:
5368  case 0xA5:
5369  case 0xA6:
5370  case 0xA7:
5371  case 0xA8:
5372  case 0xA9:
5373  case 0xAA:
5374  case 0xAB:
5375  case 0xAC:
5376  case 0xAD:
5377  case 0xAE:
5378  case 0xAF:
5379  case 0xB0:
5380  case 0xB1:
5381  case 0xB2:
5382  case 0xB3:
5383  case 0xB4:
5384  case 0xB5:
5385  case 0xB6:
5386  case 0xB7:
5387  case 0xB8:
5388  case 0xB9:
5389  case 0xBA:
5390  case 0xBB:
5391  case 0xBC:
5392  case 0xBD:
5393  case 0xBE:
5394  case 0xBF:
5395  return get_msgpack_string();
5396 
5397  case 0xC0: // nil
5398  return value_t::null;
5399 
5400  case 0xC2: // false
5401  return false;
5402 
5403  case 0xC3: // true
5404  return true;
5405 
5406  case 0xCA: // float 32
5407  return get_number<float>();
5408 
5409  case 0xCB: // float 64
5410  return get_number<double>();
5411 
5412  case 0xCC: // uint 8
5413  return get_number<uint8_t>();
5414 
5415  case 0xCD: // uint 16
5416  return get_number<uint16_t>();
5417 
5418  case 0xCE: // uint 32
5419  return get_number<uint32_t>();
5420 
5421  case 0xCF: // uint 64
5422  return get_number<uint64_t>();
5423 
5424  case 0xD0: // int 8
5425  return get_number<int8_t>();
5426 
5427  case 0xD1: // int 16
5428  return get_number<int16_t>();
5429 
5430  case 0xD2: // int 32
5431  return get_number<int32_t>();
5432 
5433  case 0xD3: // int 64
5434  return get_number<int64_t>();
5435 
5436  case 0xD9: // str 8
5437  case 0xDA: // str 16
5438  case 0xDB: // str 32
5439  return get_msgpack_string();
5440 
5441  case 0xDC: // array 16
5442  {
5443  return get_msgpack_array(get_number<uint16_t>());
5444  }
5445 
5446  case 0xDD: // array 32
5447  {
5448  return get_msgpack_array(get_number<uint32_t>());
5449  }
5450 
5451  case 0xDE: // map 16
5452  {
5453  return get_msgpack_object(get_number<uint16_t>());
5454  }
5455 
5456  case 0xDF: // map 32
5457  {
5458  return get_msgpack_object(get_number<uint32_t>());
5459  }
5460 
5461  // positive fixint
5462  case 0xE0:
5463  case 0xE1:
5464  case 0xE2:
5465  case 0xE3:
5466  case 0xE4:
5467  case 0xE5:
5468  case 0xE6:
5469  case 0xE7:
5470  case 0xE8:
5471  case 0xE9:
5472  case 0xEA:
5473  case 0xEB:
5474  case 0xEC:
5475  case 0xED:
5476  case 0xEE:
5477  case 0xEF:
5478  case 0xF0:
5479  case 0xF1:
5480  case 0xF2:
5481  case 0xF3:
5482  case 0xF4:
5483  case 0xF5:
5484  case 0xF6:
5485  case 0xF7:
5486  case 0xF8:
5487  case 0xF9:
5488  case 0xFA:
5489  case 0xFB:
5490  case 0xFC:
5491  case 0xFD:
5492  case 0xFE:
5493  case 0xFF:
5494  return static_cast<int8_t>(current);
5495 
5496  default: // anything else
5497  {
5498  std::stringstream ss;
5499  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5500  JSON_THROW(parse_error::create(112, chars_read,
5501  "error reading MessagePack; last byte: 0x" + ss.str()));
5502  }
5503  }
5504  }
5505 
5511  BasicJsonType parse_ubjson_internal(const bool get_char = true)
5512  {
5513  return get_ubjson_value(get_char ? get_ignore_noop() : current);
5514  }
5515 
5525  int get()
5526  {
5527  ++chars_read;
5528  return (current = ia->get_character());
5529  }
5530 
5534  int get_ignore_noop()
5535  {
5536  do {
5537  get();
5538  } while (current == 'N');
5539 
5540  return current;
5541  }
5542 
5543  /*
5544  @brief read a number from the input
5545 
5546  @tparam NumberType the type of the number
5547 
5548  @return number of type @a NumberType
5549 
5550  @note This function needs to respect the system's endianess, because
5551  bytes in CBOR and MessagePack are stored in network order (big
5552  endian) and therefore need reordering on little endian systems.
5553 
5554  @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5555  */
5556  template<typename NumberType> NumberType get_number()
5557  {
5558  // step 1: read input into array with system's byte order
5559  std::array<uint8_t, sizeof(NumberType)> vec;
5560  for (std::size_t i = 0; i < sizeof(NumberType); ++i) {
5561  get();
5562  unexpect_eof();
5563 
5564  // reverse byte order prior to conversion if necessary
5565  if (is_little_endian) {
5566  vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5567  } else {
5568  vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5569  }
5570  }
5571 
5572  // step 2: convert array into number of type T and return
5573  NumberType result;
5574  std::memcpy(&result, vec.data(), sizeof(NumberType));
5575  return result;
5576  }
5577 
5591  template<typename NumberType>
5592  string_t get_string(const NumberType len)
5593  {
5594  string_t result;
5595  std::generate_n(std::back_inserter(result), len, [this]() {
5596  get();
5597  unexpect_eof();
5598  return static_cast<char>(current);
5599  });
5600  return result;
5601  }
5602 
5615  string_t get_cbor_string()
5616  {
5617  unexpect_eof();
5618 
5619  switch (current) {
5620  // UTF-8 string (0x00..0x17 bytes follow)
5621  case 0x60:
5622  case 0x61:
5623  case 0x62:
5624  case 0x63:
5625  case 0x64:
5626  case 0x65:
5627  case 0x66:
5628  case 0x67:
5629  case 0x68:
5630  case 0x69:
5631  case 0x6A:
5632  case 0x6B:
5633  case 0x6C:
5634  case 0x6D:
5635  case 0x6E:
5636  case 0x6F:
5637  case 0x70:
5638  case 0x71:
5639  case 0x72:
5640  case 0x73:
5641  case 0x74:
5642  case 0x75:
5643  case 0x76:
5644  case 0x77:
5645  {
5646  return get_string(current & 0x1F);
5647  }
5648 
5649  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5650  {
5651  return get_string(get_number<uint8_t>());
5652  }
5653 
5654  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5655  {
5656  return get_string(get_number<uint16_t>());
5657  }
5658 
5659  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5660  {
5661  return get_string(get_number<uint32_t>());
5662  }
5663 
5664  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5665  {
5666  return get_string(get_number<uint64_t>());
5667  }
5668 
5669  case 0x7F: // UTF-8 string (indefinite length)
5670  {
5671  string_t result;
5672  while (get() != 0xFF) {
5673  result.append(get_cbor_string());
5674  }
5675 
5676  return result;
5677  }
5678 
5679  default:
5680  {
5681  std::stringstream ss;
5682  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5683  JSON_THROW(parse_error::create(113, chars_read,
5684  "expected a CBOR string; last byte: 0x" + ss.str()));
5685  }
5686  }
5687  }
5688 
5689  template<typename NumberType>
5690  BasicJsonType get_cbor_array(const NumberType len)
5691  {
5692  BasicJsonType result = value_t::array;
5693  std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
5694  return parse_cbor_internal();
5695  });
5696  return result;
5697  }
5698 
5699  template<typename NumberType>
5700  BasicJsonType get_cbor_object(const NumberType len)
5701  {
5702  BasicJsonType result = value_t::object;
5703  std::generate_n(std::inserter(*result.m_value.object,
5704  result.m_value.object->end()),
5705  len, [this]() {
5706  get();
5707  auto key = get_cbor_string();
5708  auto val = parse_cbor_internal();
5709  return std::make_pair(std::move(key), std::move(val));
5710  });
5711  return result;
5712  }
5713 
5725  string_t get_msgpack_string()
5726  {
5727  unexpect_eof();
5728 
5729  switch (current) {
5730  // fixstr
5731  case 0xA0:
5732  case 0xA1:
5733  case 0xA2:
5734  case 0xA3:
5735  case 0xA4:
5736  case 0xA5:
5737  case 0xA6:
5738  case 0xA7:
5739  case 0xA8:
5740  case 0xA9:
5741  case 0xAA:
5742  case 0xAB:
5743  case 0xAC:
5744  case 0xAD:
5745  case 0xAE:
5746  case 0xAF:
5747  case 0xB0:
5748  case 0xB1:
5749  case 0xB2:
5750  case 0xB3:
5751  case 0xB4:
5752  case 0xB5:
5753  case 0xB6:
5754  case 0xB7:
5755  case 0xB8:
5756  case 0xB9:
5757  case 0xBA:
5758  case 0xBB:
5759  case 0xBC:
5760  case 0xBD:
5761  case 0xBE:
5762  case 0xBF:
5763  {
5764  return get_string(current & 0x1F);
5765  }
5766 
5767  case 0xD9: // str 8
5768  {
5769  return get_string(get_number<uint8_t>());
5770  }
5771 
5772  case 0xDA: // str 16
5773  {
5774  return get_string(get_number<uint16_t>());
5775  }
5776 
5777  case 0xDB: // str 32
5778  {
5779  return get_string(get_number<uint32_t>());
5780  }
5781 
5782  default:
5783  {
5784  std::stringstream ss;
5785  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5786  JSON_THROW(parse_error::create(113, chars_read,
5787  "expected a MessagePack string; last byte: 0x" + ss.str()));
5788  }
5789  }
5790  }
5791 
5792  template<typename NumberType>
5793  BasicJsonType get_msgpack_array(const NumberType len)
5794  {
5795  BasicJsonType result = value_t::array;
5796  std::generate_n(std::back_inserter(*result.m_value.array), len, [this]() {
5797  return parse_msgpack_internal();
5798  });
5799  return result;
5800  }
5801 
5802  template<typename NumberType>
5803  BasicJsonType get_msgpack_object(const NumberType len)
5804  {
5805  BasicJsonType result = value_t::object;
5806  std::generate_n(std::inserter(*result.m_value.object,
5807  result.m_value.object->end()),
5808  len, [this]() {
5809  get();
5810  auto key = get_msgpack_string();
5811  auto val = parse_msgpack_internal();
5812  return std::make_pair(std::move(key), std::move(val));
5813  });
5814  return result;
5815  }
5816 
5833  string_t get_ubjson_string(const bool get_char = true)
5834  {
5835  if (get_char) {
5836  get(); // TODO: may we ignore N here?
5837  }
5838 
5839  unexpect_eof();
5840 
5841  switch (current) {
5842  case 'U':
5843  return get_string(get_number<uint8_t>());
5844  case 'i':
5845  return get_string(get_number<int8_t>());
5846  case 'I':
5847  return get_string(get_number<int16_t>());
5848  case 'l':
5849  return get_string(get_number<int32_t>());
5850  case 'L':
5851  return get_string(get_number<int64_t>());
5852  default:
5853  std::stringstream ss;
5854  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5855  JSON_THROW(parse_error::create(113, chars_read,
5856  "expected a UBJSON string; last byte: 0x" + ss.str()));
5857  }
5858  }
5859 
5868  std::pair<std::size_t, int> get_ubjson_size_type()
5869  {
5870  std::size_t sz = string_t::npos;
5871  int tc = 0;
5872 
5873  get_ignore_noop();
5874 
5875  if (current == '$') {
5876  tc = get(); // must not ignore 'N', because 'N' maybe the type
5877  unexpect_eof();
5878 
5879  get_ignore_noop();
5880  if (current != '#') {
5881  std::stringstream ss;
5882  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5883  JSON_THROW(parse_error::create(112, chars_read,
5884  "expected '#' after UBJSON type information; last byte: 0x" +
5885  ss.str()));
5886  }
5887 
5888  sz = parse_ubjson_internal();
5889  } else if (current == '#') {
5890  sz = parse_ubjson_internal();
5891  }
5892 
5893  return std::make_pair(sz, tc);
5894  }
5895 
5896  BasicJsonType get_ubjson_value(const int prefix)
5897  {
5898  switch (prefix) {
5899  case std::char_traits<char>::eof(): // EOF
5900  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5901 
5902  case 'T': // true
5903  return true;
5904  case 'F': // false
5905  return false;
5906 
5907  case 'Z': // null
5908  return nullptr;
5909 
5910  case 'U':
5911  return get_number<uint8_t>();
5912  case 'i':
5913  return get_number<int8_t>();
5914  case 'I':
5915  return get_number<int16_t>();
5916  case 'l':
5917  return get_number<int32_t>();
5918  case 'L':
5919  return get_number<int64_t>();
5920  case 'd':
5921  return get_number<float>();
5922  case 'D':
5923  return get_number<double>();
5924 
5925  case 'C': // char
5926  {
5927  get();
5928  unexpect_eof();
5929  if (JSON_UNLIKELY(current > 127)) {
5930  std::stringstream ss;
5931  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5932  JSON_THROW(parse_error::create(113, chars_read,
5933  "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" +
5934  ss.str()));
5935  }
5936 
5937  return string_t(1, static_cast<char>(current));
5938  }
5939 
5940  case 'S': // string
5941  return get_ubjson_string();
5942 
5943  case '[': // array
5944  return get_ubjson_array();
5945 
5946  case '{': // object
5947  return get_ubjson_object();
5948 
5949  default: // anything else
5950  std::stringstream ss;
5951  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5952  JSON_THROW(parse_error::create(112, chars_read,
5953  "error reading UBJSON; last byte: 0x" + ss.str()));
5954  }
5955  }
5956 
5957  BasicJsonType get_ubjson_array()
5958  {
5959  BasicJsonType result = value_t::array;
5960  const auto size_and_type = get_ubjson_size_type();
5961 
5962  if (size_and_type.first != string_t::npos) {
5963  if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5964  JSON_THROW(out_of_range::create(408,
5965  "excessive array size: " + std::to_string(
5966  size_and_type.first)));
5967  }
5968 
5969  if (size_and_type.second != 0) {
5970  if (size_and_type.second != 'N') {
5971  std::generate_n(std::back_inserter(*result.m_value.array),
5972  size_and_type.first, [this, size_and_type]() {
5973  return get_ubjson_value(size_and_type.second);
5974  });
5975  }
5976  } else {
5977  std::generate_n(std::back_inserter(*result.m_value.array),
5978  size_and_type.first, [this]() {
5979  return parse_ubjson_internal();
5980  });
5981  }
5982  } else {
5983  while (current != ']') {
5984  result.push_back(parse_ubjson_internal(false));
5985  get_ignore_noop();
5986  }
5987  }
5988 
5989  return result;
5990  }
5991 
5992  BasicJsonType get_ubjson_object()
5993  {
5994  BasicJsonType result = value_t::object;
5995  const auto size_and_type = get_ubjson_size_type();
5996 
5997  if (size_and_type.first != string_t::npos) {
5998  if (JSON_UNLIKELY(size_and_type.first > result.max_size())) {
5999  JSON_THROW(out_of_range::create(408,
6000  "excessive object size: " +
6001  std::to_string(size_and_type.first)));
6002  }
6003 
6004  if (size_and_type.second != 0) {
6005  std::generate_n(std::inserter(*result.m_value.object,
6006  result.m_value.object->end()),
6007  size_and_type.first, [this, size_and_type]() {
6008  auto key = get_ubjson_string();
6009  auto val = get_ubjson_value(size_and_type.second);
6010  return std::make_pair(std::move(key), std::move(val));
6011  });
6012  } else {
6013  std::generate_n(std::inserter(*result.m_value.object,
6014  result.m_value.object->end()),
6015  size_and_type.first, [this]() {
6016  auto key = get_ubjson_string();
6017  auto val = parse_ubjson_internal();
6018  return std::make_pair(std::move(key), std::move(val));
6019  });
6020  }
6021  } else {
6022  while (current != '}') {
6023  auto key = get_ubjson_string(false);
6024  result[std::move(key)] = parse_ubjson_internal();
6025  get_ignore_noop();
6026  }
6027  }
6028 
6029  return result;
6030  }
6031 
6036  void expect_eof() const
6037  {
6038  if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) {
6039  JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
6040  }
6041  }
6042 
6047  void unexpect_eof() const
6048  {
6049  if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) {
6050  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
6051  }
6052  }
6053 
6054 private:
6056  input_adapter_t ia = nullptr;
6057 
6059  int current = std::char_traits<char>::eof();
6060 
6062  std::size_t chars_read = 0;
6063 
6065  const bool is_little_endian = little_endianess();
6066 };
6067 
6068 } // namespace detail
6069 } // namespace nlohmann
6070 
6071 // #include <nlohmann/detail/output/binary_writer.hpp>
6072 
6073 
6074 #include <algorithm> // reverse
6075 #include <array> // array
6076 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6077 #include <cstring> // memcpy
6078 #include <limits> // numeric_limits
6079 
6080 // #include <nlohmann/detail/input/binary_reader.hpp>
6081 
6082 // #include <nlohmann/detail/output/output_adapters.hpp>
6083 
6084 
6085 namespace nlohmann
6086 {
6087 namespace detail
6088 {
6090 // binary writer //
6092 
6096 template<typename BasicJsonType, typename CharType>
6097 
6099 {
6100 public:
6106  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
6107  {
6108  assert(oa);
6109  }
6110 
6114  void write_cbor(const BasicJsonType &j)
6115  {
6116  switch (j.type()) {
6117  case value_t::null:
6118  {
6119  oa->write_character(static_cast<CharType>(0xF6));
6120  break;
6121  }
6122 
6123  case value_t::boolean:
6124  {
6125  oa->write_character(j.m_value.boolean
6126  ? static_cast<CharType>(0xF5)
6127  : static_cast<CharType>(0xF4));
6128  break;
6129  }
6130 
6132  {
6133  if (j.m_value.number_integer >= 0) {
6134  // CBOR does not differentiate between positive signed
6135  // integers and unsigned integers. Therefore, we used the
6136  // code from the value_t::number_unsigned case here.
6137  if (j.m_value.number_integer <= 0x17) {
6138  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6139  } else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)()) {
6140  oa->write_character(static_cast<CharType>(0x18));
6141  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6142  } else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)()) {
6143  oa->write_character(static_cast<CharType>(0x19));
6144  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6145  } else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)()) {
6146  oa->write_character(static_cast<CharType>(0x1A));
6147  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6148  } else {
6149  oa->write_character(static_cast<CharType>(0x1B));
6150  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6151  }
6152  } else {
6153  // The conversions below encode the sign in the first
6154  // byte, and the value is converted to a positive number.
6155  const auto positive_number = -1 - j.m_value.number_integer;
6156  if (j.m_value.number_integer >= -24) {
6157  write_number(static_cast<uint8_t>(0x20 + positive_number));
6158  } else if (positive_number <= (std::numeric_limits<uint8_t>::max)()) {
6159  oa->write_character(static_cast<CharType>(0x38));
6160  write_number(static_cast<uint8_t>(positive_number));
6161  } else if (positive_number <= (std::numeric_limits<uint16_t>::max)()) {
6162  oa->write_character(static_cast<CharType>(0x39));
6163  write_number(static_cast<uint16_t>(positive_number));
6164  } else if (positive_number <= (std::numeric_limits<uint32_t>::max)()) {
6165  oa->write_character(static_cast<CharType>(0x3A));
6166  write_number(static_cast<uint32_t>(positive_number));
6167  } else {
6168  oa->write_character(static_cast<CharType>(0x3B));
6169  write_number(static_cast<uint64_t>(positive_number));
6170  }
6171  }
6172 
6173  break;
6174  }
6175 
6177  {
6178  if (j.m_value.number_unsigned <= 0x17) {
6179  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6180  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6181  oa->write_character(static_cast<CharType>(0x18));
6182  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6183  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6184  oa->write_character(static_cast<CharType>(0x19));
6185  write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
6186  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6187  oa->write_character(static_cast<CharType>(0x1A));
6188  write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
6189  } else {
6190  oa->write_character(static_cast<CharType>(0x1B));
6191  write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
6192  }
6193 
6194  break;
6195  }
6196 
6197  case value_t::number_float: // Double-Precision Float
6198  {
6199  oa->write_character(static_cast<CharType>(0xFB));
6200  write_number(j.m_value.number_float);
6201  break;
6202  }
6203 
6204  case value_t::string:
6205  {
6206  // step 1: write control byte and the string length
6207  const auto N = j.m_value.string->size();
6208  if (N <= 0x17) {
6209  write_number(static_cast<uint8_t>(0x60 + N));
6210  } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6211  oa->write_character(static_cast<CharType>(0x78));
6212  write_number(static_cast<uint8_t>(N));
6213  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6214  oa->write_character(static_cast<CharType>(0x79));
6215  write_number(static_cast<uint16_t>(N));
6216  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6217  oa->write_character(static_cast<CharType>(0x7A));
6218  write_number(static_cast<uint32_t>(N));
6219  }
6220  // LCOV_EXCL_START
6221  else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6222  oa->write_character(static_cast<CharType>(0x7B));
6223  write_number(static_cast<uint64_t>(N));
6224  }
6225 
6226  // LCOV_EXCL_STOP
6227 
6228  // step 2: write the string
6229  oa->write_characters(
6230  reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6231  j.m_value.string->size());
6232  break;
6233  }
6234 
6235  case value_t::array:
6236  {
6237  // step 1: write control byte and the array size
6238  const auto N = j.m_value.array->size();
6239  if (N <= 0x17) {
6240  write_number(static_cast<uint8_t>(0x80 + N));
6241  } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6242  oa->write_character(static_cast<CharType>(0x98));
6243  write_number(static_cast<uint8_t>(N));
6244  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6245  oa->write_character(static_cast<CharType>(0x99));
6246  write_number(static_cast<uint16_t>(N));
6247  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6248  oa->write_character(static_cast<CharType>(0x9A));
6249  write_number(static_cast<uint32_t>(N));
6250  }
6251  // LCOV_EXCL_START
6252  else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6253  oa->write_character(static_cast<CharType>(0x9B));
6254  write_number(static_cast<uint64_t>(N));
6255  }
6256 
6257  // LCOV_EXCL_STOP
6258 
6259  // step 2: write each element
6260  for (const auto &el : *j.m_value.array) {
6261  write_cbor(el);
6262  }
6263 
6264  break;
6265  }
6266 
6267  case value_t::object:
6268  {
6269  // step 1: write control byte and the object size
6270  const auto N = j.m_value.object->size();
6271  if (N <= 0x17) {
6272  write_number(static_cast<uint8_t>(0xA0 + N));
6273  } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6274  oa->write_character(static_cast<CharType>(0xB8));
6275  write_number(static_cast<uint8_t>(N));
6276  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6277  oa->write_character(static_cast<CharType>(0xB9));
6278  write_number(static_cast<uint16_t>(N));
6279  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6280  oa->write_character(static_cast<CharType>(0xBA));
6281  write_number(static_cast<uint32_t>(N));
6282  }
6283  // LCOV_EXCL_START
6284  else if (N <= (std::numeric_limits<uint64_t>::max)()) {
6285  oa->write_character(static_cast<CharType>(0xBB));
6286  write_number(static_cast<uint64_t>(N));
6287  }
6288 
6289  // LCOV_EXCL_STOP
6290 
6291  // step 2: write each element
6292  for (const auto &el : *j.m_value.object) {
6293  write_cbor(el.first);
6294  write_cbor(el.second);
6295  }
6296 
6297  break;
6298  }
6299 
6300  default:
6301  break;
6302  }
6303  }
6304 
6308  void write_msgpack(const BasicJsonType &j)
6309  {
6310  switch (j.type()) {
6311  case value_t::null: // nil
6312  {
6313  oa->write_character(static_cast<CharType>(0xC0));
6314  break;
6315  }
6316 
6317  case value_t::boolean: // true and false
6318  {
6319  oa->write_character(j.m_value.boolean
6320  ? static_cast<CharType>(0xC3)
6321  : static_cast<CharType>(0xC2));
6322  break;
6323  }
6324 
6326  {
6327  if (j.m_value.number_integer >= 0) {
6328  // MessagePack does not differentiate between positive
6329  // signed integers and unsigned integers. Therefore, we used
6330  // the code from the value_t::number_unsigned case here.
6331  if (j.m_value.number_unsigned < 128) {
6332  // positive fixnum
6333  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6334  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6335  // uint 8
6336  oa->write_character(static_cast<CharType>(0xCC));
6337  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6338  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6339  // uint 16
6340  oa->write_character(static_cast<CharType>(0xCD));
6341  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6342  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6343  // uint 32
6344  oa->write_character(static_cast<CharType>(0xCE));
6345  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6346  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6347  // uint 64
6348  oa->write_character(static_cast<CharType>(0xCF));
6349  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6350  }
6351  } else {
6352  if (j.m_value.number_integer >= -32) {
6353  // negative fixnum
6354  write_number(static_cast<int8_t>(j.m_value.number_integer));
6355  } else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6356  j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)()) {
6357  // int 8
6358  oa->write_character(static_cast<CharType>(0xD0));
6359  write_number(static_cast<int8_t>(j.m_value.number_integer));
6360  } else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6361  j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)()) {
6362  // int 16
6363  oa->write_character(static_cast<CharType>(0xD1));
6364  write_number(static_cast<int16_t>(j.m_value.number_integer));
6365  } else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6366  j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)()) {
6367  // int 32
6368  oa->write_character(static_cast<CharType>(0xD2));
6369  write_number(static_cast<int32_t>(j.m_value.number_integer));
6370  } else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6371  j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)()) {
6372  // int 64
6373  oa->write_character(static_cast<CharType>(0xD3));
6374  write_number(static_cast<int64_t>(j.m_value.number_integer));
6375  }
6376  }
6377 
6378  break;
6379  }
6380 
6382  {
6383  if (j.m_value.number_unsigned < 128) {
6384  // positive fixnum
6385  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6386  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6387  // uint 8
6388  oa->write_character(static_cast<CharType>(0xCC));
6389  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6390  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)()) {
6391  // uint 16
6392  oa->write_character(static_cast<CharType>(0xCD));
6393  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6394  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)()) {
6395  // uint 32
6396  oa->write_character(static_cast<CharType>(0xCE));
6397  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6398  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)()) {
6399  // uint 64
6400  oa->write_character(static_cast<CharType>(0xCF));
6401  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6402  }
6403 
6404  break;
6405  }
6406 
6407  case value_t::number_float: // float 64
6408  {
6409  oa->write_character(static_cast<CharType>(0xCB));
6410  write_number(j.m_value.number_float);
6411  break;
6412  }
6413 
6414  case value_t::string:
6415  {
6416  // step 1: write control byte and the string length
6417  const auto N = j.m_value.string->size();
6418  if (N <= 31) {
6419  // fixstr
6420  write_number(static_cast<uint8_t>(0xA0 | N));
6421  } else if (N <= (std::numeric_limits<uint8_t>::max)()) {
6422  // str 8
6423  oa->write_character(static_cast<CharType>(0xD9));
6424  write_number(static_cast<uint8_t>(N));
6425  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6426  // str 16
6427  oa->write_character(static_cast<CharType>(0xDA));
6428  write_number(static_cast<uint16_t>(N));
6429  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6430  // str 32
6431  oa->write_character(static_cast<CharType>(0xDB));
6432  write_number(static_cast<uint32_t>(N));
6433  }
6434 
6435  // step 2: write the string
6436  oa->write_characters(
6437  reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6438  j.m_value.string->size());
6439  break;
6440  }
6441 
6442  case value_t::array:
6443  {
6444  // step 1: write control byte and the array size
6445  const auto N = j.m_value.array->size();
6446  if (N <= 15) {
6447  // fixarray
6448  write_number(static_cast<uint8_t>(0x90 | N));
6449  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6450  // array 16
6451  oa->write_character(static_cast<CharType>(0xDC));
6452  write_number(static_cast<uint16_t>(N));
6453  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6454  // array 32
6455  oa->write_character(static_cast<CharType>(0xDD));
6456  write_number(static_cast<uint32_t>(N));
6457  }
6458 
6459  // step 2: write each element
6460  for (const auto &el : *j.m_value.array) {
6461  write_msgpack(el);
6462  }
6463 
6464  break;
6465  }
6466 
6467  case value_t::object:
6468  {
6469  // step 1: write control byte and the object size
6470  const auto N = j.m_value.object->size();
6471  if (N <= 15) {
6472  // fixmap
6473  write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6474  } else if (N <= (std::numeric_limits<uint16_t>::max)()) {
6475  // map 16
6476  oa->write_character(static_cast<CharType>(0xDE));
6477  write_number(static_cast<uint16_t>(N));
6478  } else if (N <= (std::numeric_limits<uint32_t>::max)()) {
6479  // map 32
6480  oa->write_character(static_cast<CharType>(0xDF));
6481  write_number(static_cast<uint32_t>(N));
6482  }
6483 
6484  // step 2: write each element
6485  for (const auto &el : *j.m_value.object) {
6486  write_msgpack(el.first);
6487  write_msgpack(el.second);
6488  }
6489 
6490  break;
6491  }
6492 
6493  default:
6494  break;
6495  }
6496  }
6497 
6504  void write_ubjson(const BasicJsonType &j, const bool use_count,
6505  const bool use_type, const bool add_prefix = true)
6506  {
6507  switch (j.type()) {
6508  case value_t::null:
6509  {
6510  if (add_prefix) {
6511  oa->write_character(static_cast<CharType>('Z'));
6512  }
6513 
6514  break;
6515  }
6516 
6517  case value_t::boolean:
6518  {
6519  if (add_prefix)
6520  oa->write_character(j.m_value.boolean
6521  ? static_cast<CharType>('T')
6522  : static_cast<CharType>('F'));
6523 
6524  break;
6525  }
6526 
6528  {
6529  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6530  break;
6531  }
6532 
6534  {
6535  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6536  break;
6537  }
6538 
6539  case value_t::number_float:
6540  {
6541  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6542  break;
6543  }
6544 
6545  case value_t::string:
6546  {
6547  if (add_prefix) {
6548  oa->write_character(static_cast<CharType>('S'));
6549  }
6550 
6551  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
6552  oa->write_characters(
6553  reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
6554  j.m_value.string->size());
6555  break;
6556  }
6557 
6558  case value_t::array:
6559  {
6560  if (add_prefix) {
6561  oa->write_character(static_cast<CharType>('['));
6562  }
6563 
6564  bool prefix_required = true;
6565  if (use_type and not j.m_value.array->empty()) {
6566  assert(use_count);
6567  const char first_prefix = ubjson_prefix(j.front());
6568  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6569  [this, first_prefix](const BasicJsonType &v) {
6570  return ubjson_prefix(v) == first_prefix;
6571  });
6572 
6573  if (same_prefix) {
6574  prefix_required = false;
6575  oa->write_character(static_cast<CharType>('$'));
6576  oa->write_character(static_cast<CharType>(first_prefix));
6577  }
6578  }
6579 
6580  if (use_count) {
6581  oa->write_character(static_cast<CharType>('#'));
6582  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
6583  }
6584 
6585  for (const auto &el : *j.m_value.array) {
6586  write_ubjson(el, use_count, use_type, prefix_required);
6587  }
6588 
6589  if (not use_count) {
6590  oa->write_character(static_cast<CharType>(']'));
6591  }
6592 
6593  break;
6594  }
6595 
6596  case value_t::object:
6597  {
6598  if (add_prefix) {
6599  oa->write_character(static_cast<CharType>('{'));
6600  }
6601 
6602  bool prefix_required = true;
6603  if (use_type and not j.m_value.object->empty()) {
6604  assert(use_count);
6605  const char first_prefix = ubjson_prefix(j.front());
6606  const bool same_prefix = std::all_of(j.begin(), j.end(),
6607  [this, first_prefix](const BasicJsonType &v) {
6608  return ubjson_prefix(v) == first_prefix;
6609  });
6610 
6611  if (same_prefix) {
6612  prefix_required = false;
6613  oa->write_character(static_cast<CharType>('$'));
6614  oa->write_character(static_cast<CharType>(first_prefix));
6615  }
6616  }
6617 
6618  if (use_count) {
6619  oa->write_character(static_cast<CharType>('#'));
6620  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
6621  }
6622 
6623  for (const auto &el : *j.m_value.object) {
6624  write_number_with_ubjson_prefix(el.first.size(), true);
6625  oa->write_characters(
6626  reinterpret_cast<const CharType *>(el.first.c_str()),
6627  el.first.size());
6628  write_ubjson(el.second, use_count, use_type, prefix_required);
6629  }
6630 
6631  if (not use_count) {
6632  oa->write_character(static_cast<CharType>('}'));
6633  }
6634 
6635  break;
6636  }
6637 
6638  default:
6639  break;
6640  }
6641  }
6642 
6643 private:
6644  /*
6645  @brief write a number to output input
6646 
6647  @param[in] n number of type @a NumberType
6648  @tparam NumberType the type of the number
6649 
6650  @note This function needs to respect the system's endianess, because bytes
6651  in CBOR, MessagePack, and UBJSON are stored in network order (big
6652  endian) and therefore need reordering on little endian systems.
6653  */
6654  template<typename NumberType>
6655  void write_number(const NumberType n)
6656  {
6657  // step 1: write number to array of length NumberType
6658  std::array<CharType, sizeof(NumberType)> vec;
6659  std::memcpy(vec.data(), &n, sizeof(NumberType));
6660 
6661  // step 2: write array to output (with possible reordering)
6662  if (is_little_endian) {
6663  // reverse byte order prior to conversion if necessary
6664  std::reverse(vec.begin(), vec.end());
6665  }
6666 
6667  oa->write_characters(vec.data(), sizeof(NumberType));
6668  }
6669 
6670  template<typename NumberType>
6671  void write_number_with_ubjson_prefix(const NumberType n,
6672  const bool add_prefix)
6673  {
6674  if (std::is_floating_point<NumberType>::value) {
6675  if (add_prefix) {
6676  oa->write_character(static_cast<CharType>('D')); // float64
6677  }
6678 
6679  write_number(n);
6680  } else if (std::is_unsigned<NumberType>::value) {
6681  if (n <= (std::numeric_limits<int8_t>::max)()) {
6682  if (add_prefix) {
6683  oa->write_character(static_cast<CharType>('i')); // int8
6684  }
6685 
6686  write_number(static_cast<uint8_t>(n));
6687  } else if (n <= (std::numeric_limits<uint8_t>::max)()) {
6688  if (add_prefix) {
6689  oa->write_character(static_cast<CharType>('U')); // uint8
6690  }
6691 
6692  write_number(static_cast<uint8_t>(n));
6693  } else if (n <= (std::numeric_limits<int16_t>::max)()) {
6694  if (add_prefix) {
6695  oa->write_character(static_cast<CharType>('I')); // int16
6696  }
6697 
6698  write_number(static_cast<int16_t>(n));
6699  } else if (n <= (std::numeric_limits<int32_t>::max)()) {
6700  if (add_prefix) {
6701  oa->write_character(static_cast<CharType>('l')); // int32
6702  }
6703 
6704  write_number(static_cast<int32_t>(n));
6705  } else if (n <= (std::numeric_limits<int64_t>::max)()) {
6706  if (add_prefix) {
6707  oa->write_character(static_cast<CharType>('L')); // int64
6708  }
6709 
6710  write_number(static_cast<int64_t>(n));
6711  } else {
6712  JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
6713  }
6714  } else {
6715  if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)()) {
6716  if (add_prefix) {
6717  oa->write_character(static_cast<CharType>('i')); // int8
6718  }
6719 
6720  write_number(static_cast<int8_t>(n));
6721  } else if ((std::numeric_limits<uint8_t>::min)() <= n and n <=
6722  (std::numeric_limits<uint8_t>::max)()) {
6723  if (add_prefix) {
6724  oa->write_character(static_cast<CharType>('U')); // uint8
6725  }
6726 
6727  write_number(static_cast<uint8_t>(n));
6728  } else if ((std::numeric_limits<int16_t>::min)() <= n and n <=
6729  (std::numeric_limits<int16_t>::max)()) {
6730  if (add_prefix) {
6731  oa->write_character(static_cast<CharType>('I')); // int16
6732  }
6733 
6734  write_number(static_cast<int16_t>(n));
6735  } else if ((std::numeric_limits<int32_t>::min)() <= n and n <=
6736  (std::numeric_limits<int32_t>::max)()) {
6737  if (add_prefix) {
6738  oa->write_character(static_cast<CharType>('l')); // int32
6739  }
6740 
6741  write_number(static_cast<int32_t>(n));
6742  } else if ((std::numeric_limits<int64_t>::min)() <= n and n <=
6743  (std::numeric_limits<int64_t>::max)()) {
6744  if (add_prefix) {
6745  oa->write_character(static_cast<CharType>('L')); // int64
6746  }
6747 
6748  write_number(static_cast<int64_t>(n));
6749  }
6750  // LCOV_EXCL_START
6751  else {
6752  JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
6753  }
6754 
6755  // LCOV_EXCL_STOP
6756  }
6757  }
6758 
6768  char ubjson_prefix(const BasicJsonType &j) const noexcept
6769  {
6770  switch (j.type()) {
6771  case value_t::null:
6772  return 'Z';
6773 
6774  case value_t::boolean:
6775  return j.m_value.boolean ? 'T' : 'F';
6776 
6778  {
6779  if ((std::numeric_limits<int8_t>::min)() <=
6780  j.m_value.number_integer and j.m_value.number_integer <=
6781  (std::numeric_limits<int8_t>::max)()) {
6782  return 'i';
6783  } else if ((std::numeric_limits<uint8_t>::min)() <=
6784  j.m_value.number_integer and j.m_value.number_integer <=
6785  (std::numeric_limits<uint8_t>::max)()) {
6786  return 'U';
6787  } else if ((std::numeric_limits<int16_t>::min)() <=
6788  j.m_value.number_integer and j.m_value.number_integer <=
6789  (std::numeric_limits<int16_t>::max)()) {
6790  return 'I';
6791  } else if ((std::numeric_limits<int32_t>::min)() <=
6792  j.m_value.number_integer and j.m_value.number_integer <=
6793  (std::numeric_limits<int32_t>::max)()) {
6794  return 'l';
6795  } else { // no check and assume int64_t (see note above)
6796  return 'L';
6797  }
6798  }
6799 
6801  {
6802  if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)()) {
6803  return 'i';
6804  } else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)()) {
6805  return 'U';
6806  } else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)()) {
6807  return 'I';
6808  } else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)()) {
6809  return 'l';
6810  } else { // no check and assume int64_t (see note above)
6811  return 'L';
6812  }
6813  }
6814 
6815  case value_t::number_float:
6816  return 'D';
6817 
6818  case value_t::string:
6819  return 'S';
6820 
6821  case value_t::array:
6822  return '[';
6823 
6824  case value_t::object:
6825  return '{';
6826 
6827  default: // discarded values
6828  return 'N';
6829  }
6830  }
6831 
6832 private:
6834  const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6835 
6837  output_adapter_t<CharType> oa = nullptr;
6838 };
6839 
6840 } // namespace detail
6841 } // namespace nlohmann
6842 
6843 // #include <nlohmann/detail/output/serializer.hpp>
6844 
6845 
6846 #include <algorithm> // reverse, remove, fill, find, none_of
6847 #include <array> // array
6848 #include <cassert> // assert
6849 #include <ciso646> // and, or
6850 #include <clocale> // localeconv, lconv
6851 #include <cmath> // labs, isfinite, isnan, signbit
6852 #include <cstddef> // size_t, ptrdiff_t
6853 #include <cstdint> // uint8_t
6854 #include <cstdio> // snprintf
6855 #include <iomanip> // setfill
6856 #include <iterator> // next
6857 #include <limits> // numeric_limits
6858 #include <string> // string
6859 #include <sstream> // stringstream
6860 #include <type_traits> // is_same
6861 
6862 // #include <nlohmann/detail/exceptions.hpp>
6863 
6864 // #include <nlohmann/detail/conversions/to_chars.hpp>
6865 
6866 
6867 #include <cassert> // assert
6868 #include <ciso646> // or, and, not
6869 #include <cmath> // signbit, isfinite
6870 #include <cstdint> // intN_t, uintN_t
6871 #include <cstring> // memcpy, memmove
6872 
6873 namespace nlohmann
6874 {
6875 namespace detail
6876 {
6877 
6897 namespace dtoa_impl
6898 {
6899 
6900 template<typename Target, typename Source>
6901 Target reinterpret_bits(const Source source)
6902 {
6903  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
6904 
6905  Target target;
6906  std::memcpy(&target, &source, sizeof(Source));
6907  return target;
6908 }
6909 
6910 struct diyfp // f * 2^e
6911 {
6912  static constexpr int kPrecision = 64; // = q
6913 
6914  uint64_t f;
6915  int e;
6916 
6917  constexpr diyfp() noexcept : f(0), e(0) {}
6918  constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
6919 
6924  static diyfp sub(const diyfp &x, const diyfp &y) noexcept
6925  {
6926  assert(x.e == y.e);
6927  assert(x.f >= y.f);
6928 
6929  return diyfp(x.f - y.f, x.e);
6930  }
6931 
6936  static diyfp mul(const diyfp &x, const diyfp &y) noexcept
6937  {
6938  static_assert(kPrecision == 64, "internal error");
6939 
6940  // Computes:
6941  // f = round((x.f * y.f) / 2^q)
6942  // e = x.e + y.e + q
6943 
6944  // Emulate the 64-bit * 64-bit multiplication:
6945  //
6946  // p = u * v
6947  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
6948  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
6949  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
6950  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
6951  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
6952  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
6953  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
6954  //
6955  // (Since Q might be larger than 2^32 - 1)
6956  //
6957  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
6958  //
6959  // (Q_hi + H does not overflow a 64-bit int)
6960  //
6961  // = p_lo + 2^64 p_hi
6962 
6963  const uint64_t u_lo = x.f & 0xFFFFFFFF;
6964  const uint64_t u_hi = x.f >> 32;
6965  const uint64_t v_lo = y.f & 0xFFFFFFFF;
6966  const uint64_t v_hi = y.f >> 32;
6967 
6968  const uint64_t p0 = u_lo * v_lo;
6969  const uint64_t p1 = u_lo * v_hi;
6970  const uint64_t p2 = u_hi * v_lo;
6971  const uint64_t p3 = u_hi * v_hi;
6972 
6973  const uint64_t p0_hi = p0 >> 32;
6974  const uint64_t p1_lo = p1 & 0xFFFFFFFF;
6975  const uint64_t p1_hi = p1 >> 32;
6976  const uint64_t p2_lo = p2 & 0xFFFFFFFF;
6977  const uint64_t p2_hi = p2 >> 32;
6978 
6979  uint64_t Q = p0_hi + p1_lo + p2_lo;
6980 
6981  // The full product might now be computed as
6982  //
6983  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
6984  // p_lo = p0_lo + (Q << 32)
6985  //
6986  // But in this particular case here, the full p_lo is not required.
6987  // Effectively we only need to add the highest bit in p_lo to p_hi (and
6988  // Q_hi + 1 does not overflow).
6989 
6990  Q += uint64_t { 1 } << (64 - 32 - 1); // round, ties up
6991 
6992  const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
6993 
6994  return diyfp(h, x.e + y.e + 64);
6995  }
6996 
7001  static diyfp normalize(diyfp x) noexcept
7002  {
7003  assert(x.f != 0);
7004 
7005  while ((x.f >> 63) == 0) {
7006  x.f <<= 1;
7007  x.e--;
7008  }
7009 
7010  return x;
7011  }
7012 
7017  static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
7018  {
7019  const int delta = x.e - target_exponent;
7020 
7021  assert(delta >= 0);
7022  assert(((x.f << delta) >> delta) == x.f);
7023 
7024  return diyfp(x.f << delta, target_exponent);
7025  }
7026 };
7027 
7029 {
7030  diyfp w;
7031  diyfp minus;
7032  diyfp plus;
7033 };
7034 
7041 template<typename FloatType>
7043 {
7044  assert(std::isfinite(value));
7045  assert(value > 0);
7046 
7047  // Convert the IEEE representation into a diyfp.
7048  //
7049  // If v is denormal:
7050  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
7051  // If v is normalized:
7052  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
7053 
7054  static_assert(std::numeric_limits<FloatType>::is_iec559,
7055  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7056 
7057  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
7058  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7059  constexpr int kMinExp = 1 - kBias;
7060  constexpr uint64_t kHiddenBit = uint64_t { 1 } << (kPrecision - 1); // = 2^(p-1)
7061 
7062  using bits_type = typename std::conditional<kPrecision == 24, uint32_t, uint64_t>::type;
7063 
7064  const uint64_t bits = reinterpret_bits<bits_type>(value);
7065  const uint64_t E = bits >> (kPrecision - 1);
7066  const uint64_t F = bits & (kHiddenBit - 1);
7067 
7068  const bool is_denormal = (E == 0);
7069  const diyfp v = is_denormal
7070  ? diyfp(F, kMinExp)
7071  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
7072 
7073  // Compute the boundaries m- and m+ of the floating-point value
7074  // v = f * 2^e.
7075  //
7076  // Determine v- and v+, the floating-point predecessor and successor if v,
7077  // respectively.
7078  //
7079  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
7080  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
7081  //
7082  // v+ = v + 2^e
7083  //
7084  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
7085  // between m- and m+ round to v, regardless of how the input rounding
7086  // algorithm breaks ties.
7087  //
7088  // ---+-------------+-------------+-------------+-------------+--- (A)
7089  // v- m- v m+ v+
7090  //
7091  // -----------------+------+------+-------------+-------------+--- (B)
7092  // v- m- v m+ v+
7093 
7094  const bool lower_boundary_is_closer = (F == 0 and E > 1);
7095  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
7096  const diyfp m_minus = lower_boundary_is_closer
7097  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
7098  : diyfp(2 * v.f - 1, v.e - 1); // (A)
7099 
7100  // Determine the normalized w+ = m+.
7101  const diyfp w_plus = diyfp::normalize(m_plus);
7102 
7103  // Determine w- = m- such that e_(w-) = e_(w+).
7104  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
7105 
7106  return { diyfp::normalize(v), w_minus, w_plus };
7107 }
7108 
7109 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
7110 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
7111 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
7112 //
7113 // alpha <= e = e_c + e_w + q <= gamma
7114 //
7115 // or
7116 //
7117 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
7118 // <= f_c * f_w * 2^gamma
7119 //
7120 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
7121 //
7122 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
7123 //
7124 // or
7125 //
7126 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
7127 //
7128 // The choice of (alpha,gamma) determines the size of the table and the form of
7129 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
7130 // in practice:
7131 //
7132 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
7133 // processed independently: An integral part p1, and a fractional part p2:
7134 //
7135 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
7136 // = (f div 2^-e) + (f mod 2^-e) * 2^e
7137 // = p1 + p2 * 2^e
7138 //
7139 // The conversion of p1 into decimal form requires a series of divisions and
7140 // modulos by (a power of) 10. These operations are faster for 32-bit than for
7141 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
7142 // achieved by choosing
7143 //
7144 // -e >= 32 or e <= -32 := gamma
7145 //
7146 // In order to convert the fractional part
7147 //
7148 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
7149 //
7150 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
7151 // d[-i] are extracted in order:
7152 //
7153 // (10 * p2) div 2^-e = d[-1]
7154 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
7155 //
7156 // The multiplication by 10 must not overflow. It is sufficient to choose
7157 //
7158 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
7159 //
7160 // Since p2 = f mod 2^-e < 2^-e,
7161 //
7162 // -e <= 60 or e >= -60 := alpha
7163 
7164 constexpr int kAlpha = -60;
7165 constexpr int kGamma = -32;
7166 
7167 struct cached_power // c = f * 2^e ~= 10^k
7168 {
7169  uint64_t f;
7170  int e;
7171  int k;
7172 };
7173 
7182 {
7183  // Now
7184  //
7185  // alpha <= e_c + e + q <= gamma (1)
7186  // ==> f_c * 2^alpha <= c * 2^e * 2^q
7187  //
7188  // and since the c's are normalized, 2^(q-1) <= f_c,
7189  //
7190  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
7191  // ==> 2^(alpha - e - 1) <= c
7192  //
7193  // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
7194  //
7195  // k = ceil( log_10( 2^(alpha - e - 1) ) )
7196  // = ceil( (alpha - e - 1) * log_10(2) )
7197  //
7198  // From the paper:
7199  // "In theory the result of the procedure could be wrong since c is rounded,
7200  // and the computation itself is approximated [...]. In practice, however,
7201  // this simple function is sufficient."
7202  //
7203  // For IEEE double precision floating-point numbers converted into
7204  // normalized diyfp's w = f * 2^e, with q = 64,
7205  //
7206  // e >= -1022 (min IEEE exponent)
7207  // -52 (p - 1)
7208  // -52 (p - 1, possibly normalize denormal IEEE numbers)
7209  // -11 (normalize the diyfp)
7210  // = -1137
7211  //
7212  // and
7213  //
7214  // e <= +1023 (max IEEE exponent)
7215  // -52 (p - 1)
7216  // -11 (normalize the diyfp)
7217  // = 960
7218  //
7219  // This binary exponent range [-1137,960] results in a decimal exponent
7220  // range [-307,324]. One does not need to store a cached power for each
7221  // k in this range. For each such k it suffices to find a cached power
7222  // such that the exponent of the product lies in [alpha,gamma].
7223  // This implies that the difference of the decimal exponents of adjacent
7224  // table entries must be less than or equal to
7225  //
7226  // floor( (gamma - alpha) * log_10(2) ) = 8.
7227  //
7228  // (A smaller distance gamma-alpha would require a larger table.)
7229 
7230  // NB:
7231  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
7232 
7233  constexpr int kCachedPowersSize = 79;
7234  constexpr int kCachedPowersMinDecExp = -300;
7235  constexpr int kCachedPowersDecStep = 8;
7236 
7237  static constexpr cached_power kCachedPowers[] =
7238  {
7239  { 0xAB70FE17C79AC6CA, -1060, -300 },
7240  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7241  { 0xBE5691EF416BD60C, -1007, -284 },
7242  { 0x8DD01FAD907FFC3C, -980, -276 },
7243  { 0xD3515C2831559A83, -954, -268 },
7244  { 0x9D71AC8FADA6C9B5, -927, -260 },
7245  { 0xEA9C227723EE8BCB, -901, -252 },
7246  { 0xAECC49914078536D, -874, -244 },
7247  { 0x823C12795DB6CE57, -847, -236 },
7248  { 0xC21094364DFB5637, -821, -228 },
7249  { 0x9096EA6F3848984F, -794, -220 },
7250  { 0xD77485CB25823AC7, -768, -212 },
7251  { 0xA086CFCD97BF97F4, -741, -204 },
7252  { 0xEF340A98172AACE5, -715, -196 },
7253  { 0xB23867FB2A35B28E, -688, -188 },
7254  { 0x84C8D4DFD2C63F3B, -661, -180 },
7255  { 0xC5DD44271AD3CDBA, -635, -172 },
7256  { 0x936B9FCEBB25C996, -608, -164 },
7257  { 0xDBAC6C247D62A584, -582, -156 },
7258  { 0xA3AB66580D5FDAF6, -555, -148 },
7259  { 0xF3E2F893DEC3F126, -529, -140 },
7260  { 0xB5B5ADA8AAFF80B8, -502, -132 },
7261  { 0x87625F056C7C4A8B, -475, -124 },
7262  { 0xC9BCFF6034C13053, -449, -116 },
7263  { 0x964E858C91BA2655, -422, -108 },
7264  { 0xDFF9772470297EBD, -396, -100 },
7265  { 0xA6DFBD9FB8E5B88F, -369, -92 },
7266  { 0xF8A95FCF88747D94, -343, -84 },
7267  { 0xB94470938FA89BCF, -316, -76 },
7268  { 0x8A08F0F8BF0F156B, -289, -68 },
7269  { 0xCDB02555653131B6, -263, -60 },
7270  { 0x993FE2C6D07B7FAC, -236, -52 },
7271  { 0xE45C10C42A2B3B06, -210, -44 },
7272  { 0xAA242499697392D3, -183, -36 },
7273  { 0xFD87B5F28300CA0E, -157, -28 },
7274  { 0xBCE5086492111AEB, -130, -20 },
7275  { 0x8CBCCC096F5088CC, -103, -12 },
7276  { 0xD1B71758E219652C, -77, -4 },
7277  { 0x9C40000000000000, -50, 4 },
7278  { 0xE8D4A51000000000, -24, 12 },
7279  { 0xAD78EBC5AC620000, 3, 20 },
7280  { 0x813F3978F8940984, 30, 28 },
7281  { 0xC097CE7BC90715B3, 56, 36 },
7282  { 0x8F7E32CE7BEA5C70, 83, 44 },
7283  { 0xD5D238A4ABE98068, 109, 52 },
7284  { 0x9F4F2726179A2245, 136, 60 },
7285  { 0xED63A231D4C4FB27, 162, 68 },
7286  { 0xB0DE65388CC8ADA8, 189, 76 },
7287  { 0x83C7088E1AAB65DB, 216, 84 },
7288  { 0xC45D1DF942711D9A, 242, 92 },
7289  { 0x924D692CA61BE758, 269, 100 },
7290  { 0xDA01EE641A708DEA, 295, 108 },
7291  { 0xA26DA3999AEF774A, 322, 116 },
7292  { 0xF209787BB47D6B85, 348, 124 },
7293  { 0xB454E4A179DD1877, 375, 132 },
7294  { 0x865B86925B9BC5C2, 402, 140 },
7295  { 0xC83553C5C8965D3D, 428, 148 },
7296  { 0x952AB45CFA97A0B3, 455, 156 },
7297  { 0xDE469FBD99A05FE3, 481, 164 },
7298  { 0xA59BC234DB398C25, 508, 172 },
7299  { 0xF6C69A72A3989F5C, 534, 180 },
7300  { 0xB7DCBF5354E9BECE, 561, 188 },
7301  { 0x88FCF317F22241E2, 588, 196 },
7302  { 0xCC20CE9BD35C78A5, 614, 204 },
7303  { 0x98165AF37B2153DF, 641, 212 },
7304  { 0xE2A0B5DC971F303A, 667, 220 },
7305  { 0xA8D9D1535CE3B396, 694, 228 },
7306  { 0xFB9B7CD9A4A7443C, 720, 236 },
7307  { 0xBB764C4CA7A44410, 747, 244 },
7308  { 0x8BAB8EEFB6409C1A, 774, 252 },
7309  { 0xD01FEF10A657842C, 800, 260 },
7310  { 0x9B10A4E5E9913129, 827, 268 },
7311  { 0xE7109BFBA19C0C9D, 853, 276 },
7312  { 0xAC2820D9623BF429, 880, 284 },
7313  { 0x80444B5E7AA7CF85, 907, 292 },
7314  { 0xBF21E44003ACDD2D, 933, 300 },
7315  { 0x8E679C2F5E44FF8F, 960, 308 },
7316  { 0xD433179D9C8CB841, 986, 316 },
7317  { 0x9E19DB92B4E31BA9, 1013, 324 },
7318  };
7319 
7320  // This computation gives exactly the same results for k as
7321  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
7322  // for |e| <= 1500, but doesn't require floating-point operations.
7323  // NB: log_10(2) ~= 78913 / 2^18
7324  assert(e >= -1500);
7325  assert(e <= 1500);
7326  const int f = kAlpha - e - 1;
7327  const int k = (f * 78913) / (1 << 18) + (f > 0);
7328 
7329  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7330  assert(index >= 0);
7331  assert(index < kCachedPowersSize);
7332  static_cast<void>(kCachedPowersSize); // Fix warning.
7333 
7334  const cached_power cached = kCachedPowers[index];
7335  assert(kAlpha <= cached.e + e + 64);
7336  assert(kGamma >= cached.e + e + 64);
7337 
7338  return cached;
7339 }
7340 
7345 inline int find_largest_pow10(const uint32_t n, uint32_t &pow10)
7346 {
7347  // LCOV_EXCL_START
7348  if (n >= 1000000000) {
7349  pow10 = 1000000000;
7350  return 10;
7351  }
7352  // LCOV_EXCL_STOP
7353  else if (n >= 100000000) {
7354  pow10 = 100000000;
7355  return 9;
7356  } else if (n >= 10000000) {
7357  pow10 = 10000000;
7358  return 8;
7359  } else if (n >= 1000000) {
7360  pow10 = 1000000;
7361  return 7;
7362  } else if (n >= 100000) {
7363  pow10 = 100000;
7364  return 6;
7365  } else if (n >= 10000) {
7366  pow10 = 10000;
7367  return 5;
7368  } else if (n >= 1000) {
7369  pow10 = 1000;
7370  return 4;
7371  } else if (n >= 100) {
7372  pow10 = 100;
7373  return 3;
7374  } else if (n >= 10) {
7375  pow10 = 10;
7376  return 2;
7377  } else {
7378  pow10 = 1;
7379  return 1;
7380  }
7381 }
7382 
7383 inline void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta,
7384  uint64_t rest, uint64_t ten_k)
7385 {
7386  assert(len >= 1);
7387  assert(dist <= delta);
7388  assert(rest <= delta);
7389  assert(ten_k > 0);
7390 
7391  // <--------------------------- delta ---->
7392  // <---- dist --------->
7393  // --------------[------------------+-------------------]--------------
7394  // M- w M+
7395  //
7396  // ten_k
7397  // <------>
7398  // <---- rest ---->
7399  // --------------[------------------+----+--------------]--------------
7400  // w V
7401  // = buf * 10^k
7402  //
7403  // ten_k represents a unit-in-the-last-place in the decimal representation
7404  // stored in buf.
7405  // Decrement buf by ten_k while this takes buf closer to w.
7406 
7407  // The tests are written in this order to avoid overflow in unsigned
7408  // integer arithmetic.
7409 
7410  while (rest < dist
7411  and delta - rest >= ten_k
7412  and (rest + ten_k<dist or dist - rest> rest + ten_k - dist)) {
7413  assert(buf[len - 1] != '0');
7414  buf[len - 1]--;
7415  rest += ten_k;
7416  }
7417 }
7418 
7423 inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent,
7424  diyfp M_minus, diyfp w, diyfp M_plus)
7425 {
7426  static_assert(kAlpha >= -60, "internal error");
7427  static_assert(kGamma <= -32, "internal error");
7428 
7429  // Generates the digits (and the exponent) of a decimal floating-point
7430  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
7431  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
7432  //
7433  // <--------------------------- delta ---->
7434  // <---- dist --------->
7435  // --------------[------------------+-------------------]--------------
7436  // M- w M+
7437  //
7438  // Grisu2 generates the digits of M+ from left to right and stops as soon as
7439  // V is in [M-,M+].
7440 
7441  assert(M_plus.e >= kAlpha);
7442  assert(M_plus.e <= kGamma);
7443 
7444  uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
7445  uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
7446 
7447  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
7448  //
7449  // M+ = f * 2^e
7450  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
7451  // = ((p1 ) * 2^-e + (p2 )) * 2^e
7452  // = p1 + p2 * 2^e
7453 
7454  const diyfp one(uint64_t { 1 } << -M_plus.e, M_plus.e);
7455 
7456  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.)
7457  uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
7458 
7459  // 1)
7460  //
7461  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
7462 
7463  assert(p1 > 0);
7464 
7465  uint32_t pow10;
7466  const int k = find_largest_pow10(p1, pow10);
7467 
7468  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
7469  //
7470  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
7471  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
7472  //
7473  // M+ = p1 + p2 * 2^e
7474  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
7475  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
7476  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
7477  //
7478  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
7479  //
7480  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
7481  //
7482  // but stop as soon as
7483  //
7484  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
7485 
7486  int n = k;
7487  while (n > 0) {
7488  // Invariants:
7489  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
7490  // pow10 = 10^(n-1) <= p1 < 10^n
7491  //
7492  const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
7493  const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
7494  //
7495  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
7496  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
7497  //
7498  assert(d <= 9);
7499  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7500  //
7501  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
7502  //
7503  p1 = r;
7504  n--;
7505  //
7506  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
7507  // pow10 = 10^n
7508  //
7509 
7510  // Now check if enough digits have been generated.
7511  // Compute
7512  //
7513  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
7514  //
7515  // Note:
7516  // Since rest and delta share the same exponent e, it suffices to
7517  // compare the significands.
7518  const uint64_t rest = (uint64_t { p1 } << -one.e) + p2;
7519  if (rest <= delta) {
7520  // V = buffer * 10^n, with M- <= V <= M+.
7521 
7522  decimal_exponent += n;
7523 
7524  // We may now just stop. But instead look if the buffer could be
7525  // decremented to bring V closer to w.
7526  //
7527  // pow10 = 10^n is now 1 ulp in the decimal representation V.
7528  // The rounding procedure works with diyfp's with an implicit
7529  // exponent of e.
7530  //
7531  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
7532  //
7533  const uint64_t ten_n = uint64_t { pow10 } << -one.e;
7534  grisu2_round(buffer, length, dist, delta, rest, ten_n);
7535 
7536  return;
7537  }
7538 
7539  pow10 /= 10;
7540  //
7541  // pow10 = 10^(n-1) <= p1 < 10^n
7542  // Invariants restored.
7543  }
7544 
7545  // 2)
7546  //
7547  // The digits of the integral part have been generated:
7548  //
7549  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
7550  // = buffer + p2 * 2^e
7551  //
7552  // Now generate the digits of the fractional part p2 * 2^e.
7553  //
7554  // Note:
7555  // No decimal point is generated: the exponent is adjusted instead.
7556  //
7557  // p2 actually represents the fraction
7558  //
7559  // p2 * 2^e
7560  // = p2 / 2^-e
7561  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
7562  //
7563  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
7564  //
7565  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
7566  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
7567  //
7568  // using
7569  //
7570  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
7571  // = ( d) * 2^-e + ( r)
7572  //
7573  // or
7574  // 10^m * p2 * 2^e = d + r * 2^e
7575  //
7576  // i.e.
7577  //
7578  // M+ = buffer + p2 * 2^e
7579  // = buffer + 10^-m * (d + r * 2^e)
7580  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
7581  //
7582  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
7583 
7584  assert(p2 > delta);
7585 
7586  int m = 0;
7587  for (;;) {
7588  // Invariant:
7589  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
7590  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
7591  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
7592  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
7593  //
7594  assert(p2 <= UINT64_MAX / 10);
7595  p2 *= 10;
7596  const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
7597  const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
7598  //
7599  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
7600  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
7601  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
7602  //
7603  assert(d <= 9);
7604  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7605  //
7606  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
7607  //
7608  p2 = r;
7609  m++;
7610  //
7611  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
7612  // Invariant restored.
7613 
7614  // Check if enough digits have been generated.
7615  //
7616  // 10^-m * p2 * 2^e <= delta * 2^e
7617  // p2 * 2^e <= 10^m * delta * 2^e
7618  // p2 <= 10^m * delta
7619  delta *= 10;
7620  dist *= 10;
7621  if (p2 <= delta) {
7622  break;
7623  }
7624  }
7625 
7626  // V = buffer * 10^-m, with M- <= V <= M+.
7627 
7628  decimal_exponent -= m;
7629 
7630  // 1 ulp in the decimal representation is now 10^-m.
7631  // Since delta and dist are now scaled by 10^m, we need to do the
7632  // same with ulp in order to keep the units in sync.
7633  //
7634  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
7635  //
7636  const uint64_t ten_m = one.f;
7637  grisu2_round(buffer, length, dist, delta, p2, ten_m);
7638 
7639  // By construction this algorithm generates the shortest possible decimal
7640  // number (Loitsch, Theorem 6.2) which rounds back to w.
7641  // For an input number of precision p, at least
7642  //
7643  // N = 1 + ceil(p * log_10(2))
7644  //
7645  // decimal digits are sufficient to identify all binary floating-point
7646  // numbers (Matula, "In-and-Out conversions").
7647  // This implies that the algorithm does not produce more than N decimal
7648  // digits.
7649  //
7650  // N = 17 for p = 53 (IEEE double precision)
7651  // N = 9 for p = 24 (IEEE single precision)
7652 }
7653 
7659 inline void grisu2(char *buf, int &len, int &decimal_exponent,
7660  diyfp m_minus, diyfp v, diyfp m_plus)
7661 {
7662  assert(m_plus.e == m_minus.e);
7663  assert(m_plus.e == v.e);
7664 
7665  // --------(-----------------------+-----------------------)-------- (A)
7666  // m- v m+
7667  //
7668  // --------------------(-----------+-----------------------)-------- (B)
7669  // m- v m+
7670  //
7671  // First scale v (and m- and m+) such that the exponent is in the range
7672  // [alpha, gamma].
7673 
7674  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
7675 
7676  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
7677 
7678  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
7679  const diyfp w = diyfp::mul(v, c_minus_k);
7680  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7681  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
7682 
7683  // ----(---+---)---------------(---+---)---------------(---+---)----
7684  // w- w w+
7685  // = c*m- = c*v = c*m+
7686  //
7687  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
7688  // w+ are now off by a small amount.
7689  // In fact:
7690  //
7691  // w - v * 10^k < 1 ulp
7692  //
7693  // To account for this inaccuracy, add resp. subtract 1 ulp.
7694  //
7695  // --------+---[---------------(---+---)---------------]---+--------
7696  // w- M- w M+ w+
7697  //
7698  // Now any number in [M-, M+] (bounds included) will round to w when input,
7699  // regardless of how the input rounding algorithm breaks ties.
7700  //
7701  // And digit_gen generates the shortest possible such number in [M-, M+].
7702  // Note that this does not mean that Grisu2 always generates the shortest
7703  // possible number in the interval (m-, m+).
7704  const diyfp M_minus(w_minus.f + 1, w_minus.e);
7705  const diyfp M_plus(w_plus.f - 1, w_plus.e);
7706 
7707  decimal_exponent = -cached.k; // = -(-k) = k
7708 
7709  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
7710 }
7711 
7717 template<typename FloatType>
7718 void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
7719 {
7720  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
7721  "internal error: not enough precision");
7722 
7723  assert(std::isfinite(value));
7724  assert(value > 0);
7725 
7726  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
7727  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
7728  // decimal representations are not exactly "short".
7729  //
7730  // The documentation for 'std::to_chars' (http://en.cppreference.com/w/cpp/utility/to_chars)
7731  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
7732  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
7733  // does.
7734  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
7735  // representation using the corresponding std::from_chars function recovers value exactly". That
7736  // indicates that single precision floating-point numbers should be recovered using
7737  // 'std::strtof'.
7738  //
7739  // NB: If the neighbors are computed for single-precision numbers, there is a single float
7740  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
7741  // value is off by 1 ulp.
7742 #if 0
7743  const boundaries w = compute_boundaries(static_cast<double>(value));
7744 #else
7745  const boundaries w = compute_boundaries(value);
7746 #endif
7747 
7748  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
7749 }
7750 
7756 inline char *append_exponent(char *buf, int e)
7757 {
7758  assert(e > -1000);
7759  assert(e < 1000);
7760 
7761  if (e < 0) {
7762  e = -e;
7763  *buf++ = '-';
7764  } else {
7765  *buf++ = '+';
7766  }
7767 
7768  uint32_t k = static_cast<uint32_t>(e);
7769  if (k < 10) {
7770  // Always print at least two digits in the exponent.
7771  // This is for compatibility with printf("%g").
7772  *buf++ = '0';
7773  *buf++ = static_cast<char>('0' + k);
7774  } else if (k < 100) {
7775  *buf++ = static_cast<char>('0' + k / 10);
7776  k %= 10;
7777  *buf++ = static_cast<char>('0' + k);
7778  } else {
7779  *buf++ = static_cast<char>('0' + k / 100);
7780  k %= 100;
7781  *buf++ = static_cast<char>('0' + k / 10);
7782  k %= 10;
7783  *buf++ = static_cast<char>('0' + k);
7784  }
7785 
7786  return buf;
7787 }
7788 
7798 inline char *format_buffer(char *buf, int len, int decimal_exponent,
7799  int min_exp, int max_exp)
7800 {
7801  assert(min_exp < 0);
7802  assert(max_exp > 0);
7803 
7804  const int k = len;
7805  const int n = len + decimal_exponent;
7806 
7807  // v = buf * 10^(n-k)
7808  // k is the length of the buffer (number of decimal digits)
7809  // n is the position of the decimal point relative to the start of the buffer.
7810 
7811  if (k <= n and n <= max_exp) {
7812  // digits[000]
7813  // len <= max_exp + 2
7814 
7815  std::memset(buf + k, '0', static_cast<size_t>(n - k));
7816  // Make it look like a floating-point number (#362, #378)
7817  buf[n + 0] = '.';
7818  buf[n + 1] = '0';
7819  return buf + (n + 2);
7820  }
7821 
7822  if (0 < n and n <= max_exp) {
7823  // dig.its
7824  // len <= max_digits10 + 1
7825 
7826  assert(k > n);
7827 
7828  std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
7829  buf[n] = '.';
7830  return buf + (k + 1);
7831  }
7832 
7833  if (min_exp < n and n <= 0) {
7834  // 0.[000]digits
7835  // len <= 2 + (-min_exp - 1) + max_digits10
7836 
7837  std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
7838  buf[0] = '0';
7839  buf[1] = '.';
7840  std::memset(buf + 2, '0', static_cast<size_t>(-n));
7841  return buf + (2 + (-n) + k);
7842  }
7843 
7844  if (k == 1) {
7845  // dE+123
7846  // len <= 1 + 5
7847 
7848  buf += 1;
7849  } else {
7850  // d.igitsE+123
7851  // len <= max_digits10 + 1 + 5
7852 
7853  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
7854  buf[1] = '.';
7855  buf += 1 + k;
7856  }
7857 
7858  *buf++ = 'e';
7859  return append_exponent(buf, n - 1);
7860 }
7861 
7862 } // namespace dtoa_impl
7863 
7874 template<typename FloatType>
7875 char *to_chars(char *first, char *last, FloatType value)
7876 {
7877  static_cast<void>(last); // maybe unused - fix warning
7878  assert(std::isfinite(value));
7879 
7880  // Use signbit(value) instead of (value < 0) since signbit works for -0.
7881  if (std::signbit(value)) {
7882  value = -value;
7883  *first++ = '-';
7884  }
7885 
7886  if (value == 0) { // +-0
7887  *first++ = '0';
7888  // Make it look like a floating-point number (#362, #378)
7889  *first++ = '.';
7890  *first++ = '0';
7891  return first;
7892  }
7893 
7894  assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
7895 
7896  // Compute v = buffer * 10^decimal_exponent.
7897  // The decimal digits are stored in the buffer, which needs to be interpreted
7898  // as an unsigned decimal integer.
7899  // len is the length of the buffer, i.e. the number of decimal digits.
7900  int len = 0;
7901  int decimal_exponent = 0;
7902  dtoa_impl::grisu2(first, len, decimal_exponent, value);
7903 
7904  assert(len <= std::numeric_limits<FloatType>::max_digits10);
7905 
7906  // Format the buffer like printf("%.*g", prec, value)
7907  constexpr int kMinExp = -4;
7908  // Use digits10 here to increase compatibility with version 2.
7909  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
7910 
7911  assert(last - first >= kMaxExp + 2);
7912  assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
7913  assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
7914 
7915  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
7916 }
7917 
7918 } // namespace detail
7919 } // namespace nlohmann
7920 
7921 // #include <nlohmann/detail/macro_scope.hpp>
7922 
7923 // #include <nlohmann/detail/meta.hpp>
7924 
7925 // #include <nlohmann/detail/output/output_adapters.hpp>
7926 
7927 // #include <nlohmann/detail/value_t.hpp>
7928 
7929 
7930 namespace nlohmann
7931 {
7932 namespace detail
7933 {
7935 // serialization //
7937 
7938 template<typename BasicJsonType>
7939 
7941 {
7942  using string_t = typename BasicJsonType::string_t;
7943  using number_float_t = typename BasicJsonType::number_float_t;
7944  using number_integer_t = typename BasicJsonType::number_integer_t;
7945  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7946  static constexpr uint8_t UTF8_ACCEPT = 0;
7947  static constexpr uint8_t UTF8_REJECT = 1;
7948 
7949 public:
7954  serializer(output_adapter_t<char> s, const char ichar)
7955  : o(std::move(s)), loc(std::localeconv()),
7956  thousands_sep(loc->thousands_sep == nullptr ? '\0' : *(loc->thousands_sep)), decimal_point(
7957  loc->decimal_point == nullptr ? '\0' : *(loc->decimal_point)), indent_char(ichar), indent_string(
7958  512, indent_char)
7959  {}
7960 
7961  // delete because of pointer members
7962  serializer(const serializer &) = delete;
7963  serializer &operator=(const serializer &) = delete;
7964 
7982  void dump(const BasicJsonType &val, const bool pretty_print,
7983  const bool ensure_ascii,
7984  const unsigned int indent_step,
7985  const unsigned int current_indent = 0)
7986  {
7987  switch (val.m_type) {
7988  case value_t::object:
7989  {
7990  if (val.m_value.object->empty()) {
7991  o->write_characters("{}", 2);
7992  return;
7993  }
7994 
7995  if (pretty_print) {
7996  o->write_characters("{\n", 2);
7997 
7998  // variable to hold indentation for recursive calls
7999  const auto new_indent = current_indent + indent_step;
8000  if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
8001  indent_string.resize(indent_string.size() * 2, ' ');
8002  }
8003 
8004  // first n-1 elements
8005  auto i = val.m_value.object->cbegin();
8006  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
8007  o->write_characters(indent_string.c_str(), new_indent);
8008  o->write_character('\"');
8009  dump_escaped(i->first, ensure_ascii);
8010  o->write_characters("\": ", 3);
8011  dump(i->second, true, ensure_ascii, indent_step, new_indent);
8012  o->write_characters(",\n", 2);
8013  }
8014 
8015  // last element
8016  assert(i != val.m_value.object->cend());
8017  assert(std::next(i) == val.m_value.object->cend());
8018  o->write_characters(indent_string.c_str(), new_indent);
8019  o->write_character('\"');
8020  dump_escaped(i->first, ensure_ascii);
8021  o->write_characters("\": ", 3);
8022  dump(i->second, true, ensure_ascii, indent_step, new_indent);
8023 
8024  o->write_character('\n');
8025  o->write_characters(indent_string.c_str(), current_indent);
8026  o->write_character('}');
8027  } else {
8028  o->write_character('{');
8029 
8030  // first n-1 elements
8031  auto i = val.m_value.object->cbegin();
8032  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i) {
8033  o->write_character('\"');
8034  dump_escaped(i->first, ensure_ascii);
8035  o->write_characters("\":", 2);
8036  dump(i->second, false, ensure_ascii, indent_step, current_indent);
8037  o->write_character(',');
8038  }
8039 
8040  // last element
8041  assert(i != val.m_value.object->cend());
8042  assert(std::next(i) == val.m_value.object->cend());
8043  o->write_character('\"');
8044  dump_escaped(i->first, ensure_ascii);
8045  o->write_characters("\":", 2);
8046  dump(i->second, false, ensure_ascii, indent_step, current_indent);
8047 
8048  o->write_character('}');
8049  }
8050 
8051  return;
8052  }
8053 
8054  case value_t::array:
8055  {
8056  if (val.m_value.array->empty()) {
8057  o->write_characters("[]", 2);
8058  return;
8059  }
8060 
8061  if (pretty_print) {
8062  o->write_characters("[\n", 2);
8063 
8064  // variable to hold indentation for recursive calls
8065  const auto new_indent = current_indent + indent_step;
8066  if (JSON_UNLIKELY(indent_string.size() < new_indent)) {
8067  indent_string.resize(indent_string.size() * 2, ' ');
8068  }
8069 
8070  // first n-1 elements
8071  for (auto i = val.m_value.array->cbegin();
8072  i != val.m_value.array->cend() - 1; ++i) {
8073  o->write_characters(indent_string.c_str(), new_indent);
8074  dump(*i, true, ensure_ascii, indent_step, new_indent);
8075  o->write_characters(",\n", 2);
8076  }
8077 
8078  // last element
8079  assert(not val.m_value.array->empty());
8080  o->write_characters(indent_string.c_str(), new_indent);
8081  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
8082 
8083  o->write_character('\n');
8084  o->write_characters(indent_string.c_str(), current_indent);
8085  o->write_character(']');
8086  } else {
8087  o->write_character('[');
8088 
8089  // first n-1 elements
8090  for (auto i = val.m_value.array->cbegin();
8091  i != val.m_value.array->cend() - 1; ++i) {
8092  dump(*i, false, ensure_ascii, indent_step, current_indent);
8093  o->write_character(',');
8094  }
8095 
8096  // last element
8097  assert(not val.m_value.array->empty());
8098  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
8099 
8100  o->write_character(']');
8101  }
8102 
8103  return;
8104  }
8105 
8106  case value_t::string:
8107  {
8108  o->write_character('\"');
8109  dump_escaped(*val.m_value.string, ensure_ascii);
8110  o->write_character('\"');
8111  return;
8112  }
8113 
8114  case value_t::boolean:
8115  {
8116  if (val.m_value.boolean) {
8117  o->write_characters("true", 4);
8118  } else {
8119  o->write_characters("false", 5);
8120  }
8121 
8122  return;
8123  }
8124 
8126  {
8127  dump_integer(val.m_value.number_integer);
8128  return;
8129  }
8130 
8132  {
8133  dump_integer(val.m_value.number_unsigned);
8134  return;
8135  }
8136 
8137  case value_t::number_float:
8138  {
8139  dump_float(val.m_value.number_float);
8140  return;
8141  }
8142 
8143  case value_t::discarded:
8144  {
8145  o->write_characters("<discarded>", 11);
8146  return;
8147  }
8148 
8149  case value_t::null:
8150  {
8151  o->write_characters("null", 4);
8152  return;
8153  }
8154  }
8155  }
8156 
8157 private:
8172  void dump_escaped(const string_t &s, const bool ensure_ascii)
8173  {
8174  uint32_t codepoint;
8175  uint8_t state = UTF8_ACCEPT;
8176  std::size_t bytes = 0; // number of bytes written to string_buffer
8177 
8178  for (std::size_t i = 0; i < s.size(); ++i) {
8179  const auto byte = static_cast<uint8_t>(s[i]);
8180 
8181  switch (decode(state, codepoint, byte)) {
8182  case UTF8_ACCEPT: // decode found a new code point
8183  {
8184  switch (codepoint) {
8185  case 0x08: // backspace
8186  {
8187  string_buffer[bytes++] = '\\';
8188  string_buffer[bytes++] = 'b';
8189  break;
8190  }
8191 
8192  case 0x09: // horizontal tab
8193  {
8194  string_buffer[bytes++] = '\\';
8195  string_buffer[bytes++] = 't';
8196  break;
8197  }
8198 
8199  case 0x0A: // newline
8200  {
8201  string_buffer[bytes++] = '\\';
8202  string_buffer[bytes++] = 'n';
8203  break;
8204  }
8205 
8206  case 0x0C: // formfeed
8207  {
8208  string_buffer[bytes++] = '\\';
8209  string_buffer[bytes++] = 'f';
8210  break;
8211  }
8212 
8213  case 0x0D: // carriage return
8214  {
8215  string_buffer[bytes++] = '\\';
8216  string_buffer[bytes++] = 'r';
8217  break;
8218  }
8219 
8220  case 0x22: // quotation mark
8221  {
8222  string_buffer[bytes++] = '\\';
8223  string_buffer[bytes++] = '\"';
8224  break;
8225  }
8226 
8227  case 0x5C: // reverse solidus
8228  {
8229  string_buffer[bytes++] = '\\';
8230  string_buffer[bytes++] = '\\';
8231  break;
8232  }
8233 
8234  default:
8235  {
8236  // escape control characters (0x00..0x1F) or, if
8237  // ensure_ascii parameter is used, non-ASCII characters
8238  if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F))) {
8239  if (codepoint <= 0xFFFF) {
8240  std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
8241  static_cast<uint16_t>(codepoint));
8242  bytes += 6;
8243  } else {
8244  std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
8245  static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
8246  static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
8247  bytes += 12;
8248  }
8249  } else {
8250  // copy byte to buffer (all previous bytes
8251  // been copied have in default case above)
8252  string_buffer[bytes++] = s[i];
8253  }
8254 
8255  break;
8256  }
8257  }
8258 
8259  // write buffer and reset index; there must be 13 bytes
8260  // left, as this is the maximal number of bytes to be
8261  // written ("\uxxxx\uxxxx\0") for one code point
8262  if (string_buffer.size() - bytes < 13) {
8263  o->write_characters(string_buffer.data(), bytes);
8264  bytes = 0;
8265  }
8266 
8267  break;
8268  }
8269 
8270  case UTF8_REJECT: // decode found invalid UTF-8 byte
8271  {
8272  std::stringstream ss;
8273  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex <<
8274  static_cast<int>(byte);
8275  JSON_THROW(type_error::create(316,
8276  "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" +
8277  ss.str()));
8278  }
8279 
8280  default: // decode found yet incomplete multi-byte code point
8281  {
8282  if (not ensure_ascii) {
8283  // code point will not be escaped - copy byte to buffer
8284  string_buffer[bytes++] = s[i];
8285  }
8286 
8287  break;
8288  }
8289  }
8290  }
8291 
8292  if (JSON_LIKELY(state == UTF8_ACCEPT)) {
8293  // write buffer
8294  if (bytes > 0) {
8295  o->write_characters(string_buffer.data(), bytes);
8296  }
8297  } else {
8298  // we finish reading, but do not accept: string was incomplete
8299  std::stringstream ss;
8300  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex <<
8301  static_cast<int>(static_cast<uint8_t>(s.back()));
8302  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str()));
8303  }
8304  }
8305 
8315  template<typename NumberType, detail::enable_if_t<
8316  std::is_same<NumberType, number_unsigned_t>::value or
8317  std::is_same<NumberType, number_integer_t>::value,
8318  int> = 0>
8319  void dump_integer(NumberType x)
8320  {
8321  // special case for "0"
8322  if (x == 0) {
8323  o->write_character('0');
8324  return;
8325  }
8326 
8327  const bool is_negative = (x <= 0) and (x != 0); // see issue #755
8328  std::size_t i = 0;
8329 
8330  while (x != 0) {
8331  // spare 1 byte for '\0'
8332  assert(i < number_buffer.size() - 1);
8333 
8334  const auto digit = std::labs(static_cast<long>(x % 10));
8335  number_buffer[i++] = static_cast<char>('0' + digit);
8336  x /= 10;
8337  }
8338 
8339  if (is_negative) {
8340  // make sure there is capacity for the '-'
8341  assert(i < number_buffer.size() - 2);
8342  number_buffer[i++] = '-';
8343  }
8344 
8345  std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8346  o->write_characters(number_buffer.data(), i);
8347  }
8348 
8357  void dump_float(number_float_t x)
8358  {
8359  // NaN / inf
8360  if (not std::isfinite(x)) {
8361  o->write_characters("null", 4);
8362  return;
8363  }
8364 
8365  // If number_float_t is an IEEE-754 single or double precision number,
8366  // use the Grisu2 algorithm to produce short numbers which are
8367  // guaranteed to round-trip, using strtof and strtod, resp.
8368  //
8369  // NB: The test below works if <long double> == <double>.
8370  static constexpr bool is_ieee_single_or_double
8371  = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits
8372  == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
8373  (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::
8374  digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
8375 
8376  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
8377  }
8378 
8379  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
8380  {
8381  char *begin = number_buffer.data();
8382  char *end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
8383 
8384  o->write_characters(begin, static_cast<size_t>(end - begin));
8385  }
8386 
8387  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
8388  {
8389  // get number of digits for a float -> text -> float round-trip
8390  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
8391 
8392  // the actual conversion
8393  std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
8394 
8395  // negative value indicates an error
8396  assert(len > 0);
8397  // check if buffer was large enough
8398  assert(static_cast<std::size_t>(len) < number_buffer.size());
8399 
8400  // erase thousands separator
8401  if (thousands_sep != '\0') {
8402  const auto end = std::remove(number_buffer.begin(),
8403  number_buffer.begin() + len, thousands_sep);
8404  std::fill(end, number_buffer.end(), '\0');
8405  assert((end - number_buffer.begin()) <= len);
8406  len = (end - number_buffer.begin());
8407  }
8408 
8409  // convert decimal point to '.'
8410  if (decimal_point != '\0' and decimal_point != '.') {
8411  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8412  if (dec_pos != number_buffer.end()) {
8413  *dec_pos = '.';
8414  }
8415  }
8416 
8417  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
8418 
8419  // determine if need to append ".0"
8420  const bool value_is_int_like =
8421  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8422  [](char c) {
8423  return (c == '.' or c == 'e');
8424  });
8425 
8426  if (value_is_int_like) {
8427  o->write_characters(".0", 2);
8428  }
8429  }
8430 
8452  static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept
8453  {
8454  static const std::array<uint8_t, 400> utf8d =
8455  {
8456  {
8457  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,
8458  0, // 00..1F
8459  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,
8460  0, // 20..3F
8461  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,
8462  0, // 40..5F
8463  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,
8464  0, // 60..7F
8465  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,
8466  9, // 80..9F
8467  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,
8468  7, // A0..BF
8469  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,
8470  2, // C0..DF
8471  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
8472  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
8473  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
8474  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,
8475  1, // s1..s2
8476  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,
8477  1, // s3..s4
8478  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,
8479  1, // s5..s6
8480  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
8481  }
8482  };
8483 
8484  const uint8_t type = utf8d[byte];
8485 
8486  codep = (state != UTF8_ACCEPT)
8487  ? (byte & 0x3fu) | (codep << 6)
8488  : static_cast<uint32_t>(0xff >> type) & (byte);
8489 
8490  state = utf8d[256u + state * 16u + type];
8491  return state;
8492  }
8493 
8494 private:
8496  output_adapter_t<char> o = nullptr;
8497 
8499  std::array<char, 64> number_buffer { {} };
8500 
8502  const std::lconv *loc = nullptr;
8504  const char thousands_sep = '\0';
8506  const char decimal_point = '\0';
8507 
8509  std::array<char, 512> string_buffer { {} };
8510 
8512  const char indent_char;
8514  string_t indent_string;
8515 };
8516 
8517 } // namespace detail
8518 } // namespace nlohmann
8519 
8520 // #include <nlohmann/detail/json_ref.hpp>
8521 
8522 
8523 #include <initializer_list>
8524 #include <utility>
8525 
8526 namespace nlohmann
8527 {
8528 namespace detail
8529 {
8530 template<typename BasicJsonType>
8531 
8533 {
8534 public:
8535  using value_type = BasicJsonType;
8536 
8537  json_ref(value_type &&value)
8538  : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
8539  {}
8540 
8541  json_ref(const value_type &value)
8542  : value_ref(const_cast<value_type *>(&value)), is_rvalue(false)
8543  {}
8544 
8545  json_ref(std::initializer_list<json_ref> init)
8546  : owned_value(init), value_ref(&owned_value), is_rvalue(true)
8547  {}
8548 
8549  template<class... Args>
8550  json_ref(Args && ... args)
8551  : owned_value(std::forward<Args>(args) ...), value_ref(&owned_value), is_rvalue(true)
8552  {}
8553 
8554  // class should be movable only
8555  json_ref(json_ref &&) = default;
8556  json_ref(const json_ref &) = delete;
8557  json_ref &operator=(const json_ref &) = delete;
8558 
8559  value_type moved_or_copied() const
8560  {
8561  if (is_rvalue) {
8562  return std::move(*value_ref);
8563  }
8564 
8565  return *value_ref;
8566  }
8567 
8568  value_type const &operator*() const
8569  {
8570  return *static_cast<value_type const *>(value_ref);
8571  }
8572 
8573  value_type const *operator->() const
8574  {
8575  return static_cast<value_type const *>(value_ref);
8576  }
8577 
8578 private:
8579  mutable value_type owned_value = nullptr;
8580  value_type *value_ref = nullptr;
8581  const bool is_rvalue;
8582 };
8583 
8584 } // namespace detail
8585 } // namespace nlohmann
8586 
8587 // #include <nlohmann/detail/json_pointer.hpp>
8588 
8589 
8590 #include <cassert> // assert
8591 #include <numeric> // accumulate
8592 #include <string> // string
8593 #include <vector> // vector
8594 
8595 // #include <nlohmann/detail/macro_scope.hpp>
8596 
8597 // #include <nlohmann/detail/exceptions.hpp>
8598 
8599 // #include <nlohmann/detail/value_t.hpp>
8600 
8601 
8602 namespace nlohmann
8603 {
8604 template<typename BasicJsonType>
8605 
8606 class json_pointer
8607 {
8608  // allow basic_json to access private members
8609  NLOHMANN_BASIC_JSON_TPL_DECLARATION
8610  friend class basic_json;
8611 
8612 public:
8634  explicit json_pointer(const std::string &s = "")
8635  : reference_tokens(split(s))
8636  {}
8637 
8653  std::string to_string() const noexcept
8654  {
8655  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8656  std::string {},
8657  [](const std::string &a, const std::string &b) {
8658  return a + "/" + escape(b);
8659  });
8660  }
8661 
8663  operator std::string() const
8664  {
8665  return to_string();
8666  }
8667 
8675  static int array_index(const std::string &s)
8676  {
8677  std::size_t processed_chars = 0;
8678  const int res = std::stoi(s, &processed_chars);
8679 
8680  // check if the string was completely read
8681  if (JSON_UNLIKELY(processed_chars != s.size())) {
8682  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
8683  }
8684 
8685  return res;
8686  }
8687 
8688 private:
8693  std::string pop_back()
8694  {
8695  if (JSON_UNLIKELY(is_root())) {
8696  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8697  }
8698 
8699  auto last = reference_tokens.back();
8700  reference_tokens.pop_back();
8701  return last;
8702  }
8703 
8705  bool is_root() const
8706  {
8707  return reference_tokens.empty();
8708  }
8709 
8710  json_pointer top() const
8711  {
8712  if (JSON_UNLIKELY(is_root())) {
8713  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8714  }
8715 
8716  json_pointer result = *this;
8717  result.reference_tokens = { reference_tokens[0] };
8718  return result;
8719  }
8720 
8729  BasicJsonType &get_and_create(BasicJsonType &j) const
8730  {
8731  using size_type = typename BasicJsonType::size_type;
8732  auto result = &j;
8733 
8734  // in case no reference tokens exist, return a reference to the JSON value
8735  // j which will be overwritten by a primitive value
8736  for (const auto &reference_token : reference_tokens) {
8737  switch (result->m_type) {
8738  case detail::value_t::null:
8739  {
8740  if (reference_token == "0") {
8741  // start a new array if reference token is 0
8742  result = &result->operator[](0);
8743  } else {
8744  // start a new object otherwise
8745  result = &result->operator[](reference_token);
8746  }
8747 
8748  break;
8749  }
8750 
8752  {
8753  // create an entry in the object
8754  result = &result->operator[](reference_token);
8755  break;
8756  }
8757 
8759  {
8760  // create an entry in the array
8761  JSON_TRY
8762  {
8763  result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
8764  }
8765  JSON_CATCH(std::invalid_argument &)
8766  {
8767  JSON_THROW(detail::parse_error::create(109, 0,
8768  "array index '" + reference_token +
8769  "' is not a number"));
8770  }
8771  break;
8772  }
8773 
8774  /*
8775  The following code is only reached if there exists a reference
8776  token _and_ the current value is primitive. In this case, we have
8777  an error situation, because primitive values may only occur as
8778  single value; that is, with an empty list of reference tokens.
8779  */default:
8780  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
8781  }
8782  }
8783 
8784  return *result;
8785  }
8786 
8806  BasicJsonType &get_unchecked(BasicJsonType *ptr) const
8807  {
8808  using size_type = typename BasicJsonType::size_type;
8809  for (const auto &reference_token : reference_tokens) {
8810  // convert null values to arrays or objects before continuing
8811  if (ptr->m_type == detail::value_t::null) {
8812  // check if reference token is a number
8813  const bool nums =
8814  std::all_of(reference_token.begin(), reference_token.end(),
8815  [](const char x) {
8816  return (x >= '0' and x <= '9');
8817  });
8818 
8819  // change value to array for numbers or "-" or to object otherwise
8820  *ptr = (nums or reference_token == "-")
8823  }
8824 
8825  switch (ptr->m_type) {
8827  {
8828  // use unchecked object access
8829  ptr = &ptr->operator[](reference_token);
8830  break;
8831  }
8832 
8834  {
8835  // error condition (cf. RFC 6901, Sect. 4)
8836  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8837  JSON_THROW(detail::parse_error::create(106, 0,
8838  "array index '" + reference_token +
8839  "' must not begin with '0'"));
8840  }
8841 
8842  if (reference_token == "-") {
8843  // explicitly treat "-" as index beyond the end
8844  ptr = &ptr->operator[](ptr->m_value.array->size());
8845  } else {
8846  // convert array index to number; unchecked access
8847  JSON_TRY
8848  {
8849  ptr = &ptr->operator[](
8850  static_cast<size_type>(array_index(reference_token)));
8851  }
8852  JSON_CATCH(std::invalid_argument &)
8853  {
8854  JSON_THROW(detail::parse_error::create(109, 0,
8855  "array index '" + reference_token +
8856  "' is not a number"));
8857  }
8858  }
8859 
8860  break;
8861  }
8862 
8863  default:
8864  JSON_THROW(detail::out_of_range::create(404,
8865  "unresolved reference token '" + reference_token +
8866  "'"));
8867  }
8868  }
8869 
8870  return *ptr;
8871  }
8872 
8879  BasicJsonType &get_checked(BasicJsonType *ptr) const
8880  {
8881  using size_type = typename BasicJsonType::size_type;
8882  for (const auto &reference_token : reference_tokens) {
8883  switch (ptr->m_type) {
8885  {
8886  // note: at performs range check
8887  ptr = &ptr->at(reference_token);
8888  break;
8889  }
8890 
8892  {
8893  if (JSON_UNLIKELY(reference_token == "-")) {
8894  // "-" always fails the range check
8895  JSON_THROW(detail::out_of_range::create(402,
8896  "array index '-' (" +
8897  std::to_string(ptr->m_value.array->size()) +
8898  ") is out of range"));
8899  }
8900 
8901  // error condition (cf. RFC 6901, Sect. 4)
8902  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8903  JSON_THROW(detail::parse_error::create(106, 0,
8904  "array index '" + reference_token +
8905  "' must not begin with '0'"));
8906  }
8907 
8908  // note: at performs range check
8909  JSON_TRY
8910  {
8911  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8912  }
8913  JSON_CATCH(std::invalid_argument &)
8914  {
8915  JSON_THROW(detail::parse_error::create(109, 0,
8916  "array index '" + reference_token +
8917  "' is not a number"));
8918  }
8919  break;
8920  }
8921 
8922  default:
8923  JSON_THROW(detail::out_of_range::create(404,
8924  "unresolved reference token '" + reference_token +
8925  "'"));
8926  }
8927  }
8928 
8929  return *ptr;
8930  }
8931 
8945  const BasicJsonType &get_unchecked(const BasicJsonType *ptr) const
8946  {
8947  using size_type = typename BasicJsonType::size_type;
8948  for (const auto &reference_token : reference_tokens) {
8949  switch (ptr->m_type) {
8951  {
8952  // use unchecked object access
8953  ptr = &ptr->operator[](reference_token);
8954  break;
8955  }
8956 
8958  {
8959  if (JSON_UNLIKELY(reference_token == "-")) {
8960  // "-" cannot be used for const access
8961  JSON_THROW(detail::out_of_range::create(402,
8962  "array index '-' (" +
8963  std::to_string(ptr->m_value.array->size()) +
8964  ") is out of range"));
8965  }
8966 
8967  // error condition (cf. RFC 6901, Sect. 4)
8968  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
8969  JSON_THROW(detail::parse_error::create(106, 0,
8970  "array index '" + reference_token +
8971  "' must not begin with '0'"));
8972  }
8973 
8974  // use unchecked array access
8975  JSON_TRY
8976  {
8977  ptr = &ptr->operator[](
8978  static_cast<size_type>(array_index(reference_token)));
8979  }
8980  JSON_CATCH(std::invalid_argument &)
8981  {
8982  JSON_THROW(detail::parse_error::create(109, 0,
8983  "array index '" + reference_token +
8984  "' is not a number"));
8985  }
8986  break;
8987  }
8988 
8989  default:
8990  JSON_THROW(detail::out_of_range::create(404,
8991  "unresolved reference token '" + reference_token +
8992  "'"));
8993  }
8994  }
8995 
8996  return *ptr;
8997  }
8998 
9005  const BasicJsonType &get_checked(const BasicJsonType *ptr) const
9006  {
9007  using size_type = typename BasicJsonType::size_type;
9008  for (const auto &reference_token : reference_tokens) {
9009  switch (ptr->m_type) {
9011  {
9012  // note: at performs range check
9013  ptr = &ptr->at(reference_token);
9014  break;
9015  }
9016 
9018  {
9019  if (JSON_UNLIKELY(reference_token == "-")) {
9020  // "-" always fails the range check
9021  JSON_THROW(detail::out_of_range::create(402,
9022  "array index '-' (" +
9023  std::to_string(ptr->m_value.array->size()) +
9024  ") is out of range"));
9025  }
9026 
9027  // error condition (cf. RFC 6901, Sect. 4)
9028  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) {
9029  JSON_THROW(detail::parse_error::create(106, 0,
9030  "array index '" + reference_token +
9031  "' must not begin with '0'"));
9032  }
9033 
9034  // note: at performs range check
9035  JSON_TRY
9036  {
9037  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9038  }
9039  JSON_CATCH(std::invalid_argument &)
9040  {
9041  JSON_THROW(detail::parse_error::create(109, 0,
9042  "array index '" + reference_token +
9043  "' is not a number"));
9044  }
9045  break;
9046  }
9047 
9048  default:
9049  JSON_THROW(detail::out_of_range::create(404,
9050  "unresolved reference token '" + reference_token +
9051  "'"));
9052  }
9053  }
9054 
9055  return *ptr;
9056  }
9057 
9067  static std::vector<std::string> split(const std::string &reference_string)
9068  {
9069  std::vector<std::string> result;
9070 
9071  // special case: empty reference string -> no reference tokens
9072  if (reference_string.empty()) {
9073  return result;
9074  }
9075 
9076  // check if nonempty reference string begins with slash
9077  if (JSON_UNLIKELY(reference_string[0] != '/')) {
9078  JSON_THROW(detail::parse_error::create(107, 1,
9079  "JSON pointer must be empty or begin with '/' - was: '" +
9080  reference_string + "'"));
9081  }
9082 
9083  // extract the reference tokens:
9084  // - slash: position of the last read slash (or end of string)
9085  // - start: position after the previous slash
9086  for (
9087  // search for the first slash after the first character
9088  std::size_t slash = reference_string.find_first_of('/', 1),
9089  // set the beginning of the first reference token
9090  start = 1;
9091  // we can stop if start == string::npos+1 = 0
9092  start != 0;
9093  // set the beginning of the next reference token
9094  // (will eventually be 0 if slash == std::string::npos)
9095  start = slash + 1,
9096  // find next slash
9097  slash = reference_string.find_first_of('/', start)) {
9098  // use the text between the beginning of the reference token
9099  // (start) and the last slash (slash).
9100  auto reference_token = reference_string.substr(start, slash - start);
9101 
9102  // check reference tokens are properly escaped
9103  for (std::size_t pos = reference_token.find_first_of('~');
9104  pos != std::string::npos;
9105  pos = reference_token.find_first_of('~', pos + 1)) {
9106  assert(reference_token[pos] == '~');
9107 
9108  // ~ must be followed by 0 or 1
9109  if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9110  (reference_token[pos + 1] != '0' and
9111  reference_token[pos + 1] != '1'))) {
9112  JSON_THROW(detail::parse_error::create(108, 0,
9113  "escape character '~' must be followed with '0' or '1'"));
9114  }
9115  }
9116 
9117  // finally, store the reference token
9118  unescape(reference_token);
9119  result.push_back(reference_token);
9120  }
9121 
9122  return result;
9123  }
9124 
9138  static void replace_substring(std::string &s, const std::string &f,
9139  const std::string &t)
9140  {
9141  assert(not f.empty());
9142  for (auto pos = s.find(f); // find first occurrence of f
9143  pos != std::string::npos; // make sure f was found
9144  s.replace(pos, f.size(), t), // replace with t, and
9145  pos = s.find(f, pos + t.size())) // find next occurrence of f
9146  {}
9147  }
9148 
9150  static std::string escape(std::string s)
9151  {
9152  replace_substring(s, "~", "~0");
9153  replace_substring(s, "/", "~1");
9154  return s;
9155  }
9156 
9158  static void unescape(std::string &s)
9159  {
9160  replace_substring(s, "~1", "/");
9161  replace_substring(s, "~0", "~");
9162  }
9163 
9171  static void flatten(const std::string &reference_string,
9172  const BasicJsonType &value,
9173  BasicJsonType &result)
9174  {
9175  switch (value.m_type) {
9177  {
9178  if (value.m_value.array->empty()) {
9179  // flatten empty array as null
9180  result[reference_string] = nullptr;
9181  } else {
9182  // iterate array and use index as reference string
9183  for (std::size_t i = 0; i < value.m_value.array->size(); ++i) {
9184  flatten(reference_string + "/" + std::to_string(i),
9185  value.m_value.array->operator[](i), result);
9186  }
9187  }
9188 
9189  break;
9190  }
9191 
9193  {
9194  if (value.m_value.object->empty()) {
9195  // flatten empty object as null
9196  result[reference_string] = nullptr;
9197  } else {
9198  // iterate object and use keys as reference string
9199  for (const auto &element : *value.m_value.object) {
9200  flatten(reference_string + "/" + escape(element.first), element.second, result);
9201  }
9202  }
9203 
9204  break;
9205  }
9206 
9207  default:
9208  {
9209  // add primitive value with its reference string
9210  result[reference_string] = value;
9211  break;
9212  }
9213  }
9214  }
9215 
9226  static BasicJsonType
9227  unflatten(const BasicJsonType &value)
9228  {
9229  if (JSON_UNLIKELY(not value.is_object())) {
9230  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
9231  }
9232 
9233  BasicJsonType result;
9234 
9235  // iterate the JSON object values
9236  for (const auto &element : *value.m_value.object) {
9237  if (JSON_UNLIKELY(not element.second.is_primitive())) {
9238  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
9239  }
9240 
9241  // assign value to reference pointed to by JSON pointer; Note that if
9242  // the JSON pointer is "" (i.e., points to the whole value), function
9243  // get_and_create returns a reference to result itself. An assignment
9244  // will then create a primitive value.
9245  json_pointer(element.first).get_and_create(result) = element.second;
9246  }
9247 
9248  return result;
9249  }
9250 
9251  friend bool operator==(json_pointer const &lhs,
9252  json_pointer const &rhs) noexcept
9253  {
9254  return (lhs.reference_tokens == rhs.reference_tokens);
9255  }
9256 
9257  friend bool operator!=(json_pointer const &lhs,
9258  json_pointer const &rhs) noexcept
9259  {
9260  return not (lhs == rhs);
9261  }
9262 
9264  std::vector<std::string> reference_tokens;
9265 };
9266 
9267 } // namespace nlohmann
9268 
9269 // #include <nlohmann/adl_serializer.hpp>
9270 
9271 
9272 #include <utility>
9273 
9274 // #include <nlohmann/detail/conversions/from_json.hpp>
9275 
9276 // #include <nlohmann/detail/conversions/to_json.hpp>
9277 
9278 
9279 namespace nlohmann
9280 {
9281 template<typename, typename>
9282 struct adl_serializer
9283 {
9293  template<typename BasicJsonType, typename ValueType>
9294  static void from_json(BasicJsonType &&j, ValueType &val) noexcept (
9295  noexcept (::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
9296  {
9297  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
9298  }
9299 
9309  template<typename BasicJsonType, typename ValueType>
9310  static void to_json(BasicJsonType &j, ValueType &&val) noexcept (
9311  noexcept (::nlohmann::to_json(j, std::forward<ValueType>(val))))
9312  {
9313  ::nlohmann::to_json(j, std::forward<ValueType>(val));
9314  }
9315 };
9316 
9317 } // namespace nlohmann
9318 
9319 
9325 namespace nlohmann
9326 {
9327 
9409 NLOHMANN_BASIC_JSON_TPL_DECLARATION
9410 
9411 class basic_json
9412 {
9413 private:
9414  template<detail::value_t> friend struct detail::external_constructor;
9415  friend ::nlohmann::json_pointer<basic_json>;
9416  friend ::nlohmann::detail::parser<basic_json>;
9417  friend ::nlohmann::detail::serializer<basic_json>;
9418  template<typename BasicJsonType>
9419  friend class ::nlohmann::detail::iter_impl;
9420  template<typename BasicJsonType, typename CharType>
9421  friend class ::nlohmann::detail::binary_writer;
9422  template<typename BasicJsonType>
9423  friend class ::nlohmann::detail::binary_reader;
9424 
9426  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
9427 
9428  // convenience aliases for types residing in namespace detail;
9431 
9432  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
9433  template<typename BasicJsonType>
9434  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
9435  template<typename BasicJsonType>
9437  template<typename Iterator>
9438  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
9439  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
9440 
9441  template<typename CharType>
9443 
9444  using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
9445  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
9446 
9447  using serializer = ::nlohmann::detail::serializer<basic_json>;
9448 
9449 public:
9450  using value_t = detail::value_t;
9453  template<typename T, typename SFINAE>
9454  using json_serializer = JSONSerializer<T, SFINAE>;
9456  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
9457 
9459  // exceptions //
9461 
9465 
9478 
9480 
9481 
9483  // container types //
9485 
9490 
9493 
9497  using const_reference = const value_type &;
9498 
9500  using difference_type = std::ptrdiff_t;
9502  using size_type = std::size_t;
9503 
9505  using allocator_type = AllocatorType<basic_json>;
9506 
9508  using pointer = typename std::allocator_traits<allocator_type>::pointer;
9510  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
9511 
9520 
9522 
9523 
9528  {
9529  return allocator_type();
9530  }
9531 
9558  static basic_json meta()
9559  {
9560  basic_json result;
9561 
9562  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
9563  result["name"] = "JSON for Modern C++";
9564  result["url"] = "https://github.com/nlohmann/json";
9565  result["version"]["string"] =
9566  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
9567  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
9568  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
9569  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
9570  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
9571  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
9572 
9573 #ifdef _WIN32
9574  result["platform"] = "win32";
9575 #elif defined __linux__
9576  result["platform"] = "linux";
9577 #elif defined __APPLE__
9578  result["platform"] = "apple";
9579 #elif defined __unix__
9580  result["platform"] = "unix";
9581 #else
9582  result["platform"] = "unknown";
9583 #endif
9584 
9585 #if defined(__ICC) || defined(__INTEL_COMPILER)
9586  result["compiler"] = { { "family", "icc" }, { "version", __INTEL_COMPILER } };
9587 #elif defined(__clang__)
9588  result["compiler"] = { { "family", "clang" }, { "version", __clang_version__ } };
9589 #elif defined(__GNUC__) || defined(__GNUG__)
9590  result["compiler"] =
9591  { { "family", "gcc" },
9592  { "version",
9593  std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(
9594  __GNUC_PATCHLEVEL__) } };
9595 #elif defined(__HP_cc) || defined(__HP_aCC)
9596  result["compiler"] = "hp"
9597 #elif defined(__IBMCPP__)
9598  result["compiler"] = { { "family", "ilecpp" }, { "version", __IBMCPP__ } };
9599 #elif defined(_MSC_VER)
9600  result["compiler"] = { { "family", "msvc" }, { "version", _MSC_VER } };
9601 #elif defined(__PGI)
9602  result["compiler"] = { { "family", "pgcpp" }, { "version", __PGI } };
9603 #elif defined(__SUNPRO_CC)
9604  result["compiler"] = { { "family", "sunpro" }, { "version", __SUNPRO_CC } };
9605 #else
9606  result["compiler"] = { { "family", "unknown" }, { "version", "unknown" } };
9607 #endif
9608 
9609 #ifdef __cplusplus
9610  result["compiler"]["c++"] = std::to_string(__cplusplus);
9611 #else
9612  result["compiler"]["c++"] = "unknown";
9613 #endif
9614  return result;
9615  }
9616 
9617 
9619  // JSON value data types //
9621 
9626 
9627 #if defined(JSON_HAS_CPP_14)
9628  // Use transparent comparator if possible, combined with perfect forwarding
9629  // on find() and count() calls prevents unnecessary string construction.
9630  using object_comparator_t = std::less<>;
9631 #else
9632  using object_comparator_t = std::less<StringType>;
9633 #endif
9634 
9718  using object_t = ObjectType<StringType,
9719  basic_json,
9720  object_comparator_t,
9721  AllocatorType<std::pair<const StringType,
9722  basic_json>>>;
9723 
9768  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
9769 
9821  using string_t = StringType;
9822 
9847  using boolean_t = BooleanType;
9848 
9919  using number_integer_t = NumberIntegerType;
9920 
9990  using number_unsigned_t = NumberUnsignedType;
9991 
10058  using number_float_t = NumberFloatType;
10059 
10061 
10062 private:
10063 
10065  template<typename T, typename... Args>
10066  static T *create(Args && ... args)
10067  {
10068  AllocatorType<T> alloc;
10069  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
10070 
10071  auto deleter = [&](T *object) {
10072  AllocatorTraits::deallocate(alloc, object, 1);
10073  };
10074  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
10075  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args) ...);
10076  assert(object != nullptr);
10077  return object.release();
10078  }
10079 
10081  // JSON value storage //
10083 
10108  union json_value
10109  {
10111  object_t *object;
10113  array_t *array;
10115  string_t *string;
10124 
10126  json_value() = default;
10128  json_value(boolean_t v) noexcept : boolean(v) {}
10130  json_value(number_integer_t v) noexcept : number_integer(v) {}
10132  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
10134  json_value(number_float_t v) noexcept : number_float(v) {}
10136  json_value(value_t t)
10137  {
10138  switch (t) {
10139  case value_t::object:
10140  {
10141  object = create<object_t>();
10142  break;
10143  }
10144 
10145  case value_t::array:
10146  {
10147  array = create<array_t>();
10148  break;
10149  }
10150 
10151  case value_t::string:
10152  {
10153  string = create<string_t>("");
10154  break;
10155  }
10156 
10157  case value_t::boolean:
10158  {
10159  boolean = boolean_t(false);
10160  break;
10161  }
10162 
10164  {
10165  number_integer = number_integer_t(0);
10166  break;
10167  }
10168 
10170  {
10171  number_unsigned = number_unsigned_t(0);
10172  break;
10173  }
10174 
10175  case value_t::number_float:
10176  {
10177  number_float = number_float_t(0.0);
10178  break;
10179  }
10180 
10181  case value_t::null:
10182  {
10183  object = nullptr; // silence warning, see #821
10184  break;
10185  }
10186 
10187  default:
10188  {
10189  object = nullptr; // silence warning, see #821
10190  if (JSON_UNLIKELY(t == value_t::null)) {
10191  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.1")); // LCOV_EXCL_LINE
10192  }
10193 
10194  break;
10195  }
10196  }
10197  }
10198 
10200  json_value(const string_t &value)
10201  {
10202  string = create<string_t>(value);
10203  }
10204 
10206  json_value(string_t && value)
10207  {
10208  string = create<string_t>(std::move(value));
10209  }
10210 
10212  json_value(const object_t &value)
10213  {
10214  object = create<object_t>(value);
10215  }
10216 
10218  json_value(object_t && value)
10219  {
10220  object = create<object_t>(std::move(value));
10221  }
10222 
10224  json_value(const array_t &value)
10225  {
10226  array = create<array_t>(value);
10227  }
10228 
10230  json_value(array_t && value)
10231  {
10232  array = create<array_t>(std::move(value));
10233  }
10234 
10235  void destroy(value_t t) noexcept
10236  {
10237  switch (t) {
10238  case value_t::object:
10239  {
10240  AllocatorType<object_t> alloc;
10241  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
10242  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
10243  break;
10244  }
10245 
10246  case value_t::array:
10247  {
10248  AllocatorType<array_t> alloc;
10249  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
10250  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
10251  break;
10252  }
10253 
10254  case value_t::string:
10255  {
10256  AllocatorType<string_t> alloc;
10257  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
10258  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
10259  break;
10260  }
10261 
10262  default:
10263  {
10264  break;
10265  }
10266  }
10267  }
10268  };
10269 
10279  void assert_invariant() const noexcept
10280  {
10281  assert(m_type != value_t::object or m_value.object != nullptr);
10282  assert(m_type != value_t::array or m_value.array != nullptr);
10283  assert(m_type != value_t::string or m_value.string != nullptr);
10284  }
10285 
10286 public:
10288  // JSON parser callback //
10290 
10307 
10357  using parser_callback_t = typename parser::parser_callback_t;
10358 
10359 
10361  // constructors //
10363 
10368 
10399  : m_type(v), m_value(v)
10400  {
10401  assert_invariant();
10402  }
10403 
10422  basic_json(std::nullptr_t = nullptr) noexcept
10423  : basic_json(value_t::null)
10424  {
10425  assert_invariant();
10426  }
10427 
10484  template<typename CompatibleType,
10485  typename U = detail::uncvref_t<CompatibleType>,
10486  detail::enable_if_t<
10488  basic_json(CompatibleType &&val) noexcept (noexcept (
10489  JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
10490  std::forward<CompatibleType>(val))))
10491  {
10492  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
10493  assert_invariant();
10494  }
10495 
10571  bool type_deduction = true,
10572  value_t manual_type = value_t::array)
10573  {
10574  // check if each element is an array with two elements whose first
10575  // element is a string
10576  bool is_an_object = std::all_of(init.begin(), init.end(),
10577  [](const detail::json_ref<basic_json> &element_ref) {
10578  return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
10579  });
10580 
10581  // adjust type if type deduction is not wanted
10582  if (not type_deduction) {
10583  // if array is wanted, do not create an object though possible
10584  if (manual_type == value_t::array) {
10585  is_an_object = false;
10586  }
10587 
10588  // if object is wanted but impossible, throw an exception
10589  if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object)) {
10590  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
10591  }
10592  }
10593 
10594  if (is_an_object) {
10595  // the initializer list is a list of pairs -> create object
10596  m_type = value_t::object;
10597  m_value = value_t::object;
10598 
10599  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json> &element_ref) {
10600  auto element = element_ref.moved_or_copied();
10601  m_value.object->emplace(
10602  std::move(*((*element.m_value.array)[0].m_value.string)),
10603  std::move((*element.m_value.array)[1]));
10604  });
10605  } else {
10606  // the initializer list describes an array -> create array
10607  m_type = value_t::array;
10608  m_value.array = create<array_t>(init.begin(), init.end());
10609  }
10610 
10611  assert_invariant();
10612  }
10613 
10651  static basic_json array(initializer_list_t init = {})
10652  {
10653  return basic_json(init, false, value_t::array);
10654  }
10655 
10694  static basic_json object(initializer_list_t init = {})
10695  {
10696  return basic_json(init, false, value_t::object);
10697  }
10698 
10721  basic_json(size_type cnt, const basic_json &val)
10722  : m_type(value_t::array)
10723  {
10724  m_value.array = create<array_t>(cnt, val);
10725  assert_invariant();
10726  }
10727 
10783  template<class InputIT, typename std::enable_if<
10784  std::is_same<InputIT, typename basic_json_t::iterator>::value or
10785  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
10786  basic_json(InputIT first, InputIT last)
10787  {
10788  assert(first.m_object != nullptr);
10789  assert(last.m_object != nullptr);
10790 
10791  // make sure iterator fits the current value
10792  if (JSON_UNLIKELY(first.m_object != last.m_object)) {
10793  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
10794  }
10795 
10796  // copy type from first iterator
10797  m_type = first.m_object->m_type;
10798 
10799  // check if iterator range is complete for primitive values
10800  switch (m_type) {
10801  case value_t::boolean:
10802  case value_t::number_float:
10805  case value_t::string:
10806  {
10807  if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
10808  or not last.m_it.primitive_iterator.is_end())) {
10809  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
10810  }
10811 
10812  break;
10813  }
10814 
10815  default:
10816  break;
10817  }
10818 
10819  switch (m_type) {
10821  {
10822  m_value.number_integer = first.m_object->m_value.number_integer;
10823  break;
10824  }
10825 
10827  {
10828  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
10829  break;
10830  }
10831 
10832  case value_t::number_float:
10833  {
10834  m_value.number_float = first.m_object->m_value.number_float;
10835  break;
10836  }
10837 
10838  case value_t::boolean:
10839  {
10840  m_value.boolean = first.m_object->m_value.boolean;
10841  break;
10842  }
10843 
10844  case value_t::string:
10845  {
10846  m_value = *first.m_object->m_value.string;
10847  break;
10848  }
10849 
10850  case value_t::object:
10851  {
10852  m_value.object = create<object_t>(first.m_it.object_iterator,
10853  last.m_it.object_iterator);
10854  break;
10855  }
10856 
10857  case value_t::array:
10858  {
10859  m_value.array = create<array_t>(first.m_it.array_iterator,
10860  last.m_it.array_iterator);
10861  break;
10862  }
10863 
10864  default:
10865  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
10866  std::string(first.m_object->type_name())));
10867  }
10868 
10869  assert_invariant();
10870  }
10871 
10872 
10874  // other constructors and destructor //
10876 
10878  basic_json(const detail::json_ref<basic_json> &ref)
10879  : basic_json(ref.moved_or_copied())
10880  {}
10881 
10907  basic_json(const basic_json &other)
10908  : m_type(other.m_type)
10909  {
10910  // check of passed value is valid
10911  other.assert_invariant();
10912 
10913  switch (m_type) {
10914  case value_t::object:
10915  {
10916  m_value = *other.m_value.object;
10917  break;
10918  }
10919 
10920  case value_t::array:
10921  {
10922  m_value = *other.m_value.array;
10923  break;
10924  }
10925 
10926  case value_t::string:
10927  {
10928  m_value = *other.m_value.string;
10929  break;
10930  }
10931 
10932  case value_t::boolean:
10933  {
10934  m_value = other.m_value.boolean;
10935  break;
10936  }
10937 
10939  {
10940  m_value = other.m_value.number_integer;
10941  break;
10942  }
10943 
10945  {
10946  m_value = other.m_value.number_unsigned;
10947  break;
10948  }
10949 
10950  case value_t::number_float:
10951  {
10952  m_value = other.m_value.number_float;
10953  break;
10954  }
10955 
10956  default:
10957  break;
10958  }
10959 
10960  assert_invariant();
10961  }
10962 
10989  basic_json(basic_json &&other) noexcept
10990  : m_type(std::move(other.m_type)), m_value(std::move(other.m_value))
10991  {
10992  // check that passed value is valid
10993  other.assert_invariant();
10994 
10995  // invalidate payload
10996  other.m_type = value_t::null;
10997  other.m_value = {};
10998 
10999  assert_invariant();
11000  }
11001 
11025  reference &operator=(basic_json other) noexcept (
11026  std::is_nothrow_move_constructible<value_t>::value and
11027  std::is_nothrow_move_assignable<value_t>::value and
11028  std::is_nothrow_move_constructible<json_value>::value and
11029  std::is_nothrow_move_assignable<json_value>::value
11030  )
11031  {
11032  // check that passed value is valid
11033  other.assert_invariant();
11034 
11035  using std::swap;
11036  swap(m_type, other.m_type);
11037  swap(m_value, other.m_value);
11038 
11039  assert_invariant();
11040  return *this;
11041  }
11042 
11058  ~basic_json() noexcept
11059  {
11060  assert_invariant();
11061  m_value.destroy(m_type);
11062  }
11063 
11065 
11066 public:
11068  // object inspection //
11070 
11074 
11111  string_t dump(const int indent = -1, const char indent_char = ' ',
11112  const bool ensure_ascii = false) const
11113  {
11114  string_t result;
11115  serializer s(detail::output_adapter<char>(result), indent_char);
11116 
11117  if (indent >= 0) {
11118  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
11119  } else {
11120  s.dump(*this, false, ensure_ascii, 0);
11121  }
11122 
11123  return result;
11124  }
11125 
11158  constexpr value_t type() const noexcept
11159  {
11160  return m_type;
11161  }
11162 
11188  constexpr bool is_primitive() const noexcept
11189  {
11190  return is_null() or is_string() or is_boolean() or is_number();
11191  }
11192 
11215  constexpr bool is_structured() const noexcept
11216  {
11217  return is_array() or is_object();
11218  }
11219 
11237  constexpr bool is_null() const noexcept
11238  {
11239  return (m_type == value_t::null);
11240  }
11241 
11259  constexpr bool is_boolean() const noexcept
11260  {
11261  return (m_type == value_t::boolean);
11262  }
11263 
11289  constexpr bool is_number() const noexcept
11290  {
11291  return is_number_integer() or is_number_float();
11292  }
11293 
11318  constexpr bool is_number_integer() const noexcept
11319  {
11320  return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
11321  }
11322 
11346  constexpr bool is_number_unsigned() const noexcept
11347  {
11348  return (m_type == value_t::number_unsigned);
11349  }
11350 
11374  constexpr bool is_number_float() const noexcept
11375  {
11376  return (m_type == value_t::number_float);
11377  }
11378 
11396  constexpr bool is_object() const noexcept
11397  {
11398  return (m_type == value_t::object);
11399  }
11400 
11418  constexpr bool is_array() const noexcept
11419  {
11420  return (m_type == value_t::array);
11421  }
11422 
11440  constexpr bool is_string() const noexcept
11441  {
11442  return (m_type == value_t::string);
11443  }
11444 
11467  constexpr bool is_discarded() const noexcept
11468  {
11469  return (m_type == value_t::discarded);
11470  }
11471 
11493  constexpr operator value_t() const noexcept
11494  {
11495  return m_type;
11496  }
11497 
11499 
11500 private:
11502  // value access //
11504 
11506  boolean_t get_impl(boolean_t * /*unused*/) const
11507  {
11508  if (JSON_LIKELY(is_boolean())) {
11509  return m_value.boolean;
11510  }
11511 
11512  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
11513  }
11514 
11516  object_t *get_impl_ptr(object_t * /*unused*/) noexcept
11517  {
11518  return is_object() ? m_value.object : nullptr;
11519  }
11520 
11522  constexpr const object_t *get_impl_ptr(const object_t * /*unused*/) const noexcept
11523  {
11524  return is_object() ? m_value.object : nullptr;
11525  }
11526 
11528  array_t *get_impl_ptr(array_t * /*unused*/) noexcept
11529  {
11530  return is_array() ? m_value.array : nullptr;
11531  }
11532 
11534  constexpr const array_t *get_impl_ptr(const array_t * /*unused*/) const noexcept
11535  {
11536  return is_array() ? m_value.array : nullptr;
11537  }
11538 
11540  string_t *get_impl_ptr(string_t * /*unused*/) noexcept
11541  {
11542  return is_string() ? m_value.string : nullptr;
11543  }
11544 
11546  constexpr const string_t *get_impl_ptr(const string_t * /*unused*/) const noexcept
11547  {
11548  return is_string() ? m_value.string : nullptr;
11549  }
11550 
11552  boolean_t *get_impl_ptr(boolean_t * /*unused*/) noexcept
11553  {
11554  return is_boolean() ? &m_value.boolean : nullptr;
11555  }
11556 
11558  constexpr const boolean_t *get_impl_ptr(const boolean_t * /*unused*/) const noexcept
11559  {
11560  return is_boolean() ? &m_value.boolean : nullptr;
11561  }
11562 
11564  number_integer_t *get_impl_ptr(number_integer_t * /*unused*/) noexcept
11565  {
11566  return is_number_integer() ? &m_value.number_integer : nullptr;
11567  }
11568 
11570  constexpr const number_integer_t *get_impl_ptr(const number_integer_t * /*unused*/) const noexcept
11571  {
11572  return is_number_integer() ? &m_value.number_integer : nullptr;
11573  }
11574 
11576  number_unsigned_t *get_impl_ptr(number_unsigned_t * /*unused*/) noexcept
11577  {
11578  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
11579  }
11580 
11582  constexpr const number_unsigned_t *get_impl_ptr(const number_unsigned_t * /*unused*/) const noexcept
11583  {
11584  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
11585  }
11586 
11588  number_float_t *get_impl_ptr(number_float_t * /*unused*/) noexcept
11589  {
11590  return is_number_float() ? &m_value.number_float : nullptr;
11591  }
11592 
11594  constexpr const number_float_t *get_impl_ptr(const number_float_t * /*unused*/) const noexcept
11595  {
11596  return is_number_float() ? &m_value.number_float : nullptr;
11597  }
11598 
11610  template<typename ReferenceType, typename ThisType>
11611  static ReferenceType get_ref_impl(ThisType &obj)
11612  {
11613  // delegate the call to get_ptr<>()
11614  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
11615 
11616  if (JSON_LIKELY(ptr != nullptr)) {
11617  return *ptr;
11618  }
11619 
11620  JSON_THROW(type_error::create(303,
11621  "incompatible ReferenceType for get_ref, actual type is " +
11622  std::string(obj.type_name())));
11623  }
11624 
11625 public:
11629 
11644  template<typename BasicJsonType, detail::enable_if_t<
11645  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
11646  int> = 0>
11647  basic_json get() const
11648  {
11649  return *this;
11650  }
11651 
11691  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
11692  detail::enable_if_t<
11693  not std::is_same<basic_json_t, ValueType>::value and
11694  detail::has_from_json<basic_json_t, ValueType>::value and
11695  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11696  int> = 0>
11697  ValueType get() const noexcept (noexcept (
11698  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(),
11699  std::declval<ValueType &>())))
11700  {
11701  // we cannot static_assert on ValueTypeCV being non-const, because
11702  // there is support for get<const basic_json_t>(), which is why we
11703  // still need the uncvref
11704  static_assert(not std::is_reference<ValueTypeCV>::value,
11705  "get() cannot be used with reference types, you might want to use get_ref()");
11706  static_assert(std::is_default_constructible<ValueType>::value,
11707  "types must be DefaultConstructible when used with get()");
11708 
11709  ValueType ret;
11710  JSONSerializer<ValueType>::from_json(*this, ret);
11711  return ret;
11712  }
11713 
11745  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
11746  detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
11747  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
11748  int> = 0>
11749  ValueType get() const noexcept (noexcept (
11750  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t &>())))
11751  {
11752  static_assert(not std::is_reference<ValueTypeCV>::value,
11753  "get() cannot be used with reference types, you might want to use get_ref()");
11754  return JSONSerializer<ValueTypeCV>::from_json(*this);
11755  }
11756 
11784  template<typename PointerType, typename std::enable_if<
11785  std::is_pointer<PointerType>::value, int>::type = 0>
11786  PointerType get() noexcept
11787  {
11788  // delegate the call to get_ptr
11789  return get_ptr<PointerType>();
11790  }
11791 
11796  template<typename PointerType, typename std::enable_if<
11797  std::is_pointer<PointerType>::value, int>::type = 0>
11798  constexpr const PointerType get() const noexcept
11799  {
11800  // delegate the call to get_ptr
11801  return get_ptr<PointerType>();
11802  }
11803 
11830  template<typename PointerType, typename std::enable_if<
11831  std::is_pointer<PointerType>::value, int>::type = 0>
11832  PointerType get_ptr() noexcept
11833  {
11834  // get the type of the PointerType (remove pointer and const)
11835  using pointee_t = typename std::remove_const<typename
11836  std::remove_pointer<typename
11837  std::remove_const<PointerType>::type>::type>
11838  ::type;
11839  // make sure the type matches the allowed types
11840  static_assert(
11841  std::is_same<object_t, pointee_t>::value
11842  or std::is_same<array_t, pointee_t>::value
11843  or std::is_same<string_t, pointee_t>::value
11844  or std::is_same<boolean_t, pointee_t>::value
11845  or std::is_same<number_integer_t, pointee_t>::value
11846  or std::is_same<number_unsigned_t, pointee_t>::value
11847  or std::is_same<number_float_t, pointee_t>::value
11848  , "incompatible pointer type");
11849 
11850  // delegate the call to get_impl_ptr<>()
11851  return get_impl_ptr(static_cast<PointerType>(nullptr));
11852  }
11853 
11858  template<typename PointerType, typename std::enable_if<
11859  std::is_pointer<PointerType>::value and
11860  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
11861  constexpr const PointerType get_ptr() const noexcept
11862  {
11863  // get the type of the PointerType (remove pointer and const)
11864  using pointee_t = typename std::remove_const<typename
11865  std::remove_pointer<typename
11866  std::remove_const<PointerType>::type>::type>
11867  ::type;
11868  // make sure the type matches the allowed types
11869  static_assert(
11870  std::is_same<object_t, pointee_t>::value
11871  or std::is_same<array_t, pointee_t>::value
11872  or std::is_same<string_t, pointee_t>::value
11873  or std::is_same<boolean_t, pointee_t>::value
11874  or std::is_same<number_integer_t, pointee_t>::value
11875  or std::is_same<number_unsigned_t, pointee_t>::value
11876  or std::is_same<number_float_t, pointee_t>::value
11877  , "incompatible pointer type");
11878 
11879  // delegate the call to get_impl_ptr<>() const
11880  return get_impl_ptr(static_cast<PointerType>(nullptr));
11881  }
11882 
11909  template<typename ReferenceType, typename std::enable_if<
11910  std::is_reference<ReferenceType>::value, int>::type = 0>
11911  ReferenceType get_ref()
11912  {
11913  // delegate call to get_ref_impl
11914  return get_ref_impl<ReferenceType>(*this);
11915  }
11916 
11921  template<typename ReferenceType, typename std::enable_if<
11922  std::is_reference<ReferenceType>::value and
11923  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
11924  ReferenceType get_ref() const
11925  {
11926  // delegate call to get_ref_impl
11927  return get_ref_impl<ReferenceType>(*this);
11928  }
11929 
11959  template<typename ValueType, typename std::enable_if<
11960  not std::is_pointer<ValueType>::value and
11961  not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
11962  not std::is_same<ValueType, typename string_t::value_type>::value
11963 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
11964  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
11965 #endif
11966 #if defined(JSON_HAS_CPP_17)
11967  and not std::is_same<ValueType, typename std::string_view>::value
11968 #endif
11969  , int>::type = 0>
11970  operator ValueType() const
11971  {
11972  // delegate the call to get<>() const
11973  return get<ValueType>();
11974  }
11975 
11977 
11978 
11980  // element access //
11982 
11986 
12014  {
12015  // at only works for arrays
12016  if (JSON_LIKELY(is_array())) {
12017  JSON_TRY
12018  {
12019  return m_value.array->at(idx);
12020  }
12021  JSON_CATCH(std::out_of_range &)
12022  {
12023  // create better exception explanation
12024  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(
12025  idx) + " is out of range"));
12026  }
12027  } else {
12028  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12029  }
12030  }
12031 
12059  {
12060  // at only works for arrays
12061  if (JSON_LIKELY(is_array())) {
12062  JSON_TRY
12063  {
12064  return m_value.array->at(idx);
12065  }
12066  JSON_CATCH(std::out_of_range &)
12067  {
12068  // create better exception explanation
12069  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(
12070  idx) + " is out of range"));
12071  }
12072  } else {
12073  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12074  }
12075  }
12076 
12107  reference at(const typename object_t::key_type &key)
12108  {
12109  // at only works for objects
12110  if (JSON_LIKELY(is_object())) {
12111  JSON_TRY
12112  {
12113  return m_value.object->at(key);
12114  }
12115  JSON_CATCH(std::out_of_range &)
12116  {
12117  // create better exception explanation
12118  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
12119  }
12120  } else {
12121  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12122  }
12123  }
12124 
12155  const_reference at(const typename object_t::key_type &key) const
12156  {
12157  // at only works for objects
12158  if (JSON_LIKELY(is_object())) {
12159  JSON_TRY
12160  {
12161  return m_value.object->at(key);
12162  }
12163  JSON_CATCH(std::out_of_range &)
12164  {
12165  // create better exception explanation
12166  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
12167  }
12168  } else {
12169  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12170  }
12171  }
12172 
12199  {
12200  // implicitly convert null value to an empty array
12201  if (is_null()) {
12202  m_type = value_t::array;
12203  m_value.array = create<array_t>();
12204  assert_invariant();
12205  }
12206 
12207  // operator[] only works for arrays
12208  if (JSON_LIKELY(is_array())) {
12209  // fill up array with null values if given idx is outside range
12210  if (idx >= m_value.array->size()) {
12211  m_value.array->insert(m_value.array->end(),
12212  idx - m_value.array->size() + 1,
12213  basic_json());
12214  }
12215 
12216  return m_value.array->operator[](idx);
12217  }
12218 
12219  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12220  }
12221 
12242  {
12243  // const operator[] only works for arrays
12244  if (JSON_LIKELY(is_array())) {
12245  return m_value.array->operator[](idx);
12246  }
12247 
12248  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12249  }
12250 
12278  reference operator[](const typename object_t::key_type &key)
12279  {
12280  // implicitly convert null value to an empty object
12281  if (is_null()) {
12282  m_type = value_t::object;
12283  m_value.object = create<object_t>();
12284  assert_invariant();
12285  }
12286 
12287  // operator[] only works for objects
12288  if (JSON_LIKELY(is_object())) {
12289  return m_value.object->operator[](key);
12290  }
12291 
12292  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12293  }
12294 
12325  const_reference operator[](const typename object_t::key_type &key) const
12326  {
12327  // const operator[] only works for objects
12328  if (JSON_LIKELY(is_object())) {
12329  assert(m_value.object->find(key) != m_value.object->end());
12330  return m_value.object->find(key)->second;
12331  }
12332 
12333  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12334  }
12335 
12363  template<typename T>
12365  {
12366  // implicitly convert null to object
12367  if (is_null()) {
12368  m_type = value_t::object;
12369  m_value = value_t::object;
12370  assert_invariant();
12371  }
12372 
12373  // at only works for objects
12374  if (JSON_LIKELY(is_object())) {
12375  return m_value.object->operator[](key);
12376  }
12377 
12378  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12379  }
12380 
12411  template<typename T>
12413  {
12414  // at only works for objects
12415  if (JSON_LIKELY(is_object())) {
12416  assert(m_value.object->find(key) != m_value.object->end());
12417  return m_value.object->find(key)->second;
12418  }
12419 
12420  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12421  }
12422 
12471  template<class ValueType, typename std::enable_if<
12472  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
12473  ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
12474  {
12475  // at only works for objects
12476  if (JSON_LIKELY(is_object())) {
12477  // if key is found, return value and given default value otherwise
12478  const auto it = find(key);
12479  if (it != end()) {
12480  return *it;
12481  }
12482 
12483  return default_value;
12484  }
12485 
12486  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
12487  }
12488 
12493  string_t value(const typename object_t::key_type &key, const char *default_value) const
12494  {
12495  return value(key, string_t(default_value));
12496  }
12497 
12539  template<class ValueType, typename std::enable_if<
12540  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
12541  ValueType value(const json_pointer &ptr, const ValueType &default_value) const
12542  {
12543  // at only works for objects
12544  if (JSON_LIKELY(is_object())) {
12545  // if pointer resolves a value, return it or use default value
12546  JSON_TRY
12547  {
12548  return ptr.get_checked(this);
12549  }
12550  JSON_CATCH(out_of_range &)
12551  {
12552  return default_value;
12553  }
12554  }
12555 
12556  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
12557  }
12558 
12563  string_t value(const json_pointer &ptr, const char *default_value) const
12564  {
12565  return value(ptr, string_t(default_value));
12566  }
12567 
12594  {
12595  return *begin();
12596  }
12597 
12602  {
12603  return *cbegin();
12604  }
12605 
12638  {
12639  auto tmp = end();
12640  --tmp;
12641  return *tmp;
12642  }
12643 
12648  {
12649  auto tmp = cend();
12650  --tmp;
12651  return *tmp;
12652  }
12653 
12700  template<class IteratorType, typename std::enable_if<
12701  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12702  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
12703  = 0>
12704  IteratorType erase(IteratorType pos)
12705  {
12706  // make sure iterator fits the current value
12707  if (JSON_UNLIKELY(this != pos.m_object)) {
12708  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
12709  }
12710 
12711  IteratorType result = end();
12712 
12713  switch (m_type) {
12714  case value_t::boolean:
12715  case value_t::number_float:
12718  case value_t::string:
12719  {
12720  if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin())) {
12721  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
12722  }
12723 
12724  if (is_string()) {
12725  AllocatorType<string_t> alloc;
12726  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12727  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12728  m_value.string = nullptr;
12729  }
12730 
12731  m_type = value_t::null;
12732  assert_invariant();
12733  break;
12734  }
12735 
12736  case value_t::object:
12737  {
12738  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
12739  break;
12740  }
12741 
12742  case value_t::array:
12743  {
12744  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
12745  break;
12746  }
12747 
12748  default:
12749  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12750  }
12751 
12752  return result;
12753  }
12754 
12801  template<class IteratorType, typename std::enable_if<
12802  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
12803  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
12804  = 0>
12805  IteratorType erase(IteratorType first, IteratorType last)
12806  {
12807  // make sure iterator fits the current value
12808  if (JSON_UNLIKELY(this != first.m_object or this != last.m_object)) {
12809  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
12810  }
12811 
12812  IteratorType result = end();
12813 
12814  switch (m_type) {
12815  case value_t::boolean:
12816  case value_t::number_float:
12819  case value_t::string:
12820  {
12821  if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
12822  or not last.m_it.primitive_iterator.is_end())) {
12823  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
12824  }
12825 
12826  if (is_string()) {
12827  AllocatorType<string_t> alloc;
12828  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
12829  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
12830  m_value.string = nullptr;
12831  }
12832 
12833  m_type = value_t::null;
12834  assert_invariant();
12835  break;
12836  }
12837 
12838  case value_t::object:
12839  {
12840  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
12841  last.m_it.object_iterator);
12842  break;
12843  }
12844 
12845  case value_t::array:
12846  {
12847  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
12848  last.m_it.array_iterator);
12849  break;
12850  }
12851 
12852  default:
12853  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12854  }
12855 
12856  return result;
12857  }
12858 
12888  size_type erase(const typename object_t::key_type &key)
12889  {
12890  // this erase only works for objects
12891  if (JSON_LIKELY(is_object())) {
12892  return m_value.object->erase(key);
12893  }
12894 
12895  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12896  }
12897 
12922  void erase(const size_type idx)
12923  {
12924  // this erase only works for arrays
12925  if (JSON_LIKELY(is_array())) {
12926  if (JSON_UNLIKELY(idx >= size())) {
12927  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(
12928  idx) + " is out of range"));
12929  }
12930 
12931  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
12932  } else {
12933  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
12934  }
12935  }
12936 
12938 
12939 
12941  // lookup //
12943 
12946 
12969  template<typename KeyT>
12970  iterator find(KeyT &&key)
12971  {
12972  auto result = end();
12973 
12974  if (is_object()) {
12975  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
12976  }
12977 
12978  return result;
12979  }
12980 
12985  template<typename KeyT>
12986  const_iterator find(KeyT &&key) const
12987  {
12988  auto result = cend();
12989 
12990  if (is_object()) {
12991  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
12992  }
12993 
12994  return result;
12995  }
12996 
13018  template<typename KeyT>
13019  size_type count(KeyT &&key) const
13020  {
13021  // return 0 for all nonobject types
13022  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13023  }
13024 
13026 
13027 
13029  // iterators //
13031 
13034 
13059  iterator begin() noexcept
13060  {
13061  iterator result(this);
13062  result.set_begin();
13063  return result;
13064  }
13065 
13069  const_iterator begin() const noexcept
13070  {
13071  return cbegin();
13072  }
13073 
13099  const_iterator cbegin() const noexcept
13100  {
13101  const_iterator result(this);
13102  result.set_begin();
13103  return result;
13104  }
13105 
13130  iterator end() noexcept
13131  {
13132  iterator result(this);
13133  result.set_end();
13134  return result;
13135  }
13136 
13140  const_iterator end() const noexcept
13141  {
13142  return cend();
13143  }
13144 
13170  const_iterator cend() const noexcept
13171  {
13172  const_iterator result(this);
13173  result.set_end();
13174  return result;
13175  }
13176 
13201  {
13202  return reverse_iterator(end());
13203  }
13204 
13209  {
13210  return crbegin();
13211  }
13212 
13238  {
13239  return reverse_iterator(begin());
13240  }
13241 
13245  const_reverse_iterator rend() const noexcept
13246  {
13247  return crend();
13248  }
13249 
13275  {
13276  return const_reverse_iterator(cend());
13277  }
13278 
13304  {
13305  return const_reverse_iterator(cbegin());
13306  }
13307 
13308 public:
13366  JSON_DEPRECATED
13368  {
13369  return ref.items();
13370  }
13371 
13375  JSON_DEPRECATED
13377  {
13378  return ref.items();
13379  }
13380 
13434  {
13435  return iteration_proxy<iterator>(*this);
13436  }
13437 
13442  {
13443  return iteration_proxy<const_iterator>(*this);
13444  }
13445 
13447 
13448 
13450  // capacity //
13452 
13455 
13497  bool empty() const noexcept
13498  {
13499  switch (m_type) {
13500  case value_t::null:
13501  {
13502  // null values are empty
13503  return true;
13504  }
13505 
13506  case value_t::array:
13507  {
13508  // delegate call to array_t::empty()
13509  return m_value.array->empty();
13510  }
13511 
13512  case value_t::object:
13513  {
13514  // delegate call to object_t::empty()
13515  return m_value.object->empty();
13516  }
13517 
13518  default:
13519  {
13520  // all other types are nonempty
13521  return false;
13522  }
13523  }
13524  }
13525 
13568  size_type size() const noexcept
13569  {
13570  switch (m_type) {
13571  case value_t::null:
13572  {
13573  // null values are empty
13574  return 0;
13575  }
13576 
13577  case value_t::array:
13578  {
13579  // delegate call to array_t::size()
13580  return m_value.array->size();
13581  }
13582 
13583  case value_t::object:
13584  {
13585  // delegate call to object_t::size()
13586  return m_value.object->size();
13587  }
13588 
13589  default:
13590  {
13591  // all other types have size 1
13592  return 1;
13593  }
13594  }
13595  }
13596 
13637  size_type max_size() const noexcept
13638  {
13639  switch (m_type) {
13640  case value_t::array:
13641  {
13642  // delegate call to array_t::max_size()
13643  return m_value.array->max_size();
13644  }
13645 
13646  case value_t::object:
13647  {
13648  // delegate call to object_t::max_size()
13649  return m_value.object->max_size();
13650  }
13651 
13652  default:
13653  {
13654  // all other types have max_size() == size()
13655  return size();
13656  }
13657  }
13658  }
13659 
13661 
13662 
13664  // modifiers //
13666 
13669 
13706  void clear() noexcept
13707  {
13708  switch (m_type) {
13710  {
13711  m_value.number_integer = 0;
13712  break;
13713  }
13714 
13716  {
13717  m_value.number_unsigned = 0;
13718  break;
13719  }
13720 
13721  case value_t::number_float:
13722  {
13723  m_value.number_float = 0.0;
13724  break;
13725  }
13726 
13727  case value_t::boolean:
13728  {
13729  m_value.boolean = false;
13730  break;
13731  }
13732 
13733  case value_t::string:
13734  {
13735  m_value.string->clear();
13736  break;
13737  }
13738 
13739  case value_t::array:
13740  {
13741  m_value.array->clear();
13742  break;
13743  }
13744 
13745  case value_t::object:
13746  {
13747  m_value.object->clear();
13748  break;
13749  }
13750 
13751  default:
13752  break;
13753  }
13754  }
13755 
13776  void push_back(basic_json &&val)
13777  {
13778  // push_back only works for null objects or arrays
13779  if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13780  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13781  }
13782 
13783  // transform null object into an array
13784  if (is_null()) {
13785  m_type = value_t::array;
13786  m_value = value_t::array;
13787  assert_invariant();
13788  }
13789 
13790  // add element to array (move semantics)
13791  m_value.array->push_back(std::move(val));
13792  // invalidate object
13793  val.m_type = value_t::null;
13794  }
13795 
13800  reference operator+=(basic_json &&val)
13801  {
13802  push_back(std::move(val));
13803  return *this;
13804  }
13805 
13810  void push_back(const basic_json &val)
13811  {
13812  // push_back only works for null objects or arrays
13813  if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13814  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13815  }
13816 
13817  // transform null object into an array
13818  if (is_null()) {
13819  m_type = value_t::array;
13820  m_value = value_t::array;
13821  assert_invariant();
13822  }
13823 
13824  // add element to array
13825  m_value.array->push_back(val);
13826  }
13827 
13832  reference operator+=(const basic_json &val)
13833  {
13834  push_back(val);
13835  return *this;
13836  }
13837 
13858  void push_back(const typename object_t::value_type &val)
13859  {
13860  // push_back only works for null objects or objects
13861  if (JSON_UNLIKELY(not (is_null() or is_object()))) {
13862  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
13863  }
13864 
13865  // transform null object into an object
13866  if (is_null()) {
13867  m_type = value_t::object;
13868  m_value = value_t::object;
13869  assert_invariant();
13870  }
13871 
13872  // add element to array
13873  m_value.object->insert(val);
13874  }
13875 
13880  reference operator+=(const typename object_t::value_type &val)
13881  {
13882  push_back(val);
13883  return *this;
13884  }
13885 
13912  {
13913  if (is_object() and init.size() == 2 and (*init.begin())->is_string()) {
13914  basic_json &&key = init.begin()->moved_or_copied();
13915  push_back(typename object_t::value_type(
13916  std::move(key.get_ref<string_t &>()), (init.begin() + 1)->moved_or_copied()));
13917  } else {
13918  push_back(basic_json(init));
13919  }
13920  }
13921 
13927  {
13928  push_back(init);
13929  return *this;
13930  }
13931 
13953  template<class... Args>
13954  void emplace_back(Args && ... args)
13955  {
13956  // emplace_back only works for null objects or arrays
13957  if (JSON_UNLIKELY(not (is_null() or is_array()))) {
13958  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
13959  }
13960 
13961  // transform null object into an array
13962  if (is_null()) {
13963  m_type = value_t::array;
13964  m_value = value_t::array;
13965  assert_invariant();
13966  }
13967 
13968  // add element to array (perfect forwarding)
13969  m_value.array->emplace_back(std::forward<Args>(args) ...);
13970  }
13971 
13999  template<class... Args>
14000  std::pair<iterator, bool> emplace(Args && ... args)
14001  {
14002  // emplace only works for null objects or arrays
14003  if (JSON_UNLIKELY(not (is_null() or is_object()))) {
14004  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
14005  }
14006 
14007  // transform null object into an object
14008  if (is_null()) {
14009  m_type = value_t::object;
14010  m_value = value_t::object;
14011  assert_invariant();
14012  }
14013 
14014  // add element to array (perfect forwarding)
14015  auto res = m_value.object->emplace(std::forward<Args>(args) ...);
14016  // create result iterator and set iterator to the result of emplace
14017  auto it = begin();
14018  it.m_it.object_iterator = res.first;
14019 
14020  // return pair of iterator and boolean
14021  return { it, res.second };
14022  }
14023 
14046  iterator insert(const_iterator pos, const basic_json &val)
14047  {
14048  // insert only works for arrays
14049  if (JSON_LIKELY(is_array())) {
14050  // check if iterator pos fits to this JSON value
14051  if (JSON_UNLIKELY(pos.m_object != this)) {
14052  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14053  }
14054 
14055  // insert to array and return iterator
14056  iterator result(this);
14057  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
14058  return result;
14059  }
14060 
14061  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14062  }
14063 
14068  iterator insert(const_iterator pos, basic_json &&val)
14069  {
14070  return insert(pos, val);
14071  }
14072 
14097  iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
14098  {
14099  // insert only works for arrays
14100  if (JSON_LIKELY(is_array())) {
14101  // check if iterator pos fits to this JSON value
14102  if (JSON_UNLIKELY(pos.m_object != this)) {
14103  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14104  }
14105 
14106  // insert to array and return iterator
14107  iterator result(this);
14108  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
14109  return result;
14110  }
14111 
14112  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14113  }
14114 
14146  {
14147  // insert only works for arrays
14148  if (JSON_UNLIKELY(not is_array())) {
14149  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14150  }
14151 
14152  // check if iterator pos fits to this JSON value
14153  if (JSON_UNLIKELY(pos.m_object != this)) {
14154  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14155  }
14156 
14157  // check if range iterators belong to the same JSON object
14158  if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14159  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14160  }
14161 
14162  if (JSON_UNLIKELY(first.m_object == this)) {
14163  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
14164  }
14165 
14166  // insert to array and return iterator
14167  iterator result(this);
14168  result.m_it.array_iterator = m_value.array->insert(
14169  pos.m_it.array_iterator,
14170  first.m_it.array_iterator,
14171  last.m_it.array_iterator);
14172  return result;
14173  }
14174 
14200  {
14201  // insert only works for arrays
14202  if (JSON_UNLIKELY(not is_array())) {
14203  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14204  }
14205 
14206  // check if iterator pos fits to this JSON value
14207  if (JSON_UNLIKELY(pos.m_object != this)) {
14208  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14209  }
14210 
14211  // insert to array and return iterator
14212  iterator result(this);
14213  result.m_it.array_iterator =
14214  m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
14215  return result;
14216  }
14217 
14242  {
14243  // insert only works for objects
14244  if (JSON_UNLIKELY(not is_object())) {
14245  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14246  }
14247 
14248  // check if range iterators belong to the same JSON object
14249  if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14250  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14251  }
14252 
14253  // passed iterators must belong to objects
14254  if (JSON_UNLIKELY(not first.m_object->is_object())) {
14255  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
14256  }
14257 
14258  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
14259  }
14260 
14281  {
14282  // implicitly convert null value to an empty object
14283  if (is_null()) {
14284  m_type = value_t::object;
14285  m_value.object = create<object_t>();
14286  assert_invariant();
14287  }
14288 
14289  if (JSON_UNLIKELY(not is_object())) {
14290  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
14291  }
14292 
14293  if (JSON_UNLIKELY(not j.is_object())) {
14294  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
14295  }
14296 
14297  for (auto it = j.cbegin(); it != j.cend(); ++it) {
14298  m_value.object->operator[](it.key()) = it.value();
14299  }
14300  }
14301 
14329  {
14330  // implicitly convert null value to an empty object
14331  if (is_null()) {
14332  m_type = value_t::object;
14333  m_value.object = create<object_t>();
14334  assert_invariant();
14335  }
14336 
14337  if (JSON_UNLIKELY(not is_object())) {
14338  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
14339  }
14340 
14341  // check if range iterators belong to the same JSON object
14342  if (JSON_UNLIKELY(first.m_object != last.m_object)) {
14343  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14344  }
14345 
14346  // passed iterators must belong to objects
14347  if (JSON_UNLIKELY(not first.m_object->is_object()
14348  or not first.m_object->is_object())) {
14349  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
14350  }
14351 
14352  for (auto it = first; it != last; ++it) {
14353  m_value.object->operator[](it.key()) = it.value();
14354  }
14355  }
14356 
14374  void swap(reference other) noexcept (
14375  std::is_nothrow_move_constructible<value_t>::value and
14376  std::is_nothrow_move_assignable<value_t>::value and
14377  std::is_nothrow_move_constructible<json_value>::value and
14378  std::is_nothrow_move_assignable<json_value>::value
14379  )
14380  {
14381  std::swap(m_type, other.m_type);
14382  std::swap(m_value, other.m_value);
14383  assert_invariant();
14384  }
14385 
14406  void swap(array_t &other)
14407  {
14408  // swap only works for arrays
14409  if (JSON_LIKELY(is_array())) {
14410  std::swap(*(m_value.array), other);
14411  } else {
14412  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14413  }
14414  }
14415 
14436  void swap(object_t &other)
14437  {
14438  // swap only works for objects
14439  if (JSON_LIKELY(is_object())) {
14440  std::swap(*(m_value.object), other);
14441  } else {
14442  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14443  }
14444  }
14445 
14466  void swap(string_t &other)
14467  {
14468  // swap only works for strings
14469  if (JSON_LIKELY(is_string())) {
14470  std::swap(*(m_value.string), other);
14471  } else {
14472  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14473  }
14474  }
14475 
14477 
14478 public:
14480  // lexicographical comparison operators //
14482 
14485 
14525  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
14526  {
14527  const auto lhs_type = lhs.type();
14528  const auto rhs_type = rhs.type();
14529 
14530  if (lhs_type == rhs_type) {
14531  switch (lhs_type) {
14532  case value_t::array:
14533  return (*lhs.m_value.array == *rhs.m_value.array);
14534 
14535  case value_t::object:
14536  return (*lhs.m_value.object == *rhs.m_value.object);
14537 
14538  case value_t::null:
14539  return true;
14540 
14541  case value_t::string:
14542  return (*lhs.m_value.string == *rhs.m_value.string);
14543 
14544  case value_t::boolean:
14545  return (lhs.m_value.boolean == rhs.m_value.boolean);
14546 
14548  return (lhs.m_value.number_integer == rhs.m_value.number_integer);
14549 
14551  return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
14552 
14553  case value_t::number_float:
14554  return (lhs.m_value.number_float == rhs.m_value.number_float);
14555 
14556  default:
14557  return false;
14558  }
14559  } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14560  return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
14561  } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14562  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
14563  } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14564  return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
14565  } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14566  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
14567  } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14568  return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
14569  } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14570  return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
14571  }
14572 
14573  return false;
14574  }
14575 
14580  template<typename ScalarType, typename std::enable_if<
14581  std::is_scalar<ScalarType>::value, int>::type = 0>
14582  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
14583  {
14584  return (lhs == basic_json(rhs));
14585  }
14586 
14591  template<typename ScalarType, typename std::enable_if<
14592  std::is_scalar<ScalarType>::value, int>::type = 0>
14593  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
14594  {
14595  return (basic_json(lhs) == rhs);
14596  }
14597 
14616  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
14617  {
14618  return not (lhs == rhs);
14619  }
14620 
14625  template<typename ScalarType, typename std::enable_if<
14626  std::is_scalar<ScalarType>::value, int>::type = 0>
14627  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
14628  {
14629  return (lhs != basic_json(rhs));
14630  }
14631 
14636  template<typename ScalarType, typename std::enable_if<
14637  std::is_scalar<ScalarType>::value, int>::type = 0>
14638  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
14639  {
14640  return (basic_json(lhs) != rhs);
14641  }
14642 
14669  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
14670  {
14671  const auto lhs_type = lhs.type();
14672  const auto rhs_type = rhs.type();
14673 
14674  if (lhs_type == rhs_type) {
14675  switch (lhs_type) {
14676  case value_t::array:
14677  return (*lhs.m_value.array) < (*rhs.m_value.array);
14678 
14679  case value_t::object:
14680  return *lhs.m_value.object < *rhs.m_value.object;
14681 
14682  case value_t::null:
14683  return false;
14684 
14685  case value_t::string:
14686  return *lhs.m_value.string < *rhs.m_value.string;
14687 
14688  case value_t::boolean:
14689  return lhs.m_value.boolean < rhs.m_value.boolean;
14690 
14692  return lhs.m_value.number_integer < rhs.m_value.number_integer;
14693 
14695  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
14696 
14697  case value_t::number_float:
14698  return lhs.m_value.number_float < rhs.m_value.number_float;
14699 
14700  default:
14701  return false;
14702  }
14703  } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float) {
14704  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
14705  } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer) {
14706  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
14707  } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float) {
14708  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
14709  } else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned) {
14710  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
14711  } else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned) {
14712  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
14713  } else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer) {
14714  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
14715  }
14716 
14717  // We only reach this line if we cannot compare values. In that case,
14718  // we compare types. Note we have to call the operator explicitly,
14719  // because MSVC has problems otherwise.
14720  return operator<(lhs_type, rhs_type);
14721  }
14722 
14727  template<typename ScalarType, typename std::enable_if<
14728  std::is_scalar<ScalarType>::value, int>::type = 0>
14729  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
14730  {
14731  return (lhs < basic_json(rhs));
14732  }
14733 
14738  template<typename ScalarType, typename std::enable_if<
14739  std::is_scalar<ScalarType>::value, int>::type = 0>
14740  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
14741  {
14742  return (basic_json(lhs) < rhs);
14743  }
14744 
14764  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
14765  {
14766  return not (rhs < lhs);
14767  }
14768 
14773  template<typename ScalarType, typename std::enable_if<
14774  std::is_scalar<ScalarType>::value, int>::type = 0>
14775  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
14776  {
14777  return (lhs <= basic_json(rhs));
14778  }
14779 
14784  template<typename ScalarType, typename std::enable_if<
14785  std::is_scalar<ScalarType>::value, int>::type = 0>
14786  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
14787  {
14788  return (basic_json(lhs) <= rhs);
14789  }
14790 
14810  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
14811  {
14812  return not (lhs <= rhs);
14813  }
14814 
14819  template<typename ScalarType, typename std::enable_if<
14820  std::is_scalar<ScalarType>::value, int>::type = 0>
14821  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
14822  {
14823  return (lhs > basic_json(rhs));
14824  }
14825 
14830  template<typename ScalarType, typename std::enable_if<
14831  std::is_scalar<ScalarType>::value, int>::type = 0>
14832  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
14833  {
14834  return (basic_json(lhs) > rhs);
14835  }
14836 
14856  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
14857  {
14858  return not (lhs < rhs);
14859  }
14860 
14865  template<typename ScalarType, typename std::enable_if<
14866  std::is_scalar<ScalarType>::value, int>::type = 0>
14867  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
14868  {
14869  return (lhs >= basic_json(rhs));
14870  }
14871 
14876  template<typename ScalarType, typename std::enable_if<
14877  std::is_scalar<ScalarType>::value, int>::type = 0>
14878  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
14879  {
14880  return (basic_json(lhs) >= rhs);
14881  }
14882 
14884 
14886  // serialization //
14888 
14891 
14923  friend std ::ostream &operator<<(std::ostream &o, const basic_json &j)
14924  {
14925  // read width member and use it as indentation parameter if nonzero
14926  const bool pretty_print = (o.width() > 0);
14927  const auto indentation = (pretty_print ? o.width() : 0);
14928 
14929  // reset width to 0 for subsequent calls to this stream
14930  o.width(0);
14931 
14932  // do the actual serialization
14933  serializer s(detail::output_adapter<char>(o), o.fill());
14934  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
14935  return o;
14936  }
14937 
14946  JSON_DEPRECATED
14947  friend std ::ostream &operator>>(const basic_json &j, std::ostream &o)
14948  {
14949  return o << j;
14950  }
14951 
14953 
14954 
14956  // deserialization //
14958 
14961 
15024  static basic_json parse(detail::input_adapter i,
15025  const parser_callback_t cb = nullptr,
15026  const bool allow_exceptions = true)
15027  {
15028  basic_json result;
15029  parser(i, cb, allow_exceptions).parse(true, result);
15030  return result;
15031  }
15032 
15036  static basic_json parse(detail::input_adapter &i,
15037  const parser_callback_t cb = nullptr,
15038  const bool allow_exceptions = true)
15039  {
15040  basic_json result;
15041  parser(i, cb, allow_exceptions).parse(true, result);
15042  return result;
15043  }
15044 
15045  static bool accept(detail::input_adapter i)
15046  {
15047  return parser(i).accept(true);
15048  }
15049 
15050  static bool accept(detail::input_adapter &i)
15051  {
15052  return parser(i).accept(true);
15053  }
15054 
15102  template<class IteratorType, typename std::enable_if<
15103  std::is_base_of<
15104  std::random_access_iterator_tag,
15105  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
15106  static basic_json parse(IteratorType first, IteratorType last,
15107  const parser_callback_t cb = nullptr,
15108  const bool allow_exceptions = true)
15109  {
15110  basic_json result;
15111  parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
15112  return result;
15113  }
15114 
15115  template<class IteratorType, typename std::enable_if<
15116  std::is_base_of<
15117  std::random_access_iterator_tag,
15118  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
15119  static bool accept(IteratorType first, IteratorType last)
15120  {
15121  return parser(detail::input_adapter(first, last)).accept(true);
15122  }
15123 
15132  JSON_DEPRECATED
15133  friend std ::istream &operator<<(basic_json &j, std::istream &i)
15134  {
15135  return operator>>(i, j);
15136  }
15137 
15163  friend std ::istream &operator>>(std::istream &i, basic_json &j)
15164  {
15165  parser(detail::input_adapter(i)).parse(false, j);
15166  return i;
15167  }
15168 
15170 
15172  // convenience functions //
15174 
15205  const char *type_name() const noexcept
15206  {
15207  {
15208  switch (m_type) {
15209  case value_t::null:
15210  return "null";
15211  case value_t::object:
15212  return "object";
15213  case value_t::array:
15214  return "array";
15215  case value_t::string:
15216  return "string";
15217  case value_t::boolean:
15218  return "boolean";
15219  case value_t::discarded:
15220  return "discarded";
15221  default:
15222  return "number";
15223  }
15224  }
15225  }
15226 
15227 private:
15229  // member variables //
15231 
15233  value_t m_type = value_t::null;
15234 
15236  json_value m_value = {};
15237 
15239  // binary serialization/deserialization //
15241 
15244 
15245 public:
15334  static std::vector<uint8_t> to_cbor(const basic_json &j)
15335  {
15336  std::vector<uint8_t> result;
15337  to_cbor(j, result);
15338  return result;
15339  }
15340 
15341  static void to_cbor(const basic_json &j, detail::output_adapter<uint8_t> o)
15342  {
15343  binary_writer<uint8_t>(o).write_cbor(j);
15344  }
15345 
15346  static void to_cbor(const basic_json &j, detail::output_adapter<char> o)
15347  {
15348  binary_writer<char>(o).write_cbor(j);
15349  }
15350 
15431  static std::vector<uint8_t> to_msgpack(const basic_json &j)
15432  {
15433  std::vector<uint8_t> result;
15434  to_msgpack(j, result);
15435  return result;
15436  }
15437 
15438  static void to_msgpack(const basic_json &j, detail::output_adapter<uint8_t> o)
15439  {
15440  binary_writer<uint8_t>(o).write_msgpack(j);
15441  }
15442 
15443  static void to_msgpack(const basic_json &j, detail::output_adapter<char> o)
15444  {
15445  binary_writer<char>(o).write_msgpack(j);
15446  }
15447 
15528  static std::vector<uint8_t> to_ubjson(const basic_json &j,
15529  const bool use_size = false,
15530  const bool use_type = false)
15531  {
15532  std::vector<uint8_t> result;
15533  to_ubjson(j, result, use_size, use_type);
15534  return result;
15535  }
15536 
15537  static void to_ubjson(const basic_json &j, detail::output_adapter<uint8_t> o,
15538  const bool use_size = false, const bool use_type = false)
15539  {
15540  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
15541  }
15542 
15543  static void to_ubjson(const basic_json &j, detail::output_adapter<char> o,
15544  const bool use_size = false, const bool use_type = false)
15545  {
15546  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
15547  }
15548 
15642  static basic_json from_cbor(detail::input_adapter i,
15643  const bool strict = true)
15644  {
15645  return binary_reader(i).parse_cbor(strict);
15646  }
15647 
15651  template<typename A1, typename A2,
15652  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15653  static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict = true)
15654  {
15655  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(
15656  strict);
15657  }
15658 
15733  const bool strict = true)
15734  {
15735  return binary_reader(i).parse_msgpack(strict);
15736  }
15737 
15741  template<typename A1, typename A2,
15742  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15743  static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict = true)
15744  {
15745  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(
15746  strict);
15747  }
15748 
15802  static basic_json from_ubjson(detail::input_adapter i,
15803  const bool strict = true)
15804  {
15805  return binary_reader(i).parse_ubjson(strict);
15806  }
15807 
15808  template<typename A1, typename A2,
15809  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
15810  static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict = true)
15811  {
15812  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(
15813  strict);
15814  }
15815 
15817 
15819  // JSON Pointer support //
15821 
15824 
15859  {
15860  return ptr.get_unchecked(this);
15861  }
15862 
15887  {
15888  return ptr.get_unchecked(this);
15889  }
15890 
15930  {
15931  return ptr.get_checked(this);
15932  }
15933 
15972  const_reference at(const json_pointer &ptr) const
15973  {
15974  return ptr.get_checked(this);
15975  }
15976 
15999  basic_json flatten() const
16000  {
16001  basic_json result(value_t::object);
16002  json_pointer::flatten("", *this, result);
16003  return result;
16004  }
16005 
16036  basic_json unflatten() const
16037  {
16038  return json_pointer::unflatten(*this);
16039  }
16040 
16042 
16044  // JSON Patch functions //
16046 
16049 
16097  basic_json patch(const basic_json &json_patch) const
16098  {
16099  // make a working copy to apply the patch to
16100  basic_json result = *this;
16101 
16102  // the valid JSON Patch operations
16103  enum class patch_operations { add, remove, replace, move, copy, test, invalid };
16104 
16105  const auto get_op = [](const std::string &op) {
16106  if (op == "add") {
16107  return patch_operations::add;
16108  }
16109 
16110  if (op == "remove") {
16111  return patch_operations::remove;
16112  }
16113 
16114  if (op == "replace") {
16115  return patch_operations::replace;
16116  }
16117 
16118  if (op == "move") {
16119  return patch_operations::move;
16120  }
16121 
16122  if (op == "copy") {
16123  return patch_operations::copy;
16124  }
16125 
16126  if (op == "test") {
16127  return patch_operations::test;
16128  }
16129 
16130  return patch_operations::invalid;
16131  };
16132 
16133  // wrapper for "add" operation; add value at ptr
16134  const auto operation_add = [&result](json_pointer &ptr, basic_json val) {
16135  // adding to the root of the target document means replacing it
16136  if (ptr.is_root()) {
16137  result = val;
16138  } else {
16139  // make sure the top element of the pointer exists
16140  json_pointer top_pointer = ptr.top();
16141  if (top_pointer != ptr) {
16142  result.at(top_pointer);
16143  }
16144 
16145  // get reference to parent of JSON pointer ptr
16146  const auto last_path = ptr.pop_back();
16147  basic_json &parent = result[ptr];
16148 
16149  switch (parent.m_type) {
16150  case value_t::null:
16151  case value_t::object:
16152  {
16153  // use operator[] to add value
16154  parent[last_path] = val;
16155  break;
16156  }
16157 
16158  case value_t::array:
16159  {
16160  if (last_path == "-") {
16161  // special case: append to back
16162  parent.push_back(val);
16163  } else {
16164  const auto idx = json_pointer::array_index(last_path);
16165  if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size())) {
16166  // avoid undefined behavior
16167  JSON_THROW(out_of_range::create(401,
16168  "array index " + std::to_string(idx) +
16169  " is out of range"));
16170  } else {
16171  // default case: insert add offset
16172  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
16173  }
16174  }
16175 
16176  break;
16177  }
16178 
16179  default:
16180  {
16181  // if there exists a parent it cannot be primitive
16182  assert(false); // LCOV_EXCL_LINE
16183  }
16184  }
16185  }
16186  };
16187 
16188  // wrapper for "remove" operation; remove value at ptr
16189  const auto operation_remove = [&result](json_pointer &ptr) {
16190  // get reference to parent of JSON pointer ptr
16191  const auto last_path = ptr.pop_back();
16192  basic_json &parent = result.at(ptr);
16193 
16194  // remove child
16195  if (parent.is_object()) {
16196  // perform range check
16197  auto it = parent.find(last_path);
16198  if (JSON_LIKELY(it != parent.end())) {
16199  parent.erase(it);
16200  } else {
16201  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
16202  }
16203  } else if (parent.is_array()) {
16204  // note erase performs range check
16205  parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
16206  }
16207  };
16208 
16209  // type check: top level value must be an array
16210  if (JSON_UNLIKELY(not json_patch.is_array())) {
16211  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
16212  }
16213 
16214  // iterate and apply the operations
16215  for (const auto &val : json_patch) {
16216  // wrapper to get a value for an operation
16217  const auto get_value = [&val](const std::string &op,
16218  const std::string &member,
16219  bool string_type) -> basic_json & {
16220  // find value
16221  auto it = val.m_value.object->find(member);
16222 
16223  // context-sensitive error message
16224  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
16225 
16226  // check if desired value is present
16227  if (JSON_UNLIKELY(it == val.m_value.object->end())) {
16228  JSON_THROW(parse_error::create(105, 0,
16229  error_msg + " must have member '" + member + "'"));
16230  }
16231 
16232  // check if result is of type string
16233  if (JSON_UNLIKELY(string_type and not it->second.is_string())) {
16234  JSON_THROW(parse_error::create(105, 0,
16235  error_msg + " must have string member '" + member +
16236  "'"));
16237  }
16238 
16239  // no error: return value
16240  return it->second;
16241  };
16242 
16243  // type check: every element of the array must be an object
16244  if (JSON_UNLIKELY(not val.is_object())) {
16245  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
16246  }
16247 
16248  // collect mandatory members
16249  const std::string op = get_value("op", "op", true);
16250  const std::string path = get_value(op, "path", true);
16251  json_pointer ptr(path);
16252 
16253  switch (get_op(op)) {
16254  case patch_operations::add:
16255  {
16256  operation_add(ptr, get_value("add", "value", false));
16257  break;
16258  }
16259 
16260  case patch_operations::remove:
16261  {
16262  operation_remove(ptr);
16263  break;
16264  }
16265 
16266  case patch_operations::replace:
16267  {
16268  // the "path" location must exist - use at()
16269  result.at(ptr) = get_value("replace", "value", false);
16270  break;
16271  }
16272 
16273  case patch_operations::move:
16274  {
16275  const std::string from_path = get_value("move", "from", true);
16276  json_pointer from_ptr(from_path);
16277 
16278  // the "from" location must exist - use at()
16279  basic_json v = result.at(from_ptr);
16280 
16281  // The move operation is functionally identical to a
16282  // "remove" operation on the "from" location, followed
16283  // immediately by an "add" operation at the target
16284  // location with the value that was just removed.
16285  operation_remove(from_ptr);
16286  operation_add(ptr, v);
16287  break;
16288  }
16289 
16290  case patch_operations::copy:
16291  {
16292  const std::string from_path = get_value("copy", "from", true);
16293  const json_pointer from_ptr(from_path);
16294 
16295  // the "from" location must exist - use at()
16296  basic_json v = result.at(from_ptr);
16297 
16298  // The copy is functionally identical to an "add"
16299  // operation at the target location using the value
16300  // specified in the "from" member.
16301  operation_add(ptr, v);
16302  break;
16303  }
16304 
16305  case patch_operations::test:
16306  {
16307  bool success = false;
16308  JSON_TRY
16309  {
16310  // check if "value" matches the one at "path"
16311  // the "path" location must exist - use at()
16312  success = (result.at(ptr) == get_value("test", "value", false));
16313  }
16314  JSON_CATCH(out_of_range &)
16315  {
16316  // ignore out of range errors: success remains false
16317  }
16318 
16319  // throw an exception if test fails
16320  if (JSON_UNLIKELY(not success)) {
16321  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
16322  }
16323 
16324  break;
16325  }
16326 
16327  case patch_operations::invalid:
16328  {
16329  // op must be "add", "remove", "replace", "move", "copy", or
16330  // "test"
16331  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
16332  }
16333  }
16334  }
16335 
16336  return result;
16337  }
16338 
16372  static basic_json diff(const basic_json &source, const basic_json &target,
16373  const std::string &path = "")
16374  {
16375  // the patch
16376  basic_json result(value_t::array);
16377 
16378  // if the values are the same, return empty patch
16379  if (source == target) {
16380  return result;
16381  }
16382 
16383  if (source.type() != target.type()) {
16384  // different types: replace value
16385  result.push_back(
16386  {
16387  { "op", "replace" }, { "path", path }, { "value", target }
16388  });
16389  } else {
16390  switch (source.type()) {
16391  case value_t::array:
16392  {
16393  // first pass: traverse common elements
16394  std::size_t i = 0;
16395  while (i < source.size() and i < target.size()) {
16396  // recursive call to compare array values at index i
16397  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
16398  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
16399  ++i;
16400  }
16401 
16402  // i now reached the end of at least one array
16403  // in a second pass, traverse the remaining elements
16404 
16405  // remove my remaining elements
16406  const auto end_index = static_cast<difference_type>(result.size());
16407  while (i < source.size()) {
16408  // add operations in reverse order to avoid invalid
16409  // indices
16410  result.insert(result.begin() + end_index, object(
16411  {
16412  { "op", "remove" },
16413  { "path", path + "/" + std::to_string(i) }
16414  }));
16415  ++i;
16416  }
16417 
16418  // add other remaining elements
16419  while (i < target.size()) {
16420  result.push_back(
16421  {
16422  { "op", "add" },
16423  { "path", path + "/" + std::to_string(i) },
16424  { "value", target[i] }
16425  });
16426  ++i;
16427  }
16428 
16429  break;
16430  }
16431 
16432  case value_t::object:
16433  {
16434  // first pass: traverse this object's elements
16435  for (auto it = source.cbegin(); it != source.cend(); ++it) {
16436  // escape the key name to be used in a JSON patch
16437  const auto key = json_pointer::escape(it.key());
16438 
16439  if (target.find(it.key()) != target.end()) {
16440  // recursive call to compare object values at key it
16441  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
16442  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
16443  } else {
16444  // found a key that is not in o -> remove it
16445  result.push_back(object(
16446  {
16447  { "op", "remove" }, { "path", path + "/" + key }
16448  }));
16449  }
16450  }
16451 
16452  // second pass: traverse other object's elements
16453  for (auto it = target.cbegin(); it != target.cend(); ++it) {
16454  if (source.find(it.key()) == source.end()) {
16455  // found a key that is not in this -> add it
16456  const auto key = json_pointer::escape(it.key());
16457  result.push_back(
16458  {
16459  { "op", "add" }, { "path", path + "/" + key },
16460  { "value", it.value() }
16461  });
16462  }
16463  }
16464 
16465  break;
16466  }
16467 
16468  default:
16469  {
16470  // both primitive type: replace value
16471  result.push_back(
16472  {
16473  { "op", "replace" }, { "path", path }, { "value", target }
16474  });
16475  break;
16476  }
16477  }
16478  }
16479 
16480  return result;
16481  }
16482 
16484 
16486  // JSON Merge Patch functions //
16488 
16491 
16534  void merge_patch(const basic_json &patch)
16535  {
16536  if (patch.is_object()) {
16537  if (not is_object()) {
16538  *this = object();
16539  }
16540 
16541  for (auto it = patch.begin(); it != patch.end(); ++it) {
16542  if (it.value().is_null()) {
16543  erase(it.key());
16544  } else {
16545  operator[](it.key()).merge_patch(it.value());
16546  }
16547  }
16548  } else {
16549  *this = patch;
16550  }
16551  }
16552 
16554 };
16555 
16556 } // namespace nlohmann
16557 
16559 // nonmember support //
16561 
16562 // specialization of std::swap, and std::hash
16563 namespace std
16564 {
16570 template<>
16571 inline void swap(nlohmann::json &j1,
16572  nlohmann::json &j2) noexcept (
16573  is_nothrow_move_constructible<nlohmann::json>::value and
16574  is_nothrow_move_assignable<nlohmann::json>::value
16575 )
16576 {
16577  j1.swap(j2);
16578 }
16579 
16581 template<>
16582 struct hash<nlohmann::json>
16583 {
16589  std::size_t operator()(const nlohmann::json &j) const
16590  {
16591  // a naive hashing via the string representation
16592  const auto &h = hash<nlohmann::json::string_t>();
16593  return h(j.dump());
16594  }
16595 };
16596 
16600 template<>
16602 {
16608  nlohmann::detail::value_t rhs) const noexcept
16609  {
16610  return nlohmann::detail::operator<(lhs, rhs);
16611  }
16612 };
16613 
16614 } // namespace std
16615 
16629 inline nlohmann::json operator"" _json(const char *s, std::size_t n)
16630 {
16631  return nlohmann::json::parse(s, s + n);
16632 }
16633 
16647 inline nlohmann::json::json_pointer operator"" _json_pointer(const char *s, std::size_t n)
16648 {
16650 }
16651 
16652 // #include <nlohmann/detail/macro_unscope.hpp>
16653 
16654 
16655 // restore GCC/clang diagnostic settings
16656 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
16657  #pragma GCC diagnostic pop
16658 #endif
16659 #if defined(__clang__)
16660  #pragma GCC diagnostic pop
16661 #endif
16662 
16663 // clean up
16664 #undef JSON_CATCH
16665 #undef JSON_THROW
16666 #undef JSON_TRY
16667 #undef JSON_LIKELY
16668 #undef JSON_UNLIKELY
16669 #undef JSON_DEPRECATED
16670 #undef JSON_HAS_CPP_14
16671 #undef JSON_HAS_CPP_17
16672 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
16673 #undef NLOHMANN_BASIC_JSON_TPL
16674 #undef NLOHMANN_JSON_HAS_HELPER
16675 
16676 
16677 #endif
std::vector< basic_json, std::allocator< basic_json > > array_t
a type for an array
Definition: json.hpp:9768
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:13832
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:10786
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:12325
Definition: json.hpp:6910
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14328
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:2927
static JSON_DEPRECATED iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13376
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
Definition: json.hpp:10357
token_type
token types for the parser
Definition: json.hpp:1894
const int id
the id of the exception
Definition: json.hpp:559
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:13954
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:4279
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:1648
Definition: json.hpp:1201
input_adapter(IteratorType first, IteratorType last)
input adapter for iterator range with contiguous storage
Definition: json.hpp:1800
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:13637
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13367
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:14669
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13433
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:10989
double number_float_t
a type for a number (floating-point)
Definition: json.hpp:10058
JSON_DEPRECATED friend std ::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:15133
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4592
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:6924
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4242
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:4224
value_t
the JSON type enumeration
Definition: json.hpp:880
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4301
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:7423
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:4598
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13441
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:3879
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:12704
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:4556
~basic_json() noexcept
destructor
Definition: json.hpp:11058
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:15886
Definition: json.hpp:7940
Definition: json.hpp:4708
reference value() const
return the value of an iterator
Definition: json.hpp:4605
void unget_character() override
restore the last non-eof() character to input
Definition: json.hpp:1705
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:553
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:4532
a signed integer – use get_number_integer() for actual value
array (ordered collection of values)
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:8634
std::uint64_t number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:9990
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:11158
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14775
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:4083
std::int64_t number_integer_t
a type for a number (integer)
Definition: json.hpp:9919
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:12278
a template for a reverse iterator class
Definition: json.hpp:4527
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:3918
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:11188
a class to store JSON values
Definition: json.hpp:85
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:9508
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:15929
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:14068
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:4233
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:10398
default JSONSerializer template argument
Definition: json.hpp:73
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14241
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:4114
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:11215
Definition: json.hpp:330
input_adapter(T(&array)[N])
input adapter for array
Definition: json.hpp:1828
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:9527
std::string string_t
a type for a string
Definition: json.hpp:9821
Definition: json.hpp:488
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:4190
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:3160
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:7017
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:13130
number value (signed integer)
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:10721
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:15999
Definition: json.hpp:16563
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:13059
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4568
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:9500
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:13880
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14145
input_adapter(CharT b, std::size_t l)
input adapter for buffer
Definition: json.hpp:1778
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:14638
friend std ::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:14923
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:7982
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:14821
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4473
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:4270
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13208
a template for a bidirectional iterator for the basic_json class
Definition: json.hpp:3832
friend std ::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:15163
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:14593
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:3854
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:11396
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:7181
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:14000
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:4537
BasicJsonType parse_ubjson(const bool strict)
create a JSON value from UBJSON input
Definition: json.hpp:4841
lexical analysis
Definition: json.hpp:1886
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:3673
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:4784
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:14832
syntax analysis
Definition: json.hpp:3115
serialization to CBOR and MessagePack values
Definition: json.hpp:6098
Definition: json.hpp:422
serializer(output_adapter_t< char > s, const char ichar)
Definition: json.hpp:7954
output adapter for byte vectors
Definition: json.hpp:4645
pointer operator->() const
dereference the iterator
Definition: json.hpp:4040
const std::size_t byte
byte index of the parse error
Definition: json.hpp:645
abstract input adapter interface
Definition: json.hpp:1638
void unget_character() noexcept override
restore the last non-eof() character to input
Definition: json.hpp:1742
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14867
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:3773
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.hpp:9310
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:12412
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:11025
std::string move_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:2939
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:10694
exception indicating access out of the defined range
Definition: json.hpp:786
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:11237
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:11374
Definition: json.hpp:328
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:12970
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:3667
void write_msgpack(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6308
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:7001
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:12013
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:10422
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:12155
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:12888
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:14729
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false) const
serialization
Definition: json.hpp:11111
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:10907
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:4072
Definition: json.hpp:287
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4580
void clear() noexcept
clears the contents
Definition: json.hpp:13706
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:14097
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:13926
parse_event_t
Definition: json.hpp:3124
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:2921
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:11289
Definition: json.hpp:276
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:16372
exception indicating a parse error
Definition: json.hpp:617
reference operator[](T *key)
access specified object element
Definition: json.hpp:12364
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:4312
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:2933
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:4541
static basic_json from_msgpack(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:15732
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:12986
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:15858
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:4544
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:12107
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:4534
an unsigned integer – use get_number_unsigned() for actual value
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:3777
abstract output adapter interface
Definition: json.hpp:4632
general exception of the basic_json class
Definition: json.hpp:549
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:13568
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:15528
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:7042
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:11861
Definition: json.hpp:261
Definition: json.hpp:339
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:15334
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:7756
reference back()
access the last element
Definition: json.hpp:12637
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:3775
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.hpp:3868
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:14582
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:15205
static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:15743
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:4181
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13069
input_adapter(CharT b)
input adapter for string literal
Definition: json.hpp:1790
exception indicating errors with iterators
Definition: json.hpp:689
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:13237
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:11259
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:903
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:7659
namespace for Niels Lohmann
Definition: json.hpp:63
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:12805
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:11440
input adapter for buffer input
Definition: json.hpp:1717
an floating point number – use get_number_float() for actual value
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:4574
object (unordered set of name/value pairs)
Definition: json.hpp:1556
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:11911
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:4005
Definition: json.hpp:496
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:9456
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.hpp:3863
exception indicating executing a member function with a wrong type
Definition: json.hpp:741
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14786
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:3679
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:11832
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:14525
std::map< std::string, basic_json, object_comparator_t, std::allocator< std::pair< const std::string, basic_json > >> object_t
a type for an object
Definition: json.hpp:9722
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer.
Definition: json.hpp:9452
typename parser::parse_event_t parse_event_t
parser event types
Definition: json.hpp:10306
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:12563
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:13810
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:13911
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.hpp:3144
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from an iterator range with contiguous storage
Definition: json.hpp:15106
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
Definition: json.hpp:16534
static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:15653
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:4361
Definition: json.hpp:1758
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:16589
static int array_index(const std::string &s)
Definition: json.hpp:8675
const_reference back() const
access the last element
Definition: json.hpp:12647
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:11467
output adapter for basic_string
Definition: json.hpp:4687
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14280
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:12473
input_adapter(std::istream &&i)
input adapter for input stream
Definition: json.hpp:1768
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:4641
bool boolean_t
a type for a boolean
Definition: json.hpp:9847
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:14810
constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:2978
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:6106
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:3193
char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:7798
output adapter for output streams
Definition: json.hpp:4666
static basic_json parse(detail::input_adapter i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
Definition: json.hpp:15024
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:13800
JSON_DEPRECATED friend std ::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:14947
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:11318
exception indicating other library errors
Definition: json.hpp:824
Definition: json.hpp:325
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:3685
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13099
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14878
void swap(array_t &other)
exchanges the values
Definition: json.hpp:14406
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:12058
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:9510
deserialization of CBOR and MessagePack values
Definition: json.hpp:4772
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:3857
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:16607
std::char_traits< char >::int_type get_character() override
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:1700
Definition: json.hpp:462
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:11346
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4477
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:4215
void swap(string_t &other)
exchanges the values
Definition: json.hpp:14466
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:3927
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:4125
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:14046
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:11418
an iterator value
Definition: json.hpp:3770
std::char_traits< char >::int_type get_character() noexcept override
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:1733
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13140
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13274
Definition: json.hpp:8532
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:4156
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:14199
static const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:1916
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:3859
static basic_json from_cbor(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:15642
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t &>(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:10488
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:8653
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:12198
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:12493
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:13776
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:6504
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:14740
reference front()
access the first element
Definition: json.hpp:12593
JSON Pointer.
Definition: json.hpp:99
Definition: json.hpp:318
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:13200
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4332
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:11924
BasicJsonType parse_msgpack(const bool strict)
create a JSON value from MessagePack input
Definition: json.hpp:4820
number value (unsigned integer)
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:9502
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13303
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:16097
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:12241
basic_json<> json
default JSON class
Definition: json.hpp:109
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:14627
BasicJsonType parse_cbor(const bool strict)
create a JSON value from CBOR input
Definition: json.hpp:4799
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:13019
input_adapter(std::istream &i)
input adapter for input stream
Definition: json.hpp:1764
void swap(object_t &other)
exchanges the values
Definition: json.hpp:14436
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:15431
constexpr std::size_t get_position() const noexcept
return position of last read token
Definition: json.hpp:2949
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:12541
reference value() const
return the value of an iterator
Definition: json.hpp:4376
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13170
proxy class for the items() function
Definition: json.hpp:3808
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:4562
std::string get_token_string() const
Definition: json.hpp:2957
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:13858
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:10570
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:16036
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:10651
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:14764
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:12922
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:14856
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4483
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:14616
void write_cbor(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6114
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:628
Definition: json.hpp:320
std::allocator< basic_json > allocator_type
the allocator type
Definition: json.hpp:9505
input_adapter(const ContiguousContainer &c)
input adapter for contiguous container
Definition: json.hpp:1837
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:14374
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:4550
const_reference front() const
access the first element
Definition: json.hpp:12601
static basic_json from_ubjson(detail::input_adapter i, const bool strict=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:15802
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:4859
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
Definition: json.hpp:7345
static basic_json parse(detail::input_adapter &i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
create an empty value with a given type parse(detail::input_adapter, const parser_callback_t) ...
Definition: json.hpp:15036
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:4290
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:15972
char * to_chars(char *first, char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:7875
discarded by the the parser callback function
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13245
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:4586
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:13497
static basic_json meta()
returns version information on the library
Definition: json.hpp:9558
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:6936
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.hpp:9294