json.hpp
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.1.2
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 2
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 }
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 
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 {
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 template<> struct make_index_sequence<1> : index_sequence<0> {};
300 
301 template<typename... Ts>
303 
304 /*
305 Implementation of two C++17 constructs: conjunction, negation. This is needed
306 to avoid evaluating all the traits in a condition
307 
308 For example: not std::is_same<void, T>::value and has_value_type<T>::value
309 will not compile when T = void (on MSVC at least). Whereas
310 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
311 stop evaluating if negation<...>::value == false
312 
313 Please note that those constructs must be used with caution, since symbols can
314 become very long quickly (which can slow down compilation and cause MSVC
315 internal compiler errors). Only use it when you have to (see example ahead).
316 */
317 template<class...> struct conjunction : std::true_type {};
318 template<class B1> struct conjunction<B1> : B1 {};
319 template<class B1, class... Bn>
320 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
321 
322 template<class B> struct negation : std::integral_constant<bool, not B::value> {};
323 
324 // dispatch utility (taken from ranges-v3)
325 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
326 template<> struct priority_tag<0> {};
327 
329 // has_/is_ functions //
331 
332 // source: https://stackoverflow.com/a/37193089/4116453
333 
334 template <typename T, typename = void>
335 struct is_complete_type : std::false_type {};
336 
337 template <typename T>
338 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
339 
340 NLOHMANN_JSON_HAS_HELPER(mapped_type);
341 NLOHMANN_JSON_HAS_HELPER(key_type);
342 NLOHMANN_JSON_HAS_HELPER(value_type);
343 NLOHMANN_JSON_HAS_HELPER(iterator);
344 
345 template<bool B, class RealType, class CompatibleObjectType>
346 struct is_compatible_object_type_impl : std::false_type {};
347 
348 template<class RealType, class CompatibleObjectType>
349 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
350 {
351  static constexpr auto value =
352  std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
353  std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
354 };
355 
356 template<class BasicJsonType, class CompatibleObjectType>
358 {
359  static auto constexpr value = is_compatible_object_type_impl <
361  has_mapped_type<CompatibleObjectType>,
362  has_key_type<CompatibleObjectType>>::value,
363  typename BasicJsonType::object_t, CompatibleObjectType >::value;
364 };
365 
366 template<typename BasicJsonType, typename T>
368 {
369  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
370  std::is_same<T, typename BasicJsonType::const_iterator>::value or
371  std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
372  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
373 };
374 
375 template<class BasicJsonType, class CompatibleArrayType>
377 {
378  static auto constexpr value =
381  BasicJsonType, CompatibleArrayType>>,
382  negation<std::is_constructible<typename BasicJsonType::string_t,
383  CompatibleArrayType>>,
385  has_value_type<CompatibleArrayType>,
386  has_iterator<CompatibleArrayType>>::value;
387 };
388 
389 template<bool, typename, typename>
390 struct is_compatible_integer_type_impl : std::false_type {};
391 
392 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
393 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
394 {
395  // is there an assert somewhere on overflows?
396  using RealLimits = std::numeric_limits<RealIntegerType>;
397  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
398 
399  static constexpr auto value =
400  std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
401  CompatibleLimits::is_integer and
402  RealLimits::is_signed == CompatibleLimits::is_signed;
403 };
404 
405 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
407 {
408  static constexpr auto value =
410  std::is_integral<CompatibleNumberIntegerType>::value and
411  not std::is_same<bool, CompatibleNumberIntegerType>::value,
412  RealIntegerType, CompatibleNumberIntegerType > ::value;
413 };
414 
415 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
416 template<typename BasicJsonType, typename T>
418 {
419  private:
420  // also check the return type of from_json
422  std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
423  static int detect(U&&);
424  static void detect(...);
425 
426  public:
427  static constexpr bool value = std::is_integral<decltype(
428  detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
429 };
430 
431 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
432 // this overload is used for non-default-constructible user-defined-types
433 template<typename BasicJsonType, typename T>
435 {
436  private:
437  template <
438  typename U,
439  typename = enable_if_t<std::is_same<
440  T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
441  static int detect(U&&);
442  static void detect(...);
443 
444  public:
445  static constexpr bool value = std::is_integral<decltype(detect(
446  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
447 };
448 
449 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
450 template<typename BasicJsonType, typename T>
452 {
453  private:
455  std::declval<BasicJsonType&>(), std::declval<T>()))>
456  static int detect(U&&);
457  static void detect(...);
458 
459  public:
460  static constexpr bool value = std::is_integral<decltype(detect(
461  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
462 };
463 
464 template <typename BasicJsonType, typename CompatibleCompleteType>
466 {
467  static constexpr bool value =
468  not std::is_base_of<std::istream, CompatibleCompleteType>::value and
472 };
473 
474 template <typename BasicJsonType, typename CompatibleType>
476  : conjunction<is_complete_type<CompatibleType>,
477  is_compatible_complete_type<BasicJsonType, CompatibleType>>
478 {
479 };
480 
481 // taken from ranges-v3
482 template<typename T>
484 {
485  static constexpr T value{};
486 };
487 
488 template<typename T>
489 constexpr T static_const<T>::value;
490 }
491 }
492 
493 // #include <nlohmann/detail/exceptions.hpp>
494 
495 
496 #include <exception> // exception
497 #include <stdexcept> // runtime_error
498 #include <string> // to_string
499 
500 namespace nlohmann
501 {
502 namespace detail
503 {
505 // exceptions //
507 
536 class exception : public std::exception
537 {
538  public:
540  const char* what() const noexcept override
541  {
542  return m.what();
543  }
544 
546  const int id;
547 
548  protected:
549  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
550 
551  static std::string name(const std::string& ename, int id_)
552  {
553  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
554  }
555 
556  private:
558  std::runtime_error m;
559 };
560 
604 class parse_error : public exception
605 {
606  public:
615  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
616  {
617  std::string w = exception::name("parse_error", id_) + "parse error" +
618  (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
619  ": " + what_arg;
620  return parse_error(id_, byte_, w.c_str());
621  }
622 
632  const std::size_t byte;
633 
634  private:
635  parse_error(int id_, std::size_t byte_, const char* what_arg)
636  : exception(id_, what_arg), byte(byte_) {}
637 };
638 
677 {
678  public:
679  static invalid_iterator create(int id_, const std::string& what_arg)
680  {
681  std::string w = exception::name("invalid_iterator", id_) + what_arg;
682  return invalid_iterator(id_, w.c_str());
683  }
684 
685  private:
686  invalid_iterator(int id_, const char* what_arg)
687  : exception(id_, what_arg) {}
688 };
689 
728 class type_error : public exception
729 {
730  public:
731  static type_error create(int id_, const std::string& what_arg)
732  {
733  std::string w = exception::name("type_error", id_) + what_arg;
734  return type_error(id_, w.c_str());
735  }
736 
737  private:
738  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
739 };
740 
773 class out_of_range : public exception
774 {
775  public:
776  static out_of_range create(int id_, const std::string& what_arg)
777  {
778  std::string w = exception::name("out_of_range", id_) + what_arg;
779  return out_of_range(id_, w.c_str());
780  }
781 
782  private:
783  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
784 };
785 
810 class other_error : public exception
811 {
812  public:
813  static other_error create(int id_, const std::string& what_arg)
814  {
815  std::string w = exception::name("other_error", id_) + what_arg;
816  return other_error(id_, w.c_str());
817  }
818 
819  private:
820  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
821 };
822 }
823 }
824 
825 // #include <nlohmann/detail/value_t.hpp>
826 
827 
828 #include <array> // array
829 #include <ciso646> // and
830 #include <cstddef> // size_t
831 #include <cstdint> // uint8_t
832 
833 namespace nlohmann
834 {
835 namespace detail
836 {
838 // JSON type enumeration //
840 
865 enum class value_t : std::uint8_t
866 {
867  null,
868  object,
869  array,
870  string,
871  boolean,
874  number_float,
875  discarded
876 };
877 
888 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
889 {
890  static constexpr std::array<std::uint8_t, 8> order = {{
891  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
892  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
893  }
894  };
895 
896  const auto l_index = static_cast<std::size_t>(lhs);
897  const auto r_index = static_cast<std::size_t>(rhs);
898  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
899 }
900 }
901 }
902 
903 // #include <nlohmann/detail/conversions/from_json.hpp>
904 
905 
906 #include <algorithm> // transform
907 #include <array> // array
908 #include <ciso646> // and, not
909 #include <forward_list> // forward_list
910 #include <iterator> // inserter, front_inserter, end
911 #include <string> // string
912 #include <tuple> // tuple, make_tuple
913 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
914 #include <utility> // pair, declval
915 #include <valarray> // valarray
916 
917 // #include <nlohmann/detail/exceptions.hpp>
918 
919 // #include <nlohmann/detail/macro_scope.hpp>
920 
921 // #include <nlohmann/detail/meta.hpp>
922 
923 // #include <nlohmann/detail/value_t.hpp>
924 
925 
926 namespace nlohmann
927 {
928 namespace detail
929 {
930 // overloads for basic_json template parameters
931 template<typename BasicJsonType, typename ArithmeticType,
933  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
934  int> = 0>
935 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
936 {
937  switch (static_cast<value_t>(j))
938  {
940  {
941  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
942  break;
943  }
945  {
946  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
947  break;
948  }
950  {
951  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
952  break;
953  }
954 
955  default:
956  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
957  }
958 }
959 
960 template<typename BasicJsonType>
961 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
962 {
963  if (JSON_UNLIKELY(not j.is_boolean()))
964  {
965  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
966  }
967  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
968 }
969 
970 template<typename BasicJsonType>
971 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
972 {
973  if (JSON_UNLIKELY(not j.is_string()))
974  {
975  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
976  }
977  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
978 }
979 
980 template<typename BasicJsonType>
981 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
982 {
983  get_arithmetic_value(j, val);
984 }
985 
986 template<typename BasicJsonType>
987 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
988 {
989  get_arithmetic_value(j, val);
990 }
991 
992 template<typename BasicJsonType>
993 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
994 {
995  get_arithmetic_value(j, val);
996 }
997 
998 template<typename BasicJsonType, typename EnumType,
1000 void from_json(const BasicJsonType& j, EnumType& e)
1001 {
1002  typename std::underlying_type<EnumType>::type val;
1003  get_arithmetic_value(j, val);
1004  e = static_cast<EnumType>(val);
1005 }
1006 
1007 template<typename BasicJsonType>
1008 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1009 {
1010  if (JSON_UNLIKELY(not j.is_array()))
1011  {
1012  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1013  }
1014  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1015 }
1016 
1017 // forward_list doesn't have an insert method
1018 template<typename BasicJsonType, typename T, typename Allocator,
1020 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1021 {
1022  if (JSON_UNLIKELY(not j.is_array()))
1023  {
1024  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1025  }
1026  std::transform(j.rbegin(), j.rend(),
1027  std::front_inserter(l), [](const BasicJsonType & i)
1028  {
1029  return i.template get<T>();
1030  });
1031 }
1032 
1033 // valarray doesn't have an insert method
1034 template<typename BasicJsonType, typename T,
1035  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1036 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1037 {
1038  if (JSON_UNLIKELY(not j.is_array()))
1039  {
1040  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1041  }
1042  l.resize(j.size());
1043  std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1044 }
1045 
1046 template<typename BasicJsonType, typename CompatibleArrayType>
1047 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1048 {
1049  using std::end;
1050 
1051  std::transform(j.begin(), j.end(),
1052  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1053  {
1054  // get<BasicJsonType>() returns *this, this won't call a from_json
1055  // method when value_type is BasicJsonType
1056  return i.template get<typename CompatibleArrayType::value_type>();
1057  });
1058 }
1059 
1060 template<typename BasicJsonType, typename CompatibleArrayType>
1061 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1062 -> decltype(
1063  arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1064  void())
1065 {
1066  using std::end;
1067 
1068  arr.reserve(j.size());
1069  std::transform(j.begin(), j.end(),
1070  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1071  {
1072  // get<BasicJsonType>() returns *this, this won't call a from_json
1073  // method when value_type is BasicJsonType
1074  return i.template get<typename CompatibleArrayType::value_type>();
1075  });
1076 }
1077 
1078 template<typename BasicJsonType, typename T, std::size_t N>
1079 void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1080 {
1081  for (std::size_t i = 0; i < N; ++i)
1082  {
1083  arr[i] = j.at(i).template get<T>();
1084  }
1085 }
1086 
1087 template <
1088  typename BasicJsonType, typename CompatibleArrayType,
1089  enable_if_t <
1091  not std::is_same<typename BasicJsonType::array_t,
1092  CompatibleArrayType>::value and
1093  std::is_constructible <
1094  BasicJsonType, typename CompatibleArrayType::value_type >::value,
1095  int > = 0 >
1096 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1097 {
1098  if (JSON_UNLIKELY(not j.is_array()))
1099  {
1100  JSON_THROW(type_error::create(302, "type must be array, but is " +
1101  std::string(j.type_name())));
1102  }
1103 
1105 }
1106 
1107 template<typename BasicJsonType, typename CompatibleObjectType,
1109 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1110 {
1111  if (JSON_UNLIKELY(not j.is_object()))
1112  {
1113  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1114  }
1115 
1116  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1117  using value_type = typename CompatibleObjectType::value_type;
1118  std::transform(
1119  inner_object->begin(), inner_object->end(),
1120  std::inserter(obj, obj.begin()),
1121  [](typename BasicJsonType::object_t::value_type const & p)
1122  {
1123  return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1124  });
1125 }
1126 
1127 // overload for arithmetic types, not chosen for basic_json template arguments
1128 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1129 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1130 // an arithmetic type?
1131 template<typename BasicJsonType, typename ArithmeticType,
1132  enable_if_t <
1133  std::is_arithmetic<ArithmeticType>::value and
1134  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1135  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1136  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1137  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1138  int> = 0>
1139 void from_json(const BasicJsonType& j, ArithmeticType& val)
1140 {
1141  switch (static_cast<value_t>(j))
1142  {
1144  {
1145  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1146  break;
1147  }
1149  {
1150  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1151  break;
1152  }
1153  case value_t::number_float:
1154  {
1155  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1156  break;
1157  }
1158  case value_t::boolean:
1159  {
1160  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1161  break;
1162  }
1163 
1164  default:
1165  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1166  }
1167 }
1168 
1169 template<typename BasicJsonType, typename A1, typename A2>
1170 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1171 {
1172  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1173 }
1174 
1175 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1176 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1177 {
1178  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1179 }
1180 
1181 template<typename BasicJsonType, typename... Args>
1182 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1183 {
1185 }
1186 
1188 {
1189  private:
1190  template<typename BasicJsonType, typename T>
1191  auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1192  noexcept(noexcept(from_json(j, val)))
1193  -> decltype(from_json(j, val), void())
1194  {
1195  return from_json(j, val);
1196  }
1197 
1198  template<typename BasicJsonType, typename T>
1199  void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1200  {
1201  static_assert(sizeof(BasicJsonType) == 0,
1202  "could not find from_json() method in T's namespace");
1203 #ifdef _MSC_VER
1204  // MSVC does not show a stacktrace for the above assert
1205  using decayed = uncvref_t<T>;
1206  static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1207  "forcing MSVC stacktrace to show which T we're talking about.");
1208 #endif
1209  }
1210 
1211  public:
1212  template<typename BasicJsonType, typename T>
1213  void operator()(const BasicJsonType& j, T& val) const
1214  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1215  {
1216  return call(j, val, priority_tag<1> {});
1217  }
1218 };
1219 }
1220 
1224 namespace
1225 {
1227 }
1228 }
1229 
1230 // #include <nlohmann/detail/conversions/to_json.hpp>
1231 
1232 
1233 #include <ciso646> // or, and, not
1234 #include <iterator> // begin, end
1235 #include <tuple> // tuple, get
1236 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1237 #include <utility> // move, forward, declval, pair
1238 #include <valarray> // valarray
1239 #include <vector> // vector
1240 
1241 // #include <nlohmann/detail/meta.hpp>
1242 
1243 // #include <nlohmann/detail/value_t.hpp>
1244 
1245 
1246 namespace nlohmann
1247 {
1248 namespace detail
1249 {
1251 // constructors //
1253 
1254 template<value_t> struct external_constructor;
1255 
1256 template<>
1258 {
1259  template<typename BasicJsonType>
1260  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1261  {
1262  j.m_type = value_t::boolean;
1263  j.m_value = b;
1264  j.assert_invariant();
1265  }
1266 };
1267 
1268 template<>
1270 {
1271  template<typename BasicJsonType>
1272  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1273  {
1274  j.m_type = value_t::string;
1275  j.m_value = s;
1276  j.assert_invariant();
1277  }
1278 
1279  template<typename BasicJsonType>
1280  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1281  {
1282  j.m_type = value_t::string;
1283  j.m_value = std::move(s);
1284  j.assert_invariant();
1285  }
1286 };
1287 
1288 template<>
1290 {
1291  template<typename BasicJsonType>
1292  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1293  {
1294  j.m_type = value_t::number_float;
1295  j.m_value = val;
1296  j.assert_invariant();
1297  }
1298 };
1299 
1300 template<>
1302 {
1303  template<typename BasicJsonType>
1304  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1305  {
1306  j.m_type = value_t::number_unsigned;
1307  j.m_value = val;
1308  j.assert_invariant();
1309  }
1310 };
1311 
1312 template<>
1314 {
1315  template<typename BasicJsonType>
1316  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1317  {
1318  j.m_type = value_t::number_integer;
1319  j.m_value = val;
1320  j.assert_invariant();
1321  }
1322 };
1323 
1324 template<>
1326 {
1327  template<typename BasicJsonType>
1328  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1329  {
1330  j.m_type = value_t::array;
1331  j.m_value = arr;
1332  j.assert_invariant();
1333  }
1334 
1335  template<typename BasicJsonType>
1336  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1337  {
1338  j.m_type = value_t::array;
1339  j.m_value = std::move(arr);
1340  j.assert_invariant();
1341  }
1342 
1343  template<typename BasicJsonType, typename CompatibleArrayType,
1345  int> = 0>
1346  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1347  {
1348  using std::begin;
1349  using std::end;
1350  j.m_type = value_t::array;
1351  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1352  j.assert_invariant();
1353  }
1354 
1355  template<typename BasicJsonType>
1356  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1357  {
1358  j.m_type = value_t::array;
1359  j.m_value = value_t::array;
1360  j.m_value.array->reserve(arr.size());
1361  for (const bool x : arr)
1362  {
1363  j.m_value.array->push_back(x);
1364  }
1365  j.assert_invariant();
1366  }
1367 
1368  template<typename BasicJsonType, typename T,
1370  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1371  {
1372  j.m_type = value_t::array;
1373  j.m_value = value_t::array;
1374  j.m_value.array->resize(arr.size());
1375  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1376  j.assert_invariant();
1377  }
1378 };
1379 
1380 template<>
1382 {
1383  template<typename BasicJsonType>
1384  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1385  {
1386  j.m_type = value_t::object;
1387  j.m_value = obj;
1388  j.assert_invariant();
1389  }
1390 
1391  template<typename BasicJsonType>
1392  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1393  {
1394  j.m_type = value_t::object;
1395  j.m_value = std::move(obj);
1396  j.assert_invariant();
1397  }
1398 
1399  template<typename BasicJsonType, typename CompatibleObjectType,
1401  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1402  {
1403  using std::begin;
1404  using std::end;
1405 
1406  j.m_type = value_t::object;
1407  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1408  j.assert_invariant();
1409  }
1410 };
1411 
1413 // to_json //
1415 
1416 template<typename BasicJsonType, typename T,
1418 void to_json(BasicJsonType& j, T b) noexcept
1419 {
1421 }
1422 
1423 template<typename BasicJsonType, typename CompatibleString,
1425 void to_json(BasicJsonType& j, const CompatibleString& s)
1426 {
1428 }
1429 
1430 template<typename BasicJsonType>
1431 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1432 {
1434 }
1435 
1436 template<typename BasicJsonType, typename FloatType,
1438 void to_json(BasicJsonType& j, FloatType val) noexcept
1439 {
1440  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1441 }
1442 
1443 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1445 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1446 {
1447  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1448 }
1449 
1450 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1452 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1453 {
1454  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1455 }
1456 
1457 template<typename BasicJsonType, typename EnumType,
1458  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1459 void to_json(BasicJsonType& j, EnumType e) noexcept
1460 {
1461  using underlying_type = typename std::underlying_type<EnumType>::type;
1462  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1463 }
1464 
1465 template<typename BasicJsonType>
1466 void to_json(BasicJsonType& j, const std::vector<bool>& e)
1467 {
1469 }
1470 
1471 template<typename BasicJsonType, typename CompatibleArrayType,
1473  std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1474  int> = 0>
1475 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1476 {
1478 }
1479 
1480 template<typename BasicJsonType, typename T,
1482 void to_json(BasicJsonType& j, std::valarray<T> arr)
1483 {
1485 }
1486 
1487 template<typename BasicJsonType>
1488 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1489 {
1491 }
1492 
1493 template<typename BasicJsonType, typename CompatibleObjectType,
1494  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1495 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1496 {
1498 }
1499 
1500 template<typename BasicJsonType>
1501 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1502 {
1504 }
1505 
1506 template<typename BasicJsonType, typename T, std::size_t N,
1508 void to_json(BasicJsonType& j, T (&arr)[N])
1509 {
1511 }
1512 
1513 template<typename BasicJsonType, typename... Args>
1514 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1515 {
1516  j = {p.first, p.second};
1517 }
1518 
1519 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1520 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1521 {
1522  j = {std::get<Idx>(t)...};
1523 }
1524 
1525 template<typename BasicJsonType, typename... Args>
1526 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1527 {
1529 }
1530 
1532 {
1533  private:
1534  template<typename BasicJsonType, typename T>
1535  auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1536  -> decltype(to_json(j, std::forward<T>(val)), void())
1537  {
1538  return to_json(j, std::forward<T>(val));
1539  }
1540 
1541  template<typename BasicJsonType, typename T>
1542  void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1543  {
1544  static_assert(sizeof(BasicJsonType) == 0,
1545  "could not find to_json() method in T's namespace");
1546 
1547 #ifdef _MSC_VER
1548  // MSVC does not show a stacktrace for the above assert
1549  using decayed = uncvref_t<T>;
1550  static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1551  "forcing MSVC stacktrace to show which T we're talking about.");
1552 #endif
1553  }
1554 
1555  public:
1556  template<typename BasicJsonType, typename T>
1557  void operator()(BasicJsonType& j, T&& val) const
1558  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1559  {
1560  return call(j, std::forward<T>(val), priority_tag<1> {});
1561  }
1562 };
1563 }
1564 
1566 namespace
1567 {
1569 }
1570 }
1571 
1572 // #include <nlohmann/detail/input/input_adapters.hpp>
1573 
1574 
1575 #include <algorithm> // min
1576 #include <array> // array
1577 #include <cassert> // assert
1578 #include <cstddef> // size_t
1579 #include <cstring> // strlen
1580 #include <ios> // streamsize, streamoff, streampos
1581 #include <istream> // istream
1582 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
1583 #include <memory> // shared_ptr, make_shared, addressof
1584 #include <numeric> // accumulate
1585 #include <string> // string, char_traits
1586 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
1587 #include <utility> // pair, declval
1588 
1589 // #include <nlohmann/detail/macro_scope.hpp>
1590 
1591 
1592 namespace nlohmann
1593 {
1594 namespace detail
1595 {
1597 // input adapters //
1599 
1612 {
1614  virtual std::char_traits<char>::int_type get_character() = 0;
1616  virtual void unget_character() = 0;
1617  virtual ~input_adapter_protocol() = default;
1618 };
1619 
1621 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1622 
1633 {
1634  public:
1636  {
1637  // clear stream flags; we use underlying streambuf I/O, do not
1638  // maintain ifstream flags
1639  is.clear();
1640  }
1641 
1642  explicit input_stream_adapter(std::istream& i)
1643  : is(i), sb(*i.rdbuf())
1644  {
1645  // skip byte order mark
1646  std::char_traits<char>::int_type c;
1647  if ((c = get_character()) == 0xEF)
1648  {
1649  if ((c = get_character()) == 0xBB)
1650  {
1651  if ((c = get_character()) == 0xBF)
1652  {
1653  return; // Ignore BOM
1654  }
1655  else if (c != std::char_traits<char>::eof())
1656  {
1657  is.unget();
1658  }
1659  is.putback('\xBB');
1660  }
1661  else if (c != std::char_traits<char>::eof())
1662  {
1663  is.unget();
1664  }
1665  is.putback('\xEF');
1666  }
1667  else if (c != std::char_traits<char>::eof())
1668  {
1669  is.unget(); // no byte order mark; process as usual
1670  }
1671  }
1672 
1673  // delete because of pointer members
1674  input_stream_adapter(const input_stream_adapter&) = delete;
1675  input_stream_adapter& operator=(input_stream_adapter&) = delete;
1676 
1677  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1678  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
1679  // end up as the same value, eg. 0xFFFFFFFF.
1680  std::char_traits<char>::int_type get_character() override
1681  {
1682  return sb.sbumpc();
1683  }
1684 
1685  void unget_character() override
1686  {
1687  sb.sungetc(); // is.unget() avoided for performance
1688  }
1689 
1690  private:
1692  std::istream& is;
1693  std::streambuf& sb;
1694 };
1695 
1698 {
1699  public:
1700  input_buffer_adapter(const char* b, const std::size_t l)
1701  : cursor(b), limit(b + l), start(b)
1702  {
1703  // skip byte order mark
1704  if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
1705  {
1706  cursor += 3;
1707  }
1708  }
1709 
1710  // delete because of pointer members
1711  input_buffer_adapter(const input_buffer_adapter&) = delete;
1712  input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1713 
1714  std::char_traits<char>::int_type get_character() noexcept override
1715  {
1716  if (JSON_LIKELY(cursor < limit))
1717  {
1718  return std::char_traits<char>::to_int_type(*(cursor++));
1719  }
1720 
1721  return std::char_traits<char>::eof();
1722  }
1723 
1724  void unget_character() noexcept override
1725  {
1726  if (JSON_LIKELY(cursor > start))
1727  {
1728  --cursor;
1729  }
1730  }
1731 
1732  private:
1734  const char* cursor;
1736  const char* limit;
1738  const char* start;
1739 };
1740 
1742 {
1743  public:
1744  // native support
1745 
1747  input_adapter(std::istream& i)
1748  : ia(std::make_shared<input_stream_adapter>(i)) {}
1749 
1751  input_adapter(std::istream&& i)
1752  : ia(std::make_shared<input_stream_adapter>(i)) {}
1753 
1755  template<typename CharT,
1756  typename std::enable_if<
1757  std::is_pointer<CharT>::value and
1758  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1759  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1760  int>::type = 0>
1761  input_adapter(CharT b, std::size_t l)
1762  : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1763 
1764  // derived support
1765 
1767  template<typename CharT,
1768  typename std::enable_if<
1769  std::is_pointer<CharT>::value and
1770  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
1771  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1772  int>::type = 0>
1773  input_adapter(CharT b)
1774  : input_adapter(reinterpret_cast<const char*>(b),
1775  std::strlen(reinterpret_cast<const char*>(b))) {}
1776 
1778  template<class IteratorType,
1779  typename std::enable_if<
1780  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
1781  int>::type = 0>
1782  input_adapter(IteratorType first, IteratorType last)
1783  {
1784  // assertion to check that the iterator range is indeed contiguous,
1785  // see http://stackoverflow.com/a/35008842/266378 for more discussion
1786  assert(std::accumulate(
1787  first, last, std::pair<bool, int>(true, 0),
1788  [&first](std::pair<bool, int> res, decltype(*first) val)
1789  {
1790  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1791  return res;
1792  }).first);
1793 
1794  // assertion to check that each element is 1 byte long
1795  static_assert(
1796  sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1797  "each element in the iterator range must have the size of 1 byte");
1798 
1799  const auto len = static_cast<size_t>(std::distance(first, last));
1800  if (JSON_LIKELY(len > 0))
1801  {
1802  // there is at least one element: use the address of first
1803  ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
1804  }
1805  else
1806  {
1807  // the address of first cannot be used: use nullptr
1808  ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1809  }
1810  }
1811 
1813  template<class T, std::size_t N>
1815  : input_adapter(std::begin(array), std::end(array)) {}
1816 
1818  template<class ContiguousContainer, typename
1819  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
1820  std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1821  int>::type = 0>
1822  input_adapter(const ContiguousContainer& c)
1823  : input_adapter(std::begin(c), std::end(c)) {}
1824 
1825  operator input_adapter_t()
1826  {
1827  return ia;
1828  }
1829 
1830  private:
1832  input_adapter_t ia = nullptr;
1833 };
1834 }
1835 }
1836 
1837 // #include <nlohmann/detail/input/lexer.hpp>
1838 
1839 
1840 #include <clocale> // localeconv
1841 #include <cstddef> // size_t
1842 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
1843 #include <initializer_list> // initializer_list
1844 #include <ios> // hex, uppercase
1845 #include <iomanip> // setw, setfill
1846 #include <sstream> // stringstream
1847 #include <string> // char_traits, string
1848 #include <vector> // vector
1849 
1850 // #include <nlohmann/detail/macro_scope.hpp>
1851 
1852 // #include <nlohmann/detail/input/input_adapters.hpp>
1853 
1854 
1855 namespace nlohmann
1856 {
1857 namespace detail
1858 {
1860 // lexer //
1862 
1868 template<typename BasicJsonType>
1869 class lexer
1870 {
1871  using number_integer_t = typename BasicJsonType::number_integer_t;
1872  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1873  using number_float_t = typename BasicJsonType::number_float_t;
1874  using string_t = typename BasicJsonType::string_t;
1875 
1876  public:
1878  enum class token_type
1879  {
1880  uninitialized,
1881  literal_true,
1882  literal_false,
1883  literal_null,
1884  value_string,
1885  value_unsigned,
1886  value_integer,
1887  value_float,
1888  begin_array,
1889  begin_object,
1890  end_array,
1891  end_object,
1892  name_separator,
1893  value_separator,
1894  parse_error,
1895  end_of_input,
1896  literal_or_value
1897  };
1898 
1900  static const char* token_type_name(const token_type t) noexcept
1901  {
1902  switch (t)
1903  {
1904  case token_type::uninitialized:
1905  return "<uninitialized>";
1906  case token_type::literal_true:
1907  return "true literal";
1908  case token_type::literal_false:
1909  return "false literal";
1910  case token_type::literal_null:
1911  return "null literal";
1912  case token_type::value_string:
1913  return "string literal";
1917  return "number literal";
1918  case token_type::begin_array:
1919  return "'['";
1920  case token_type::begin_object:
1921  return "'{'";
1922  case token_type::end_array:
1923  return "']'";
1924  case token_type::end_object:
1925  return "'}'";
1926  case token_type::name_separator:
1927  return "':'";
1928  case token_type::value_separator:
1929  return "','";
1930  case token_type::parse_error:
1931  return "<parse error>";
1932  case token_type::end_of_input:
1933  return "end of input";
1934  case token_type::literal_or_value:
1935  return "'[', '{', or a literal";
1936  default: // catch non-enum values
1937  return "unknown token"; // LCOV_EXCL_LINE
1938  }
1939  }
1940 
1941  explicit lexer(detail::input_adapter_t adapter)
1942  : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1943 
1944  // delete because of pointer members
1945  lexer(const lexer&) = delete;
1946  lexer& operator=(lexer&) = delete;
1947 
1948  private:
1950  // locales
1952 
1954  static char get_decimal_point() noexcept
1955  {
1956  const auto loc = localeconv();
1957  assert(loc != nullptr);
1958  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
1959  }
1960 
1962  // scan functions
1964 
1981  {
1982  // this function only makes sense after reading `\u`
1983  assert(current == 'u');
1984  int codepoint = 0;
1985 
1986  const auto factors = { 12, 8, 4, 0 };
1987  for (const auto factor : factors)
1988  {
1989  get();
1990 
1991  if (current >= '0' and current <= '9')
1992  {
1993  codepoint += ((current - 0x30) << factor);
1994  }
1995  else if (current >= 'A' and current <= 'F')
1996  {
1997  codepoint += ((current - 0x37) << factor);
1998  }
1999  else if (current >= 'a' and current <= 'f')
2000  {
2001  codepoint += ((current - 0x57) << factor);
2002  }
2003  else
2004  {
2005  return -1;
2006  }
2007  }
2008 
2009  assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2010  return codepoint;
2011  }
2012 
2028  bool next_byte_in_range(std::initializer_list<int> ranges)
2029  {
2030  assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2031  add(current);
2032 
2033  for (auto range = ranges.begin(); range != ranges.end(); ++range)
2034  {
2035  get();
2036  if (JSON_LIKELY(*range <= current and current <= *(++range)))
2037  {
2038  add(current);
2039  }
2040  else
2041  {
2042  error_message = "invalid string: ill-formed UTF-8 byte";
2043  return false;
2044  }
2045  }
2046 
2047  return true;
2048  }
2049 
2066  {
2067  // reset token_buffer (ignore opening quote)
2068  reset();
2069 
2070  // we entered the function by reading an open quote
2071  assert(current == '\"');
2072 
2073  while (true)
2074  {
2075  // get next character
2076  switch (get())
2077  {
2078  // end of file while parsing string
2079  case std::char_traits<char>::eof():
2080  {
2081  error_message = "invalid string: missing closing quote";
2082  return token_type::parse_error;
2083  }
2084 
2085  // closing quote
2086  case '\"':
2087  {
2088  return token_type::value_string;
2089  }
2090 
2091  // escapes
2092  case '\\':
2093  {
2094  switch (get())
2095  {
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  {
2137  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2138  return token_type::parse_error;
2139  }
2140 
2141  // check if code point is a high surrogate
2142  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2143  {
2144  // expect next \uxxxx entry
2145  if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2146  {
2147  const int codepoint2 = get_codepoint();
2148 
2149  if (JSON_UNLIKELY(codepoint2 == -1))
2150  {
2151  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2152  return token_type::parse_error;
2153  }
2154 
2155  // check if codepoint2 is a low surrogate
2156  if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2157  {
2158  // overwrite codepoint
2159  codepoint =
2160  // high surrogate occupies the most significant 22 bits
2161  (codepoint1 << 10)
2162  // low surrogate occupies the least significant 15 bits
2163  + codepoint2
2164  // there is still the 0xD800, 0xDC00 and 0x10000 noise
2165  // in the result so we have to subtract with:
2166  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2167  - 0x35FDC00;
2168  }
2169  else
2170  {
2171  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2172  return token_type::parse_error;
2173  }
2174  }
2175  else
2176  {
2177  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2178  return token_type::parse_error;
2179  }
2180  }
2181  else
2182  {
2183  if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2184  {
2185  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2186  return token_type::parse_error;
2187  }
2188  }
2189 
2190  // result of the above calculation yields a proper codepoint
2191  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2192 
2193  // translate codepoint into bytes
2194  if (codepoint < 0x80)
2195  {
2196  // 1-byte characters: 0xxxxxxx (ASCII)
2197  add(codepoint);
2198  }
2199  else if (codepoint <= 0x7FF)
2200  {
2201  // 2-byte characters: 110xxxxx 10xxxxxx
2202  add(0xC0 | (codepoint >> 6));
2203  add(0x80 | (codepoint & 0x3F));
2204  }
2205  else if (codepoint <= 0xFFFF)
2206  {
2207  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2208  add(0xE0 | (codepoint >> 12));
2209  add(0x80 | ((codepoint >> 6) & 0x3F));
2210  add(0x80 | (codepoint & 0x3F));
2211  }
2212  else
2213  {
2214  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2215  add(0xF0 | (codepoint >> 18));
2216  add(0x80 | ((codepoint >> 12) & 0x3F));
2217  add(0x80 | ((codepoint >> 6) & 0x3F));
2218  add(0x80 | (codepoint & 0x3F));
2219  }
2220 
2221  break;
2222  }
2223 
2224  // other characters after escape
2225  default:
2226  error_message = "invalid string: forbidden character after backslash";
2227  return token_type::parse_error;
2228  }
2229 
2230  break;
2231  }
2232 
2233  // invalid control characters
2234  case 0x00:
2235  case 0x01:
2236  case 0x02:
2237  case 0x03:
2238  case 0x04:
2239  case 0x05:
2240  case 0x06:
2241  case 0x07:
2242  case 0x08:
2243  case 0x09:
2244  case 0x0A:
2245  case 0x0B:
2246  case 0x0C:
2247  case 0x0D:
2248  case 0x0E:
2249  case 0x0F:
2250  case 0x10:
2251  case 0x11:
2252  case 0x12:
2253  case 0x13:
2254  case 0x14:
2255  case 0x15:
2256  case 0x16:
2257  case 0x17:
2258  case 0x18:
2259  case 0x19:
2260  case 0x1A:
2261  case 0x1B:
2262  case 0x1C:
2263  case 0x1D:
2264  case 0x1E:
2265  case 0x1F:
2266  {
2267  error_message = "invalid string: control character must be escaped";
2268  return token_type::parse_error;
2269  }
2270 
2271  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2272  case 0x20:
2273  case 0x21:
2274  case 0x23:
2275  case 0x24:
2276  case 0x25:
2277  case 0x26:
2278  case 0x27:
2279  case 0x28:
2280  case 0x29:
2281  case 0x2A:
2282  case 0x2B:
2283  case 0x2C:
2284  case 0x2D:
2285  case 0x2E:
2286  case 0x2F:
2287  case 0x30:
2288  case 0x31:
2289  case 0x32:
2290  case 0x33:
2291  case 0x34:
2292  case 0x35:
2293  case 0x36:
2294  case 0x37:
2295  case 0x38:
2296  case 0x39:
2297  case 0x3A:
2298  case 0x3B:
2299  case 0x3C:
2300  case 0x3D:
2301  case 0x3E:
2302  case 0x3F:
2303  case 0x40:
2304  case 0x41:
2305  case 0x42:
2306  case 0x43:
2307  case 0x44:
2308  case 0x45:
2309  case 0x46:
2310  case 0x47:
2311  case 0x48:
2312  case 0x49:
2313  case 0x4A:
2314  case 0x4B:
2315  case 0x4C:
2316  case 0x4D:
2317  case 0x4E:
2318  case 0x4F:
2319  case 0x50:
2320  case 0x51:
2321  case 0x52:
2322  case 0x53:
2323  case 0x54:
2324  case 0x55:
2325  case 0x56:
2326  case 0x57:
2327  case 0x58:
2328  case 0x59:
2329  case 0x5A:
2330  case 0x5B:
2331  case 0x5D:
2332  case 0x5E:
2333  case 0x5F:
2334  case 0x60:
2335  case 0x61:
2336  case 0x62:
2337  case 0x63:
2338  case 0x64:
2339  case 0x65:
2340  case 0x66:
2341  case 0x67:
2342  case 0x68:
2343  case 0x69:
2344  case 0x6A:
2345  case 0x6B:
2346  case 0x6C:
2347  case 0x6D:
2348  case 0x6E:
2349  case 0x6F:
2350  case 0x70:
2351  case 0x71:
2352  case 0x72:
2353  case 0x73:
2354  case 0x74:
2355  case 0x75:
2356  case 0x76:
2357  case 0x77:
2358  case 0x78:
2359  case 0x79:
2360  case 0x7A:
2361  case 0x7B:
2362  case 0x7C:
2363  case 0x7D:
2364  case 0x7E:
2365  case 0x7F:
2366  {
2367  add(current);
2368  break;
2369  }
2370 
2371  // U+0080..U+07FF: bytes C2..DF 80..BF
2372  case 0xC2:
2373  case 0xC3:
2374  case 0xC4:
2375  case 0xC5:
2376  case 0xC6:
2377  case 0xC7:
2378  case 0xC8:
2379  case 0xC9:
2380  case 0xCA:
2381  case 0xCB:
2382  case 0xCC:
2383  case 0xCD:
2384  case 0xCE:
2385  case 0xCF:
2386  case 0xD0:
2387  case 0xD1:
2388  case 0xD2:
2389  case 0xD3:
2390  case 0xD4:
2391  case 0xD5:
2392  case 0xD6:
2393  case 0xD7:
2394  case 0xD8:
2395  case 0xD9:
2396  case 0xDA:
2397  case 0xDB:
2398  case 0xDC:
2399  case 0xDD:
2400  case 0xDE:
2401  case 0xDF:
2402  {
2403  if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2404  {
2405  return token_type::parse_error;
2406  }
2407  break;
2408  }
2409 
2410  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2411  case 0xE0:
2412  {
2413  if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2414  {
2415  return token_type::parse_error;
2416  }
2417  break;
2418  }
2419 
2420  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2421  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2422  case 0xE1:
2423  case 0xE2:
2424  case 0xE3:
2425  case 0xE4:
2426  case 0xE5:
2427  case 0xE6:
2428  case 0xE7:
2429  case 0xE8:
2430  case 0xE9:
2431  case 0xEA:
2432  case 0xEB:
2433  case 0xEC:
2434  case 0xEE:
2435  case 0xEF:
2436  {
2437  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2438  {
2439  return token_type::parse_error;
2440  }
2441  break;
2442  }
2443 
2444  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2445  case 0xED:
2446  {
2447  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2448  {
2449  return token_type::parse_error;
2450  }
2451  break;
2452  }
2453 
2454  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2455  case 0xF0:
2456  {
2457  if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2458  {
2459  return token_type::parse_error;
2460  }
2461  break;
2462  }
2463 
2464  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2465  case 0xF1:
2466  case 0xF2:
2467  case 0xF3:
2468  {
2469  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2470  {
2471  return token_type::parse_error;
2472  }
2473  break;
2474  }
2475 
2476  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2477  case 0xF4:
2478  {
2479  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2480  {
2481  return token_type::parse_error;
2482  }
2483  break;
2484  }
2485 
2486  // remaining bytes (80..C1 and F5..FF) are ill-formed
2487  default:
2488  {
2489  error_message = "invalid string: ill-formed UTF-8 byte";
2490  return token_type::parse_error;
2491  }
2492  }
2493  }
2494  }
2495 
2496  static void strtof(float& f, const char* str, char** endptr) noexcept
2497  {
2498  f = std::strtof(str, endptr);
2499  }
2500 
2501  static void strtof(double& f, const char* str, char** endptr) noexcept
2502  {
2503  f = std::strtod(str, endptr);
2504  }
2505 
2506  static void strtof(long double& f, const char* str, char** endptr) noexcept
2507  {
2508  f = std::strtold(str, endptr);
2509  }
2510 
2552  {
2553  // reset token_buffer to store the number's bytes
2554  reset();
2555 
2556  // the type of the parsed number; initially set to unsigned; will be
2557  // changed if minus sign, decimal point or exponent is read
2558  token_type number_type = token_type::value_unsigned;
2559 
2560  // state (init): we just found out we need to scan a number
2561  switch (current)
2562  {
2563  case '-':
2564  {
2565  add(current);
2566  goto scan_number_minus;
2567  }
2568 
2569  case '0':
2570  {
2571  add(current);
2572  goto scan_number_zero;
2573  }
2574 
2575  case '1':
2576  case '2':
2577  case '3':
2578  case '4':
2579  case '5':
2580  case '6':
2581  case '7':
2582  case '8':
2583  case '9':
2584  {
2585  add(current);
2586  goto scan_number_any1;
2587  }
2588 
2589  default:
2590  {
2591  // all other characters are rejected outside scan_number()
2592  assert(false); // LCOV_EXCL_LINE
2593  }
2594  }
2595 
2596 scan_number_minus:
2597  // state: we just parsed a leading minus sign
2598  number_type = token_type::value_integer;
2599  switch (get())
2600  {
2601  case '0':
2602  {
2603  add(current);
2604  goto scan_number_zero;
2605  }
2606 
2607  case '1':
2608  case '2':
2609  case '3':
2610  case '4':
2611  case '5':
2612  case '6':
2613  case '7':
2614  case '8':
2615  case '9':
2616  {
2617  add(current);
2618  goto scan_number_any1;
2619  }
2620 
2621  default:
2622  {
2623  error_message = "invalid number; expected digit after '-'";
2624  return token_type::parse_error;
2625  }
2626  }
2627 
2628 scan_number_zero:
2629  // state: we just parse a zero (maybe with a leading minus sign)
2630  switch (get())
2631  {
2632  case '.':
2633  {
2634  add(decimal_point_char);
2635  goto scan_number_decimal1;
2636  }
2637 
2638  case 'e':
2639  case 'E':
2640  {
2641  add(current);
2642  goto scan_number_exponent;
2643  }
2644 
2645  default:
2646  goto scan_number_done;
2647  }
2648 
2649 scan_number_any1:
2650  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2651  switch (get())
2652  {
2653  case '0':
2654  case '1':
2655  case '2':
2656  case '3':
2657  case '4':
2658  case '5':
2659  case '6':
2660  case '7':
2661  case '8':
2662  case '9':
2663  {
2664  add(current);
2665  goto scan_number_any1;
2666  }
2667 
2668  case '.':
2669  {
2670  add(decimal_point_char);
2671  goto scan_number_decimal1;
2672  }
2673 
2674  case 'e':
2675  case 'E':
2676  {
2677  add(current);
2678  goto scan_number_exponent;
2679  }
2680 
2681  default:
2682  goto scan_number_done;
2683  }
2684 
2685 scan_number_decimal1:
2686  // state: we just parsed a decimal point
2687  number_type = token_type::value_float;
2688  switch (get())
2689  {
2690  case '0':
2691  case '1':
2692  case '2':
2693  case '3':
2694  case '4':
2695  case '5':
2696  case '6':
2697  case '7':
2698  case '8':
2699  case '9':
2700  {
2701  add(current);
2702  goto scan_number_decimal2;
2703  }
2704 
2705  default:
2706  {
2707  error_message = "invalid number; expected digit after '.'";
2708  return token_type::parse_error;
2709  }
2710  }
2711 
2712 scan_number_decimal2:
2713  // we just parsed at least one number after a decimal point
2714  switch (get())
2715  {
2716  case '0':
2717  case '1':
2718  case '2':
2719  case '3':
2720  case '4':
2721  case '5':
2722  case '6':
2723  case '7':
2724  case '8':
2725  case '9':
2726  {
2727  add(current);
2728  goto scan_number_decimal2;
2729  }
2730 
2731  case 'e':
2732  case 'E':
2733  {
2734  add(current);
2735  goto scan_number_exponent;
2736  }
2737 
2738  default:
2739  goto scan_number_done;
2740  }
2741 
2742 scan_number_exponent:
2743  // we just parsed an exponent
2744  number_type = token_type::value_float;
2745  switch (get())
2746  {
2747  case '+':
2748  case '-':
2749  {
2750  add(current);
2751  goto scan_number_sign;
2752  }
2753 
2754  case '0':
2755  case '1':
2756  case '2':
2757  case '3':
2758  case '4':
2759  case '5':
2760  case '6':
2761  case '7':
2762  case '8':
2763  case '9':
2764  {
2765  add(current);
2766  goto scan_number_any2;
2767  }
2768 
2769  default:
2770  {
2771  error_message =
2772  "invalid number; expected '+', '-', or digit after exponent";
2773  return token_type::parse_error;
2774  }
2775  }
2776 
2777 scan_number_sign:
2778  // we just parsed an exponent sign
2779  switch (get())
2780  {
2781  case '0':
2782  case '1':
2783  case '2':
2784  case '3':
2785  case '4':
2786  case '5':
2787  case '6':
2788  case '7':
2789  case '8':
2790  case '9':
2791  {
2792  add(current);
2793  goto scan_number_any2;
2794  }
2795 
2796  default:
2797  {
2798  error_message = "invalid number; expected digit after exponent sign";
2799  return token_type::parse_error;
2800  }
2801  }
2802 
2803 scan_number_any2:
2804  // we just parsed a number after the exponent or exponent sign
2805  switch (get())
2806  {
2807  case '0':
2808  case '1':
2809  case '2':
2810  case '3':
2811  case '4':
2812  case '5':
2813  case '6':
2814  case '7':
2815  case '8':
2816  case '9':
2817  {
2818  add(current);
2819  goto scan_number_any2;
2820  }
2821 
2822  default:
2823  goto scan_number_done;
2824  }
2825 
2826 scan_number_done:
2827  // unget the character after the number (we only read it to know that
2828  // we are done scanning a number)
2829  unget();
2830 
2831  char* endptr = nullptr;
2832  errno = 0;
2833 
2834  // try to parse integers first and fall back to floats
2835  if (number_type == token_type::value_unsigned)
2836  {
2837  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
2838 
2839  // we checked the number format before
2840  assert(endptr == token_buffer.data() + token_buffer.size());
2841 
2842  if (errno == 0)
2843  {
2844  value_unsigned = static_cast<number_unsigned_t>(x);
2845  if (value_unsigned == x)
2846  {
2847  return token_type::value_unsigned;
2848  }
2849  }
2850  }
2851  else if (number_type == token_type::value_integer)
2852  {
2853  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
2854 
2855  // we checked the number format before
2856  assert(endptr == token_buffer.data() + token_buffer.size());
2857 
2858  if (errno == 0)
2859  {
2860  value_integer = static_cast<number_integer_t>(x);
2861  if (value_integer == x)
2862  {
2863  return token_type::value_integer;
2864  }
2865  }
2866  }
2867 
2868  // this code is reached if we parse a floating-point number or if an
2869  // integer conversion above failed
2870  strtof(value_float, token_buffer.data(), &endptr);
2871 
2872  // we checked the number format before
2873  assert(endptr == token_buffer.data() + token_buffer.size());
2874 
2875  return token_type::value_float;
2876  }
2877 
2883  token_type scan_literal(const char* literal_text, const std::size_t length,
2884  token_type return_type)
2885  {
2886  assert(current == literal_text[0]);
2887  for (std::size_t i = 1; i < length; ++i)
2888  {
2889  if (JSON_UNLIKELY(get() != literal_text[i]))
2890  {
2891  error_message = "invalid literal";
2892  return token_type::parse_error;
2893  }
2894  }
2895  return return_type;
2896  }
2897 
2899  // input management
2901 
2903  void reset() noexcept
2904  {
2905  token_buffer.clear();
2906  token_string.clear();
2907  token_string.push_back(std::char_traits<char>::to_char_type(current));
2908  }
2909 
2910  /*
2911  @brief get next character from the input
2912 
2913  This function provides the interface to the used input adapter. It does
2914  not throw in case the input reached EOF, but returns a
2915  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
2916  for use in error messages.
2917 
2918  @return character read from the input
2919  */
2920  std::char_traits<char>::int_type get()
2921  {
2922  ++chars_read;
2923  current = ia->get_character();
2924  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2925  {
2926  token_string.push_back(std::char_traits<char>::to_char_type(current));
2927  }
2928  return current;
2929  }
2930 
2932  void unget()
2933  {
2934  --chars_read;
2935  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2936  {
2937  ia->unget_character();
2938  assert(token_string.size() != 0);
2939  token_string.pop_back();
2940  }
2941  }
2942 
2944  void add(int c)
2945  {
2946  token_buffer.push_back(std::char_traits<char>::to_char_type(c));
2947  }
2948 
2949  public:
2951  // value getters
2953 
2955  constexpr number_integer_t get_number_integer() const noexcept
2956  {
2957  return value_integer;
2958  }
2959 
2961  constexpr number_unsigned_t get_number_unsigned() const noexcept
2962  {
2963  return value_unsigned;
2964  }
2965 
2967  constexpr number_float_t get_number_float() const noexcept
2968  {
2969  return value_float;
2970  }
2971 
2974  {
2975  return std::move(token_buffer);
2976  }
2977 
2979  // diagnostics
2981 
2983  constexpr std::size_t get_position() const noexcept
2984  {
2985  return chars_read;
2986  }
2987 
2992  {
2993  // escape control characters
2994  std::string result;
2995  for (const auto c : token_string)
2996  {
2997  if ('\x00' <= c and c <= '\x1F')
2998  {
2999  // escape control characters
3000  std::stringstream ss;
3001  ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
3002  << std::hex << static_cast<int>(c) << ">";
3003  result += ss.str();
3004  }
3005  else
3006  {
3007  // add character as is
3008  result.push_back(c);
3009  }
3010  }
3011 
3012  return result;
3013  }
3014 
3016  constexpr const char* get_error_message() const noexcept
3017  {
3018  return error_message;
3019  }
3020 
3022  // actual scanner
3024 
3026  {
3027  // read next character and ignore whitespace
3028  do
3029  {
3030  get();
3031  }
3032  while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3033 
3034  switch (current)
3035  {
3036  // structural characters
3037  case '[':
3038  return token_type::begin_array;
3039  case ']':
3040  return token_type::end_array;
3041  case '{':
3042  return token_type::begin_object;
3043  case '}':
3044  return token_type::end_object;
3045  case ':':
3046  return token_type::name_separator;
3047  case ',':
3048  return token_type::value_separator;
3049 
3050  // literals
3051  case 't':
3052  return scan_literal("true", 4, token_type::literal_true);
3053  case 'f':
3054  return scan_literal("false", 5, token_type::literal_false);
3055  case 'n':
3056  return scan_literal("null", 4, token_type::literal_null);
3057 
3058  // string
3059  case '\"':
3060  return scan_string();
3061 
3062  // number
3063  case '-':
3064  case '0':
3065  case '1':
3066  case '2':
3067  case '3':
3068  case '4':
3069  case '5':
3070  case '6':
3071  case '7':
3072  case '8':
3073  case '9':
3074  return scan_number();
3075 
3076  // end of input (the null byte is needed when parsing from
3077  // string literals)
3078  case '\0':
3079  case std::char_traits<char>::eof():
3080  return token_type::end_of_input;
3081 
3082  // error
3083  default:
3084  error_message = "invalid literal";
3085  return token_type::parse_error;
3086  }
3087  }
3088 
3089  private:
3092 
3094  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3095 
3097  std::size_t chars_read = 0;
3098 
3100  std::vector<char> token_string {};
3101 
3103  string_t token_buffer {};
3104 
3106  const char* error_message = "";
3107 
3108  // number values
3109  number_integer_t value_integer = 0;
3110  number_unsigned_t value_unsigned = 0;
3111  number_float_t value_float = 0;
3112 
3114  const char decimal_point_char = '.';
3115 };
3116 }
3117 }
3118 
3119 // #include <nlohmann/detail/input/parser.hpp>
3120 
3121 
3122 #include <cassert> // assert
3123 #include <cmath> // isfinite
3124 #include <cstdint> // uint8_t
3125 #include <functional> // function
3126 #include <string> // string
3127 #include <utility> // move
3128 
3129 // #include <nlohmann/detail/exceptions.hpp>
3130 
3131 // #include <nlohmann/detail/macro_scope.hpp>
3132 
3133 // #include <nlohmann/detail/input/input_adapters.hpp>
3134 
3135 // #include <nlohmann/detail/input/lexer.hpp>
3136 
3137 // #include <nlohmann/detail/value_t.hpp>
3138 
3139 
3140 namespace nlohmann
3141 {
3142 namespace detail
3143 {
3145 // parser //
3147 
3153 template<typename BasicJsonType>
3154 class parser
3155 {
3156  using number_integer_t = typename BasicJsonType::number_integer_t;
3157  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3158  using number_float_t = typename BasicJsonType::number_float_t;
3159  using string_t = typename BasicJsonType::string_t;
3162 
3163  public:
3164  enum class parse_event_t : uint8_t
3165  {
3167  object_start,
3169  object_end,
3171  array_start,
3173  array_end,
3175  key,
3177  value
3178  };
3179 
3180  using parser_callback_t =
3181  std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
3182 
3185  const parser_callback_t cb = nullptr,
3186  const bool allow_exceptions_ = true)
3187  : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
3188  {}
3189 
3200  void parse(const bool strict, BasicJsonType& result)
3201  {
3202  // read first token
3203  get_token();
3204 
3205  parse_internal(true, result);
3206  result.assert_invariant();
3207 
3208  // in strict mode, input must be completely read
3209  if (strict)
3210  {
3211  get_token();
3212  expect(token_type::end_of_input);
3213  }
3214 
3215  // in case of an error, return discarded value
3216  if (errored)
3217  {
3218  result = value_t::discarded;
3219  return;
3220  }
3221 
3222  // set top-level value to null if it was discarded by the callback
3223  // function
3224  if (result.is_discarded())
3225  {
3226  result = nullptr;
3227  }
3228  }
3229 
3236  bool accept(const bool strict = true)
3237  {
3238  // read first token
3239  get_token();
3240 
3241  if (not accept_internal())
3242  {
3243  return false;
3244  }
3245 
3246  // strict => last token must be EOF
3247  return not strict or (get_token() == token_type::end_of_input);
3248  }
3249 
3250  private:
3257  void parse_internal(bool keep, BasicJsonType& result)
3258  {
3259  // never parse after a parse error was detected
3260  assert(not errored);
3261 
3262  // start with a discarded value
3263  if (not result.is_discarded())
3264  {
3265  result.m_value.destroy(result.m_type);
3266  result.m_type = value_t::discarded;
3267  }
3268 
3269  switch (last_token)
3270  {
3271  case token_type::begin_object:
3272  {
3273  if (keep)
3274  {
3275  if (callback)
3276  {
3277  keep = callback(depth++, parse_event_t::object_start, result);
3278  }
3279 
3280  if (not callback or keep)
3281  {
3282  // explicitly set result to object to cope with {}
3283  result.m_type = value_t::object;
3284  result.m_value = value_t::object;
3285  }
3286  }
3287 
3288  // read next token
3289  get_token();
3290 
3291  // closing } -> we are done
3292  if (last_token == token_type::end_object)
3293  {
3294  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3295  {
3296  result.m_value.destroy(result.m_type);
3297  result.m_type = value_t::discarded;
3298  }
3299  break;
3300  }
3301 
3302  // parse values
3303  string_t key;
3304  BasicJsonType value;
3305  while (true)
3306  {
3307  // store key
3308  if (not expect(token_type::value_string))
3309  {
3310  return;
3311  }
3312  key = m_lexer.move_string();
3313 
3314  bool keep_tag = false;
3315  if (keep)
3316  {
3317  if (callback)
3318  {
3319  BasicJsonType k(key);
3320  keep_tag = callback(depth, parse_event_t::key, k);
3321  }
3322  else
3323  {
3324  keep_tag = true;
3325  }
3326  }
3327 
3328  // parse separator (:)
3329  get_token();
3330  if (not expect(token_type::name_separator))
3331  {
3332  return;
3333  }
3334 
3335  // parse and add value
3336  get_token();
3337  value.m_value.destroy(value.m_type);
3338  value.m_type = value_t::discarded;
3339  parse_internal(keep, value);
3340 
3341  if (JSON_UNLIKELY(errored))
3342  {
3343  return;
3344  }
3345 
3346  if (keep and keep_tag and not value.is_discarded())
3347  {
3348  result.m_value.object->emplace(std::move(key), std::move(value));
3349  }
3350 
3351  // comma -> next value
3352  get_token();
3353  if (last_token == token_type::value_separator)
3354  {
3355  get_token();
3356  continue;
3357  }
3358 
3359  // closing }
3360  if (not expect(token_type::end_object))
3361  {
3362  return;
3363  }
3364  break;
3365  }
3366 
3367  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3368  {
3369  result.m_value.destroy(result.m_type);
3370  result.m_type = value_t::discarded;
3371  }
3372  break;
3373  }
3374 
3375  case token_type::begin_array:
3376  {
3377  if (keep)
3378  {
3379  if (callback)
3380  {
3381  keep = callback(depth++, parse_event_t::array_start, result);
3382  }
3383 
3384  if (not callback or keep)
3385  {
3386  // explicitly set result to array to cope with []
3387  result.m_type = value_t::array;
3388  result.m_value = value_t::array;
3389  }
3390  }
3391 
3392  // read next token
3393  get_token();
3394 
3395  // closing ] -> we are done
3396  if (last_token == token_type::end_array)
3397  {
3398  if (callback and not callback(--depth, parse_event_t::array_end, result))
3399  {
3400  result.m_value.destroy(result.m_type);
3401  result.m_type = value_t::discarded;
3402  }
3403  break;
3404  }
3405 
3406  // parse values
3407  BasicJsonType value;
3408  while (true)
3409  {
3410  // parse value
3411  value.m_value.destroy(value.m_type);
3412  value.m_type = value_t::discarded;
3413  parse_internal(keep, value);
3414 
3415  if (JSON_UNLIKELY(errored))
3416  {
3417  return;
3418  }
3419 
3420  if (keep and not value.is_discarded())
3421  {
3422  result.m_value.array->push_back(std::move(value));
3423  }
3424 
3425  // comma -> next value
3426  get_token();
3427  if (last_token == token_type::value_separator)
3428  {
3429  get_token();
3430  continue;
3431  }
3432 
3433  // closing ]
3434  if (not expect(token_type::end_array))
3435  {
3436  return;
3437  }
3438  break;
3439  }
3440 
3441  if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3442  {
3443  result.m_value.destroy(result.m_type);
3444  result.m_type = value_t::discarded;
3445  }
3446  break;
3447  }
3448 
3449  case token_type::literal_null:
3450  {
3451  result.m_type = value_t::null;
3452  break;
3453  }
3454 
3455  case token_type::value_string:
3456  {
3457  result.m_type = value_t::string;
3458  result.m_value = m_lexer.move_string();
3459  break;
3460  }
3461 
3462  case token_type::literal_true:
3463  {
3464  result.m_type = value_t::boolean;
3465  result.m_value = true;
3466  break;
3467  }
3468 
3469  case token_type::literal_false:
3470  {
3471  result.m_type = value_t::boolean;
3472  result.m_value = false;
3473  break;
3474  }
3475 
3476  case token_type::value_unsigned:
3477  {
3478  result.m_type = value_t::number_unsigned;
3479  result.m_value = m_lexer.get_number_unsigned();
3480  break;
3481  }
3482 
3483  case token_type::value_integer:
3484  {
3485  result.m_type = value_t::number_integer;
3486  result.m_value = m_lexer.get_number_integer();
3487  break;
3488  }
3489 
3490  case token_type::value_float:
3491  {
3492  result.m_type = value_t::number_float;
3493  result.m_value = m_lexer.get_number_float();
3494 
3495  // throw in case of infinity or NAN
3496  if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3497  {
3498  if (allow_exceptions)
3499  {
3500  JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3501  m_lexer.get_token_string() + "'"));
3502  }
3503  expect(token_type::uninitialized);
3504  }
3505  break;
3506  }
3507 
3508  case token_type::parse_error:
3509  {
3510  // using "uninitialized" to avoid "expected" message
3511  if (not expect(token_type::uninitialized))
3512  {
3513  return;
3514  }
3515  break; // LCOV_EXCL_LINE
3516  }
3517 
3518  default:
3519  {
3520  // the last token was unexpected; we expected a value
3521  if (not expect(token_type::literal_or_value))
3522  {
3523  return;
3524  }
3525  break; // LCOV_EXCL_LINE
3526  }
3527  }
3528 
3529  if (keep and callback and not callback(depth, parse_event_t::value, result))
3530  {
3531  result.m_value.destroy(result.m_type);
3532  result.m_type = value_t::discarded;
3533  }
3534  }
3535 
3547  {
3548  switch (last_token)
3549  {
3550  case token_type::begin_object:
3551  {
3552  // read next token
3553  get_token();
3554 
3555  // closing } -> we are done
3556  if (last_token == token_type::end_object)
3557  {
3558  return true;
3559  }
3560 
3561  // parse values
3562  while (true)
3563  {
3564  // parse key
3565  if (last_token != token_type::value_string)
3566  {
3567  return false;
3568  }
3569 
3570  // parse separator (:)
3571  get_token();
3572  if (last_token != token_type::name_separator)
3573  {
3574  return false;
3575  }
3576 
3577  // parse value
3578  get_token();
3579  if (not accept_internal())
3580  {
3581  return false;
3582  }
3583 
3584  // comma -> next value
3585  get_token();
3586  if (last_token == token_type::value_separator)
3587  {
3588  get_token();
3589  continue;
3590  }
3591 
3592  // closing }
3593  return (last_token == token_type::end_object);
3594  }
3595  }
3596 
3597  case token_type::begin_array:
3598  {
3599  // read next token
3600  get_token();
3601 
3602  // closing ] -> we are done
3603  if (last_token == token_type::end_array)
3604  {
3605  return true;
3606  }
3607 
3608  // parse values
3609  while (true)
3610  {
3611  // parse value
3612  if (not accept_internal())
3613  {
3614  return false;
3615  }
3616 
3617  // comma -> next value
3618  get_token();
3619  if (last_token == token_type::value_separator)
3620  {
3621  get_token();
3622  continue;
3623  }
3624 
3625  // closing ]
3626  return (last_token == token_type::end_array);
3627  }
3628  }
3629 
3630  case token_type::value_float:
3631  {
3632  // reject infinity or NAN
3633  return std::isfinite(m_lexer.get_number_float());
3634  }
3635 
3636  case token_type::literal_false:
3637  case token_type::literal_null:
3638  case token_type::literal_true:
3639  case token_type::value_integer:
3640  case token_type::value_string:
3641  case token_type::value_unsigned:
3642  return true;
3643 
3644  default: // the last token was unexpected
3645  return false;
3646  }
3647  }
3648 
3651  {
3652  return (last_token = m_lexer.scan());
3653  }
3654 
3659  {
3660  if (JSON_UNLIKELY(t != last_token))
3661  {
3662  errored = true;
3663  expected = t;
3664  if (allow_exceptions)
3665  {
3666  throw_exception();
3667  }
3668  else
3669  {
3670  return false;
3671  }
3672  }
3673 
3674  return true;
3675  }
3676 
3677  [[noreturn]] void throw_exception() const
3678  {
3679  std::string error_msg = "syntax error - ";
3680  if (last_token == token_type::parse_error)
3681  {
3682  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3683  m_lexer.get_token_string() + "'";
3684  }
3685  else
3686  {
3687  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3688  }
3689 
3690  if (expected != token_type::uninitialized)
3691  {
3692  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3693  }
3694 
3695  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3696  }
3697 
3698  private:
3700  int depth = 0;
3702  const parser_callback_t callback = nullptr;
3704  token_type last_token = token_type::uninitialized;
3708  bool errored = false;
3710  token_type expected = token_type::uninitialized;
3712  const bool allow_exceptions = true;
3713 };
3714 }
3715 }
3716 
3717 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3718 
3719 
3720 #include <cstddef> // ptrdiff_t
3721 #include <limits> // numeric_limits
3722 
3723 namespace nlohmann
3724 {
3725 namespace detail
3726 {
3727 /*
3728 @brief an iterator for primitive JSON types
3729 
3730 This class models an iterator for primitive JSON types (boolean, number,
3731 string). It's only purpose is to allow the iterator/const_iterator classes
3732 to "iterate" over primitive values. Internally, the iterator is modeled by
3733 a `difference_type` variable. Value begin_value (`0`) models the begin,
3734 end_value (`1`) models past the end.
3735 */
3737 {
3738  private:
3739  using difference_type = std::ptrdiff_t;
3740  static constexpr difference_type begin_value = 0;
3741  static constexpr difference_type end_value = begin_value + 1;
3742 
3744  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3745 
3746  public:
3747  constexpr difference_type get_value() const noexcept
3748  {
3749  return m_it;
3750  }
3751 
3753  void set_begin() noexcept
3754  {
3755  m_it = begin_value;
3756  }
3757 
3759  void set_end() noexcept
3760  {
3761  m_it = end_value;
3762  }
3763 
3765  constexpr bool is_begin() const noexcept
3766  {
3767  return m_it == begin_value;
3768  }
3769 
3771  constexpr bool is_end() const noexcept
3772  {
3773  return m_it == end_value;
3774  }
3775 
3776  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3777  {
3778  return lhs.m_it == rhs.m_it;
3779  }
3780 
3781  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3782  {
3783  return lhs.m_it < rhs.m_it;
3784  }
3785 
3787  {
3788  auto result = *this;
3789  result += n;
3790  return result;
3791  }
3792 
3794  {
3795  return lhs.m_it - rhs.m_it;
3796  }
3797 
3799  {
3800  ++m_it;
3801  return *this;
3802  }
3803 
3804  primitive_iterator_t const operator++(int) noexcept
3805  {
3806  auto result = *this;
3807  m_it++;
3808  return result;
3809  }
3810 
3812  {
3813  --m_it;
3814  return *this;
3815  }
3816 
3817  primitive_iterator_t const operator--(int) noexcept
3818  {
3819  auto result = *this;
3820  m_it--;
3821  return result;
3822  }
3823 
3825  {
3826  m_it += n;
3827  return *this;
3828  }
3829 
3831  {
3832  m_it -= n;
3833  return *this;
3834  }
3835 };
3836 }
3837 }
3838 
3839 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
3840 
3841 
3842 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3843 
3844 
3845 namespace nlohmann
3846 {
3847 namespace detail
3848 {
3855 template<typename BasicJsonType> struct internal_iterator
3856 {
3858  typename BasicJsonType::object_t::iterator object_iterator {};
3860  typename BasicJsonType::array_t::iterator array_iterator {};
3862  primitive_iterator_t primitive_iterator {};
3863 };
3864 }
3865 }
3866 
3867 // #include <nlohmann/detail/iterators/iter_impl.hpp>
3868 
3869 
3870 #include <ciso646> // not
3871 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
3872 #include <type_traits> // conditional, is_const, remove_const
3873 
3874 // #include <nlohmann/detail/exceptions.hpp>
3875 
3876 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
3877 
3878 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
3879 
3880 // #include <nlohmann/detail/macro_scope.hpp>
3881 
3882 // #include <nlohmann/detail/meta.hpp>
3883 
3884 // #include <nlohmann/detail/value_t.hpp>
3885 
3886 
3887 namespace nlohmann
3888 {
3889 namespace detail
3890 {
3891 // forward declare, to be able to friend it later on
3892 template<typename IteratorType> class iteration_proxy;
3893 
3914 template<typename BasicJsonType>
3916 {
3918  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
3921 
3922  using object_t = typename BasicJsonType::object_t;
3923  using array_t = typename BasicJsonType::array_t;
3924  // make sure BasicJsonType is basic_json or const basic_json
3925  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
3926  "iter_impl only accepts (const) basic_json");
3927 
3928  public:
3929 
3935  using iterator_category = std::bidirectional_iterator_tag;
3936 
3938  using value_type = typename BasicJsonType::value_type;
3940  using difference_type = typename BasicJsonType::difference_type;
3942  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3943  typename BasicJsonType::const_pointer,
3944  typename BasicJsonType::pointer>::type;
3946  using reference =
3947  typename std::conditional<std::is_const<BasicJsonType>::value,
3948  typename BasicJsonType::const_reference,
3949  typename BasicJsonType::reference>::type;
3950 
3952  iter_impl() = default;
3953 
3960  explicit iter_impl(pointer object) noexcept : m_object(object)
3961  {
3962  assert(m_object != nullptr);
3963 
3964  switch (m_object->m_type)
3965  {
3966  case value_t::object:
3967  {
3968  m_it.object_iterator = typename object_t::iterator();
3969  break;
3970  }
3971 
3972  case value_t::array:
3973  {
3974  m_it.array_iterator = typename array_t::iterator();
3975  break;
3976  }
3977 
3978  default:
3979  {
3980  m_it.primitive_iterator = primitive_iterator_t();
3981  break;
3982  }
3983  }
3984  }
3985 
4000  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
4001  : m_object(other.m_object), m_it(other.m_it) {}
4002 
4009  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
4010  {
4011  m_object = other.m_object;
4012  m_it = other.m_it;
4013  return *this;
4014  }
4015 
4016  private:
4021  void set_begin() noexcept
4022  {
4023  assert(m_object != nullptr);
4024 
4025  switch (m_object->m_type)
4026  {
4027  case value_t::object:
4028  {
4029  m_it.object_iterator = m_object->m_value.object->begin();
4030  break;
4031  }
4032 
4033  case value_t::array:
4034  {
4035  m_it.array_iterator = m_object->m_value.array->begin();
4036  break;
4037  }
4038 
4039  case value_t::null:
4040  {
4041  // set to end so begin()==end() is true: null is empty
4042  m_it.primitive_iterator.set_end();
4043  break;
4044  }
4045 
4046  default:
4047  {
4048  m_it.primitive_iterator.set_begin();
4049  break;
4050  }
4051  }
4052  }
4053 
4058  void set_end() noexcept
4059  {
4060  assert(m_object != nullptr);
4061 
4062  switch (m_object->m_type)
4063  {
4064  case value_t::object:
4065  {
4066  m_it.object_iterator = m_object->m_value.object->end();
4067  break;
4068  }
4069 
4070  case value_t::array:
4071  {
4072  m_it.array_iterator = m_object->m_value.array->end();
4073  break;
4074  }
4075 
4076  default:
4077  {
4078  m_it.primitive_iterator.set_end();
4079  break;
4080  }
4081  }
4082  }
4083 
4084  public:
4090  {
4091  assert(m_object != nullptr);
4092 
4093  switch (m_object->m_type)
4094  {
4095  case value_t::object:
4096  {
4097  assert(m_it.object_iterator != m_object->m_value.object->end());
4098  return m_it.object_iterator->second;
4099  }
4100 
4101  case value_t::array:
4102  {
4103  assert(m_it.array_iterator != m_object->m_value.array->end());
4104  return *m_it.array_iterator;
4105  }
4106 
4107  case value_t::null:
4108  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4109 
4110  default:
4111  {
4112  if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4113  {
4114  return *m_object;
4115  }
4116 
4117  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4118  }
4119  }
4120  }
4121 
4127  {
4128  assert(m_object != nullptr);
4129 
4130  switch (m_object->m_type)
4131  {
4132  case value_t::object:
4133  {
4134  assert(m_it.object_iterator != m_object->m_value.object->end());
4135  return &(m_it.object_iterator->second);
4136  }
4137 
4138  case value_t::array:
4139  {
4140  assert(m_it.array_iterator != m_object->m_value.array->end());
4141  return &*m_it.array_iterator;
4142  }
4143 
4144  default:
4145  {
4146  if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
4147  {
4148  return m_object;
4149  }
4150 
4151  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4152  }
4153  }
4154  }
4155 
4161  {
4162  auto result = *this;
4163  ++(*this);
4164  return result;
4165  }
4166 
4172  {
4173  assert(m_object != nullptr);
4174 
4175  switch (m_object->m_type)
4176  {
4177  case value_t::object:
4178  {
4179  std::advance(m_it.object_iterator, 1);
4180  break;
4181  }
4182 
4183  case value_t::array:
4184  {
4185  std::advance(m_it.array_iterator, 1);
4186  break;
4187  }
4188 
4189  default:
4190  {
4191  ++m_it.primitive_iterator;
4192  break;
4193  }
4194  }
4195 
4196  return *this;
4197  }
4198 
4204  {
4205  auto result = *this;
4206  --(*this);
4207  return result;
4208  }
4209 
4215  {
4216  assert(m_object != nullptr);
4217 
4218  switch (m_object->m_type)
4219  {
4220  case value_t::object:
4221  {
4222  std::advance(m_it.object_iterator, -1);
4223  break;
4224  }
4225 
4226  case value_t::array:
4227  {
4228  std::advance(m_it.array_iterator, -1);
4229  break;
4230  }
4231 
4232  default:
4233  {
4234  --m_it.primitive_iterator;
4235  break;
4236  }
4237  }
4238 
4239  return *this;
4240  }
4241 
4246  bool operator==(const iter_impl& other) const
4247  {
4248  // if objects are not the same, the comparison is undefined
4249  if (JSON_UNLIKELY(m_object != other.m_object))
4250  {
4251  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4252  }
4253 
4254  assert(m_object != nullptr);
4255 
4256  switch (m_object->m_type)
4257  {
4258  case value_t::object:
4259  return (m_it.object_iterator == other.m_it.object_iterator);
4260 
4261  case value_t::array:
4262  return (m_it.array_iterator == other.m_it.array_iterator);
4263 
4264  default:
4265  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
4266  }
4267  }
4268 
4273  bool operator!=(const iter_impl& other) const
4274  {
4275  return not operator==(other);
4276  }
4277 
4282  bool operator<(const iter_impl& other) const
4283  {
4284  // if objects are not the same, the comparison is undefined
4285  if (JSON_UNLIKELY(m_object != other.m_object))
4286  {
4287  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
4288  }
4289 
4290  assert(m_object != nullptr);
4291 
4292  switch (m_object->m_type)
4293  {
4294  case value_t::object:
4295  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
4296 
4297  case value_t::array:
4298  return (m_it.array_iterator < other.m_it.array_iterator);
4299 
4300  default:
4301  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4302  }
4303  }
4304 
4309  bool operator<=(const iter_impl& other) const
4310  {
4311  return not other.operator < (*this);
4312  }
4313 
4318  bool operator>(const iter_impl& other) const
4319  {
4320  return not operator<=(other);
4321  }
4322 
4327  bool operator>=(const iter_impl& other) const
4328  {
4329  return not operator<(other);
4330  }
4331 
4337  {
4338  assert(m_object != nullptr);
4339 
4340  switch (m_object->m_type)
4341  {
4342  case value_t::object:
4343  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4344 
4345  case value_t::array:
4346  {
4347  std::advance(m_it.array_iterator, i);
4348  break;
4349  }
4350 
4351  default:
4352  {
4353  m_it.primitive_iterator += i;
4354  break;
4355  }
4356  }
4357 
4358  return *this;
4359  }
4360 
4366  {
4367  return operator+=(-i);
4368  }
4369 
4375  {
4376  auto result = *this;
4377  result += i;
4378  return result;
4379  }
4380 
4386  {
4387  auto result = it;
4388  result += i;
4389  return result;
4390  }
4391 
4397  {
4398  auto result = *this;
4399  result -= i;
4400  return result;
4401  }
4402 
4408  {
4409  assert(m_object != nullptr);
4410 
4411  switch (m_object->m_type)
4412  {
4413  case value_t::object:
4414  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4415 
4416  case value_t::array:
4417  return m_it.array_iterator - other.m_it.array_iterator;
4418 
4419  default:
4420  return m_it.primitive_iterator - other.m_it.primitive_iterator;
4421  }
4422  }
4423 
4429  {
4430  assert(m_object != nullptr);
4431 
4432  switch (m_object->m_type)
4433  {
4434  case value_t::object:
4435  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4436 
4437  case value_t::array:
4438  return *std::next(m_it.array_iterator, n);
4439 
4440  case value_t::null:
4441  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4442 
4443  default:
4444  {
4445  if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4446  {
4447  return *m_object;
4448  }
4449 
4450  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4451  }
4452  }
4453  }
4454 
4459  typename object_t::key_type key() const
4460  {
4461  assert(m_object != nullptr);
4462 
4463  if (JSON_LIKELY(m_object->is_object()))
4464  {
4465  return m_it.object_iterator->first;
4466  }
4467 
4468  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4469  }
4470 
4476  {
4477  return operator*();
4478  }
4479 
4480  private:
4482  pointer m_object = nullptr;
4485 };
4486 }
4487 }
4488 
4489 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4490 
4491 
4492 #include <cstddef> // size_t
4493 #include <string> // string, to_string
4494 
4495 // #include <nlohmann/detail/value_t.hpp>
4496 
4497 
4498 namespace nlohmann
4499 {
4500 namespace detail
4501 {
4503 template<typename IteratorType> class iteration_proxy
4504 {
4505  private:
4508  {
4509  private:
4511  IteratorType anchor;
4513  std::size_t array_index = 0;
4514 
4515  public:
4516  explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4517 
4520  {
4521  return *this;
4522  }
4523 
4526  {
4527  ++anchor;
4528  ++array_index;
4529 
4530  return *this;
4531  }
4532 
4534  bool operator!=(const iteration_proxy_internal& o) const noexcept
4535  {
4536  return anchor != o.anchor;
4537  }
4538 
4541  {
4542  assert(anchor.m_object != nullptr);
4543 
4544  switch (anchor.m_object->type())
4545  {
4546  // use integer array index as key
4547  case value_t::array:
4548  return std::to_string(array_index);
4549 
4550  // use key from the object
4551  case value_t::object:
4552  return anchor.key();
4553 
4554  // use an empty key for all primitive types
4555  default:
4556  return "";
4557  }
4558  }
4559 
4561  typename IteratorType::reference value() const
4562  {
4563  return anchor.value();
4564  }
4565  };
4566 
4568  typename IteratorType::reference container;
4569 
4570  public:
4572  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4573  : container(cont) {}
4574 
4577  {
4578  return iteration_proxy_internal(container.begin());
4579  }
4580 
4583  {
4584  return iteration_proxy_internal(container.end());
4585  }
4586 };
4587 }
4588 }
4589 
4590 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
4591 
4592 
4593 #include <cstddef> // ptrdiff_t
4594 #include <iterator> // reverse_iterator
4595 #include <utility> // declval
4596 
4597 namespace nlohmann
4598 {
4599 namespace detail
4600 {
4602 // reverse_iterator //
4604 
4623 template<typename Base>
4624 class json_reverse_iterator : public std::reverse_iterator<Base>
4625 {
4626  public:
4627  using difference_type = std::ptrdiff_t;
4629  using base_iterator = std::reverse_iterator<Base>;
4631  using reference = typename Base::reference;
4632 
4634  json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
4635  : base_iterator(it) {}
4636 
4639 
4642  {
4643  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4644  }
4645 
4648  {
4649  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4650  }
4651 
4654  {
4655  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4656  }
4657 
4660  {
4661  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4662  }
4663 
4666  {
4667  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4668  }
4669 
4672  {
4673  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4674  }
4675 
4678  {
4679  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4680  }
4681 
4684  {
4685  return base_iterator(*this) - base_iterator(other);
4686  }
4687 
4690  {
4691  return *(this->operator+(n));
4692  }
4693 
4695  auto key() const -> decltype(std::declval<Base>().key())
4696  {
4697  auto it = --this->base();
4698  return it.key();
4699  }
4700 
4703  {
4704  auto it = --this->base();
4705  return it.operator * ();
4706  }
4707 };
4708 }
4709 }
4710 
4711 // #include <nlohmann/detail/output/output_adapters.hpp>
4712 
4713 
4714 #include <algorithm> // copy
4715 #include <cstddef> // size_t
4716 #include <ios> // streamsize
4717 #include <iterator> // back_inserter
4718 #include <memory> // shared_ptr, make_shared
4719 #include <ostream> // basic_ostream
4720 #include <string> // basic_string
4721 #include <vector> // vector
4722 
4723 namespace nlohmann
4724 {
4725 namespace detail
4726 {
4728 template<typename CharType> struct output_adapter_protocol
4729 {
4730  virtual void write_character(CharType c) = 0;
4731  virtual void write_characters(const CharType* s, std::size_t length) = 0;
4732  virtual ~output_adapter_protocol() = default;
4733 };
4734 
4736 template<typename CharType>
4737 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4738 
4740 template<typename CharType>
4742 {
4743  public:
4744  explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4745 
4746  void write_character(CharType c) override
4747  {
4748  v.push_back(c);
4749  }
4750 
4751  void write_characters(const CharType* s, std::size_t length) override
4752  {
4753  std::copy(s, s + length, std::back_inserter(v));
4754  }
4755 
4756  private:
4757  std::vector<CharType>& v;
4758 };
4759 
4761 template<typename CharType>
4763 {
4764  public:
4765  explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4766 
4767  void write_character(CharType c) override
4768  {
4769  stream.put(c);
4770  }
4771 
4772  void write_characters(const CharType* s, std::size_t length) override
4773  {
4774  stream.write(s, static_cast<std::streamsize>(length));
4775  }
4776 
4777  private:
4778  std::basic_ostream<CharType>& stream;
4779 };
4780 
4782 template<typename CharType, typename StringType = std::basic_string<CharType>>
4784 {
4785  public:
4786  explicit output_string_adapter(StringType& s) : str(s) {}
4787 
4788  void write_character(CharType c) override
4789  {
4790  str.push_back(c);
4791  }
4792 
4793  void write_characters(const CharType* s, std::size_t length) override
4794  {
4795  str.append(s, length);
4796  }
4797 
4798  private:
4799  StringType& str;
4800 };
4801 
4802 template<typename CharType, typename StringType = std::basic_string<CharType>>
4804 {
4805  public:
4806  output_adapter(std::vector<CharType>& vec)
4807  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4808 
4809  output_adapter(std::basic_ostream<CharType>& s)
4810  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4811 
4812  output_adapter(StringType& s)
4813  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
4814 
4816  {
4817  return oa;
4818  }
4819 
4820  private:
4822 };
4823 }
4824 }
4825 
4826 // #include <nlohmann/detail/input/binary_reader.hpp>
4827 
4828 
4829 #include <algorithm> // generate_n
4830 #include <array> // array
4831 #include <cassert> // assert
4832 #include <cmath> // ldexp
4833 #include <cstddef> // size_t
4834 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4835 #include <cstring> // memcpy
4836 #include <iomanip> // setw, setfill
4837 #include <ios> // hex
4838 #include <iterator> // back_inserter
4839 #include <limits> // numeric_limits
4840 #include <sstream> // stringstream
4841 #include <string> // char_traits, string
4842 #include <utility> // make_pair, move
4843 
4844 // #include <nlohmann/detail/input/input_adapters.hpp>
4845 
4846 // #include <nlohmann/detail/exceptions.hpp>
4847 
4848 // #include <nlohmann/detail/macro_scope.hpp>
4849 
4850 // #include <nlohmann/detail/value_t.hpp>
4851 
4852 
4853 namespace nlohmann
4854 {
4855 namespace detail
4856 {
4858 // binary reader //
4860 
4864 template<typename BasicJsonType>
4866 {
4867  using number_integer_t = typename BasicJsonType::number_integer_t;
4868  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4869  using string_t = typename BasicJsonType::string_t;
4870 
4871  public:
4877  explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4878  {
4879  assert(ia);
4880  }
4881 
4892  BasicJsonType parse_cbor(const bool strict)
4893  {
4894  const auto res = parse_cbor_internal();
4895  if (strict)
4896  {
4897  get();
4898  expect_eof();
4899  }
4900  return res;
4901  }
4902 
4913  BasicJsonType parse_msgpack(const bool strict)
4914  {
4915  const auto res = parse_msgpack_internal();
4916  if (strict)
4917  {
4918  get();
4919  expect_eof();
4920  }
4921  return res;
4922  }
4923 
4934  BasicJsonType parse_ubjson(const bool strict)
4935  {
4936  const auto res = parse_ubjson_internal();
4937  if (strict)
4938  {
4939  get_ignore_noop();
4940  expect_eof();
4941  }
4942  return res;
4943  }
4944 
4952  static constexpr bool little_endianess(int num = 1) noexcept
4953  {
4954  return (*reinterpret_cast<char*>(&num) == 1);
4955  }
4956 
4957  private:
4963  BasicJsonType parse_cbor_internal(const bool get_char = true)
4964  {
4965  switch (get_char ? get() : current)
4966  {
4967  // EOF
4968  case std::char_traits<char>::eof():
4969  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4970 
4971  // Integer 0x00..0x17 (0..23)
4972  case 0x00:
4973  case 0x01:
4974  case 0x02:
4975  case 0x03:
4976  case 0x04:
4977  case 0x05:
4978  case 0x06:
4979  case 0x07:
4980  case 0x08:
4981  case 0x09:
4982  case 0x0A:
4983  case 0x0B:
4984  case 0x0C:
4985  case 0x0D:
4986  case 0x0E:
4987  case 0x0F:
4988  case 0x10:
4989  case 0x11:
4990  case 0x12:
4991  case 0x13:
4992  case 0x14:
4993  case 0x15:
4994  case 0x16:
4995  case 0x17:
4996  return static_cast<number_unsigned_t>(current);
4997 
4998  case 0x18: // Unsigned integer (one-byte uint8_t follows)
4999  return get_number<uint8_t>();
5000 
5001  case 0x19: // Unsigned integer (two-byte uint16_t follows)
5002  return get_number<uint16_t>();
5003 
5004  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
5005  return get_number<uint32_t>();
5006 
5007  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
5008  return get_number<uint64_t>();
5009 
5010  // Negative integer -1-0x00..-1-0x17 (-1..-24)
5011  case 0x20:
5012  case 0x21:
5013  case 0x22:
5014  case 0x23:
5015  case 0x24:
5016  case 0x25:
5017  case 0x26:
5018  case 0x27:
5019  case 0x28:
5020  case 0x29:
5021  case 0x2A:
5022  case 0x2B:
5023  case 0x2C:
5024  case 0x2D:
5025  case 0x2E:
5026  case 0x2F:
5027  case 0x30:
5028  case 0x31:
5029  case 0x32:
5030  case 0x33:
5031  case 0x34:
5032  case 0x35:
5033  case 0x36:
5034  case 0x37:
5035  return static_cast<int8_t>(0x20 - 1 - current);
5036 
5037  case 0x38: // Negative integer (one-byte uint8_t follows)
5038  {
5039  return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
5040  }
5041 
5042  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
5043  {
5044  return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
5045  }
5046 
5047  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
5048  {
5049  return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
5050  }
5051 
5052  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
5053  {
5054  return static_cast<number_integer_t>(-1) -
5055  static_cast<number_integer_t>(get_number<uint64_t>());
5056  }
5057 
5058  // UTF-8 string (0x00..0x17 bytes follow)
5059  case 0x60:
5060  case 0x61:
5061  case 0x62:
5062  case 0x63:
5063  case 0x64:
5064  case 0x65:
5065  case 0x66:
5066  case 0x67:
5067  case 0x68:
5068  case 0x69:
5069  case 0x6A:
5070  case 0x6B:
5071  case 0x6C:
5072  case 0x6D:
5073  case 0x6E:
5074  case 0x6F:
5075  case 0x70:
5076  case 0x71:
5077  case 0x72:
5078  case 0x73:
5079  case 0x74:
5080  case 0x75:
5081  case 0x76:
5082  case 0x77:
5083  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5084  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5085  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5086  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5087  case 0x7F: // UTF-8 string (indefinite length)
5088  {
5089  return get_cbor_string();
5090  }
5091 
5092  // array (0x00..0x17 data items follow)
5093  case 0x80:
5094  case 0x81:
5095  case 0x82:
5096  case 0x83:
5097  case 0x84:
5098  case 0x85:
5099  case 0x86:
5100  case 0x87:
5101  case 0x88:
5102  case 0x89:
5103  case 0x8A:
5104  case 0x8B:
5105  case 0x8C:
5106  case 0x8D:
5107  case 0x8E:
5108  case 0x8F:
5109  case 0x90:
5110  case 0x91:
5111  case 0x92:
5112  case 0x93:
5113  case 0x94:
5114  case 0x95:
5115  case 0x96:
5116  case 0x97:
5117  {
5118  return get_cbor_array(current & 0x1F);
5119  }
5120 
5121  case 0x98: // array (one-byte uint8_t for n follows)
5122  {
5123  return get_cbor_array(get_number<uint8_t>());
5124  }
5125 
5126  case 0x99: // array (two-byte uint16_t for n follow)
5127  {
5128  return get_cbor_array(get_number<uint16_t>());
5129  }
5130 
5131  case 0x9A: // array (four-byte uint32_t for n follow)
5132  {
5133  return get_cbor_array(get_number<uint32_t>());
5134  }
5135 
5136  case 0x9B: // array (eight-byte uint64_t for n follow)
5137  {
5138  return get_cbor_array(get_number<uint64_t>());
5139  }
5140 
5141  case 0x9F: // array (indefinite length)
5142  {
5143  BasicJsonType result = value_t::array;
5144  while (get() != 0xFF)
5145  {
5146  result.push_back(parse_cbor_internal(false));
5147  }
5148  return result;
5149  }
5150 
5151  // map (0x00..0x17 pairs of data items follow)
5152  case 0xA0:
5153  case 0xA1:
5154  case 0xA2:
5155  case 0xA3:
5156  case 0xA4:
5157  case 0xA5:
5158  case 0xA6:
5159  case 0xA7:
5160  case 0xA8:
5161  case 0xA9:
5162  case 0xAA:
5163  case 0xAB:
5164  case 0xAC:
5165  case 0xAD:
5166  case 0xAE:
5167  case 0xAF:
5168  case 0xB0:
5169  case 0xB1:
5170  case 0xB2:
5171  case 0xB3:
5172  case 0xB4:
5173  case 0xB5:
5174  case 0xB6:
5175  case 0xB7:
5176  {
5177  return get_cbor_object(current & 0x1F);
5178  }
5179 
5180  case 0xB8: // map (one-byte uint8_t for n follows)
5181  {
5182  return get_cbor_object(get_number<uint8_t>());
5183  }
5184 
5185  case 0xB9: // map (two-byte uint16_t for n follow)
5186  {
5187  return get_cbor_object(get_number<uint16_t>());
5188  }
5189 
5190  case 0xBA: // map (four-byte uint32_t for n follow)
5191  {
5192  return get_cbor_object(get_number<uint32_t>());
5193  }
5194 
5195  case 0xBB: // map (eight-byte uint64_t for n follow)
5196  {
5197  return get_cbor_object(get_number<uint64_t>());
5198  }
5199 
5200  case 0xBF: // map (indefinite length)
5201  {
5202  BasicJsonType result = value_t::object;
5203  while (get() != 0xFF)
5204  {
5205  auto key = get_cbor_string();
5206  result[key] = parse_cbor_internal();
5207  }
5208  return result;
5209  }
5210 
5211  case 0xF4: // false
5212  {
5213  return false;
5214  }
5215 
5216  case 0xF5: // true
5217  {
5218  return true;
5219  }
5220 
5221  case 0xF6: // null
5222  {
5223  return value_t::null;
5224  }
5225 
5226  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
5227  {
5228  const int byte1 = get();
5229  unexpect_eof();
5230  const int byte2 = get();
5231  unexpect_eof();
5232 
5233  // code from RFC 7049, Appendix D, Figure 3:
5234  // As half-precision floating-point numbers were only added
5235  // to IEEE 754 in 2008, today's programming platforms often
5236  // still only have limited support for them. It is very
5237  // easy to include at least decoding support for them even
5238  // without such support. An example of a small decoder for
5239  // half-precision floating-point numbers in the C language
5240  // is shown in Fig. 3.
5241  const int half = (byte1 << 8) + byte2;
5242  const int exp = (half >> 10) & 0x1F;
5243  const int mant = half & 0x3FF;
5244  double val;
5245  if (exp == 0)
5246  {
5247  val = std::ldexp(mant, -24);
5248  }
5249  else if (exp != 31)
5250  {
5251  val = std::ldexp(mant + 1024, exp - 25);
5252  }
5253  else
5254  {
5255  val = (mant == 0) ? std::numeric_limits<double>::infinity()
5256  : std::numeric_limits<double>::quiet_NaN();
5257  }
5258  return (half & 0x8000) != 0 ? -val : val;
5259  }
5260 
5261  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
5262  {
5263  return get_number<float>();
5264  }
5265 
5266  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
5267  {
5268  return get_number<double>();
5269  }
5270 
5271  default: // anything else (0xFF is handled inside the other types)
5272  {
5273  std::stringstream ss;
5274  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5275  JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
5276  }
5277  }
5278  }
5279 
5280  BasicJsonType parse_msgpack_internal()
5281  {
5282  switch (get())
5283  {
5284  // EOF
5285  case std::char_traits<char>::eof():
5286  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5287 
5288  // positive fixint
5289  case 0x00:
5290  case 0x01:
5291  case 0x02:
5292  case 0x03:
5293  case 0x04:
5294  case 0x05:
5295  case 0x06:
5296  case 0x07:
5297  case 0x08:
5298  case 0x09:
5299  case 0x0A:
5300  case 0x0B:
5301  case 0x0C:
5302  case 0x0D:
5303  case 0x0E:
5304  case 0x0F:
5305  case 0x10:
5306  case 0x11:
5307  case 0x12:
5308  case 0x13:
5309  case 0x14:
5310  case 0x15:
5311  case 0x16:
5312  case 0x17:
5313  case 0x18:
5314  case 0x19:
5315  case 0x1A:
5316  case 0x1B:
5317  case 0x1C:
5318  case 0x1D:
5319  case 0x1E:
5320  case 0x1F:
5321  case 0x20:
5322  case 0x21:
5323  case 0x22:
5324  case 0x23:
5325  case 0x24:
5326  case 0x25:
5327  case 0x26:
5328  case 0x27:
5329  case 0x28:
5330  case 0x29:
5331  case 0x2A:
5332  case 0x2B:
5333  case 0x2C:
5334  case 0x2D:
5335  case 0x2E:
5336  case 0x2F:
5337  case 0x30:
5338  case 0x31:
5339  case 0x32:
5340  case 0x33:
5341  case 0x34:
5342  case 0x35:
5343  case 0x36:
5344  case 0x37:
5345  case 0x38:
5346  case 0x39:
5347  case 0x3A:
5348  case 0x3B:
5349  case 0x3C:
5350  case 0x3D:
5351  case 0x3E:
5352  case 0x3F:
5353  case 0x40:
5354  case 0x41:
5355  case 0x42:
5356  case 0x43:
5357  case 0x44:
5358  case 0x45:
5359  case 0x46:
5360  case 0x47:
5361  case 0x48:
5362  case 0x49:
5363  case 0x4A:
5364  case 0x4B:
5365  case 0x4C:
5366  case 0x4D:
5367  case 0x4E:
5368  case 0x4F:
5369  case 0x50:
5370  case 0x51:
5371  case 0x52:
5372  case 0x53:
5373  case 0x54:
5374  case 0x55:
5375  case 0x56:
5376  case 0x57:
5377  case 0x58:
5378  case 0x59:
5379  case 0x5A:
5380  case 0x5B:
5381  case 0x5C:
5382  case 0x5D:
5383  case 0x5E:
5384  case 0x5F:
5385  case 0x60:
5386  case 0x61:
5387  case 0x62:
5388  case 0x63:
5389  case 0x64:
5390  case 0x65:
5391  case 0x66:
5392  case 0x67:
5393  case 0x68:
5394  case 0x69:
5395  case 0x6A:
5396  case 0x6B:
5397  case 0x6C:
5398  case 0x6D:
5399  case 0x6E:
5400  case 0x6F:
5401  case 0x70:
5402  case 0x71:
5403  case 0x72:
5404  case 0x73:
5405  case 0x74:
5406  case 0x75:
5407  case 0x76:
5408  case 0x77:
5409  case 0x78:
5410  case 0x79:
5411  case 0x7A:
5412  case 0x7B:
5413  case 0x7C:
5414  case 0x7D:
5415  case 0x7E:
5416  case 0x7F:
5417  return static_cast<number_unsigned_t>(current);
5418 
5419  // fixmap
5420  case 0x80:
5421  case 0x81:
5422  case 0x82:
5423  case 0x83:
5424  case 0x84:
5425  case 0x85:
5426  case 0x86:
5427  case 0x87:
5428  case 0x88:
5429  case 0x89:
5430  case 0x8A:
5431  case 0x8B:
5432  case 0x8C:
5433  case 0x8D:
5434  case 0x8E:
5435  case 0x8F:
5436  {
5437  return get_msgpack_object(current & 0x0F);
5438  }
5439 
5440  // fixarray
5441  case 0x90:
5442  case 0x91:
5443  case 0x92:
5444  case 0x93:
5445  case 0x94:
5446  case 0x95:
5447  case 0x96:
5448  case 0x97:
5449  case 0x98:
5450  case 0x99:
5451  case 0x9A:
5452  case 0x9B:
5453  case 0x9C:
5454  case 0x9D:
5455  case 0x9E:
5456  case 0x9F:
5457  {
5458  return get_msgpack_array(current & 0x0F);
5459  }
5460 
5461  // fixstr
5462  case 0xA0:
5463  case 0xA1:
5464  case 0xA2:
5465  case 0xA3:
5466  case 0xA4:
5467  case 0xA5:
5468  case 0xA6:
5469  case 0xA7:
5470  case 0xA8:
5471  case 0xA9:
5472  case 0xAA:
5473  case 0xAB:
5474  case 0xAC:
5475  case 0xAD:
5476  case 0xAE:
5477  case 0xAF:
5478  case 0xB0:
5479  case 0xB1:
5480  case 0xB2:
5481  case 0xB3:
5482  case 0xB4:
5483  case 0xB5:
5484  case 0xB6:
5485  case 0xB7:
5486  case 0xB8:
5487  case 0xB9:
5488  case 0xBA:
5489  case 0xBB:
5490  case 0xBC:
5491  case 0xBD:
5492  case 0xBE:
5493  case 0xBF:
5494  return get_msgpack_string();
5495 
5496  case 0xC0: // nil
5497  return value_t::null;
5498 
5499  case 0xC2: // false
5500  return false;
5501 
5502  case 0xC3: // true
5503  return true;
5504 
5505  case 0xCA: // float 32
5506  return get_number<float>();
5507 
5508  case 0xCB: // float 64
5509  return get_number<double>();
5510 
5511  case 0xCC: // uint 8
5512  return get_number<uint8_t>();
5513 
5514  case 0xCD: // uint 16
5515  return get_number<uint16_t>();
5516 
5517  case 0xCE: // uint 32
5518  return get_number<uint32_t>();
5519 
5520  case 0xCF: // uint 64
5521  return get_number<uint64_t>();
5522 
5523  case 0xD0: // int 8
5524  return get_number<int8_t>();
5525 
5526  case 0xD1: // int 16
5527  return get_number<int16_t>();
5528 
5529  case 0xD2: // int 32
5530  return get_number<int32_t>();
5531 
5532  case 0xD3: // int 64
5533  return get_number<int64_t>();
5534 
5535  case 0xD9: // str 8
5536  case 0xDA: // str 16
5537  case 0xDB: // str 32
5538  return get_msgpack_string();
5539 
5540  case 0xDC: // array 16
5541  {
5542  return get_msgpack_array(get_number<uint16_t>());
5543  }
5544 
5545  case 0xDD: // array 32
5546  {
5547  return get_msgpack_array(get_number<uint32_t>());
5548  }
5549 
5550  case 0xDE: // map 16
5551  {
5552  return get_msgpack_object(get_number<uint16_t>());
5553  }
5554 
5555  case 0xDF: // map 32
5556  {
5557  return get_msgpack_object(get_number<uint32_t>());
5558  }
5559 
5560  // positive fixint
5561  case 0xE0:
5562  case 0xE1:
5563  case 0xE2:
5564  case 0xE3:
5565  case 0xE4:
5566  case 0xE5:
5567  case 0xE6:
5568  case 0xE7:
5569  case 0xE8:
5570  case 0xE9:
5571  case 0xEA:
5572  case 0xEB:
5573  case 0xEC:
5574  case 0xED:
5575  case 0xEE:
5576  case 0xEF:
5577  case 0xF0:
5578  case 0xF1:
5579  case 0xF2:
5580  case 0xF3:
5581  case 0xF4:
5582  case 0xF5:
5583  case 0xF6:
5584  case 0xF7:
5585  case 0xF8:
5586  case 0xF9:
5587  case 0xFA:
5588  case 0xFB:
5589  case 0xFC:
5590  case 0xFD:
5591  case 0xFE:
5592  case 0xFF:
5593  return static_cast<int8_t>(current);
5594 
5595  default: // anything else
5596  {
5597  std::stringstream ss;
5598  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5599  JSON_THROW(parse_error::create(112, chars_read,
5600  "error reading MessagePack; last byte: 0x" + ss.str()));
5601  }
5602  }
5603  }
5604 
5610  BasicJsonType parse_ubjson_internal(const bool get_char = true)
5611  {
5612  return get_ubjson_value(get_char ? get_ignore_noop() : current);
5613  }
5614 
5624  int get()
5625  {
5626  ++chars_read;
5627  return (current = ia->get_character());
5628  }
5629 
5634  {
5635  do
5636  {
5637  get();
5638  }
5639  while (current == 'N');
5640 
5641  return current;
5642  }
5643 
5644  /*
5645  @brief read a number from the input
5646 
5647  @tparam NumberType the type of the number
5648 
5649  @return number of type @a NumberType
5650 
5651  @note This function needs to respect the system's endianess, because
5652  bytes in CBOR and MessagePack are stored in network order (big
5653  endian) and therefore need reordering on little endian systems.
5654 
5655  @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5656  */
5657  template<typename NumberType> NumberType get_number()
5658  {
5659  // step 1: read input into array with system's byte order
5660  std::array<uint8_t, sizeof(NumberType)> vec;
5661  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5662  {
5663  get();
5664  unexpect_eof();
5665 
5666  // reverse byte order prior to conversion if necessary
5667  if (is_little_endian)
5668  {
5669  vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5670  }
5671  else
5672  {
5673  vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5674  }
5675  }
5676 
5677  // step 2: convert array into number of type T and return
5678  NumberType result;
5679  std::memcpy(&result, vec.data(), sizeof(NumberType));
5680  return result;
5681  }
5682 
5696  template<typename NumberType>
5697  string_t get_string(const NumberType len)
5698  {
5699  string_t result;
5700  std::generate_n(std::back_inserter(result), len, [this]()
5701  {
5702  get();
5703  unexpect_eof();
5704  return static_cast<char>(current);
5705  });
5706  return result;
5707  }
5708 
5722  {
5723  unexpect_eof();
5724 
5725  switch (current)
5726  {
5727  // UTF-8 string (0x00..0x17 bytes follow)
5728  case 0x60:
5729  case 0x61:
5730  case 0x62:
5731  case 0x63:
5732  case 0x64:
5733  case 0x65:
5734  case 0x66:
5735  case 0x67:
5736  case 0x68:
5737  case 0x69:
5738  case 0x6A:
5739  case 0x6B:
5740  case 0x6C:
5741  case 0x6D:
5742  case 0x6E:
5743  case 0x6F:
5744  case 0x70:
5745  case 0x71:
5746  case 0x72:
5747  case 0x73:
5748  case 0x74:
5749  case 0x75:
5750  case 0x76:
5751  case 0x77:
5752  {
5753  return get_string(current & 0x1F);
5754  }
5755 
5756  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5757  {
5758  return get_string(get_number<uint8_t>());
5759  }
5760 
5761  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5762  {
5763  return get_string(get_number<uint16_t>());
5764  }
5765 
5766  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5767  {
5768  return get_string(get_number<uint32_t>());
5769  }
5770 
5771  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5772  {
5773  return get_string(get_number<uint64_t>());
5774  }
5775 
5776  case 0x7F: // UTF-8 string (indefinite length)
5777  {
5778  string_t result;
5779  while (get() != 0xFF)
5780  {
5781  result.append(get_cbor_string());
5782  }
5783  return result;
5784  }
5785 
5786  default:
5787  {
5788  std::stringstream ss;
5789  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5790  JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
5791  }
5792  }
5793  }
5794 
5795  template<typename NumberType>
5796  BasicJsonType get_cbor_array(const NumberType len)
5797  {
5798  BasicJsonType result = value_t::array;
5799  std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5800  {
5801  return parse_cbor_internal();
5802  });
5803  return result;
5804  }
5805 
5806  template<typename NumberType>
5807  BasicJsonType get_cbor_object(const NumberType len)
5808  {
5809  BasicJsonType result = value_t::object;
5810  std::generate_n(std::inserter(*result.m_value.object,
5811  result.m_value.object->end()),
5812  len, [this]()
5813  {
5814  get();
5815  auto key = get_cbor_string();
5816  auto val = parse_cbor_internal();
5817  return std::make_pair(std::move(key), std::move(val));
5818  });
5819  return result;
5820  }
5821 
5834  {
5835  unexpect_eof();
5836 
5837  switch (current)
5838  {
5839  // fixstr
5840  case 0xA0:
5841  case 0xA1:
5842  case 0xA2:
5843  case 0xA3:
5844  case 0xA4:
5845  case 0xA5:
5846  case 0xA6:
5847  case 0xA7:
5848  case 0xA8:
5849  case 0xA9:
5850  case 0xAA:
5851  case 0xAB:
5852  case 0xAC:
5853  case 0xAD:
5854  case 0xAE:
5855  case 0xAF:
5856  case 0xB0:
5857  case 0xB1:
5858  case 0xB2:
5859  case 0xB3:
5860  case 0xB4:
5861  case 0xB5:
5862  case 0xB6:
5863  case 0xB7:
5864  case 0xB8:
5865  case 0xB9:
5866  case 0xBA:
5867  case 0xBB:
5868  case 0xBC:
5869  case 0xBD:
5870  case 0xBE:
5871  case 0xBF:
5872  {
5873  return get_string(current & 0x1F);
5874  }
5875 
5876  case 0xD9: // str 8
5877  {
5878  return get_string(get_number<uint8_t>());
5879  }
5880 
5881  case 0xDA: // str 16
5882  {
5883  return get_string(get_number<uint16_t>());
5884  }
5885 
5886  case 0xDB: // str 32
5887  {
5888  return get_string(get_number<uint32_t>());
5889  }
5890 
5891  default:
5892  {
5893  std::stringstream ss;
5894  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5895  JSON_THROW(parse_error::create(113, chars_read,
5896  "expected a MessagePack string; last byte: 0x" + ss.str()));
5897  }
5898  }
5899  }
5900 
5901  template<typename NumberType>
5902  BasicJsonType get_msgpack_array(const NumberType len)
5903  {
5904  BasicJsonType result = value_t::array;
5905  std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5906  {
5907  return parse_msgpack_internal();
5908  });
5909  return result;
5910  }
5911 
5912  template<typename NumberType>
5913  BasicJsonType get_msgpack_object(const NumberType len)
5914  {
5915  BasicJsonType result = value_t::object;
5916  std::generate_n(std::inserter(*result.m_value.object,
5917  result.m_value.object->end()),
5918  len, [this]()
5919  {
5920  get();
5921  auto key = get_msgpack_string();
5922  auto val = parse_msgpack_internal();
5923  return std::make_pair(std::move(key), std::move(val));
5924  });
5925  return result;
5926  }
5927 
5944  string_t get_ubjson_string(const bool get_char = true)
5945  {
5946  if (get_char)
5947  {
5948  get(); // TODO: may we ignore N here?
5949  }
5950 
5951  unexpect_eof();
5952 
5953  switch (current)
5954  {
5955  case 'U':
5956  return get_string(get_number<uint8_t>());
5957  case 'i':
5958  return get_string(get_number<int8_t>());
5959  case 'I':
5960  return get_string(get_number<int16_t>());
5961  case 'l':
5962  return get_string(get_number<int32_t>());
5963  case 'L':
5964  return get_string(get_number<int64_t>());
5965  default:
5966  std::stringstream ss;
5967  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5968  JSON_THROW(parse_error::create(113, chars_read,
5969  "expected a UBJSON string; last byte: 0x" + ss.str()));
5970  }
5971  }
5972 
5981  std::pair<std::size_t, int> get_ubjson_size_type()
5982  {
5983  std::size_t sz = string_t::npos;
5984  int tc = 0;
5985 
5986  get_ignore_noop();
5987 
5988  if (current == '$')
5989  {
5990  tc = get(); // must not ignore 'N', because 'N' maybe the type
5991  unexpect_eof();
5992 
5993  get_ignore_noop();
5994  if (current != '#')
5995  {
5996  std::stringstream ss;
5997  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
5998  JSON_THROW(parse_error::create(112, chars_read,
5999  "expected '#' after UBJSON type information; last byte: 0x" + ss.str()));
6000  }
6001  sz = parse_ubjson_internal();
6002  }
6003  else if (current == '#')
6004  {
6005  sz = parse_ubjson_internal();
6006  }
6007 
6008  return std::make_pair(sz, tc);
6009  }
6010 
6011  BasicJsonType get_ubjson_value(const int prefix)
6012  {
6013  switch (prefix)
6014  {
6015  case std::char_traits<char>::eof(): // EOF
6016  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
6017 
6018  case 'T': // true
6019  return true;
6020  case 'F': // false
6021  return false;
6022 
6023  case 'Z': // null
6024  return nullptr;
6025 
6026  case 'U':
6027  return get_number<uint8_t>();
6028  case 'i':
6029  return get_number<int8_t>();
6030  case 'I':
6031  return get_number<int16_t>();
6032  case 'l':
6033  return get_number<int32_t>();
6034  case 'L':
6035  return get_number<int64_t>();
6036  case 'd':
6037  return get_number<float>();
6038  case 'D':
6039  return get_number<double>();
6040 
6041  case 'C': // char
6042  {
6043  get();
6044  unexpect_eof();
6045  if (JSON_UNLIKELY(current > 127))
6046  {
6047  std::stringstream ss;
6048  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
6049  JSON_THROW(parse_error::create(113, chars_read,
6050  "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + ss.str()));
6051  }
6052  return string_t(1, static_cast<char>(current));
6053  }
6054 
6055  case 'S': // string
6056  return get_ubjson_string();
6057 
6058  case '[': // array
6059  return get_ubjson_array();
6060 
6061  case '{': // object
6062  return get_ubjson_object();
6063 
6064  default: // anything else
6065  std::stringstream ss;
6066  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
6067  JSON_THROW(parse_error::create(112, chars_read,
6068  "error reading UBJSON; last byte: 0x" + ss.str()));
6069  }
6070  }
6071 
6072  BasicJsonType get_ubjson_array()
6073  {
6074  BasicJsonType result = value_t::array;
6075  const auto size_and_type = get_ubjson_size_type();
6076 
6077  if (size_and_type.first != string_t::npos)
6078  {
6079  if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6080  {
6082  "excessive array size: " + std::to_string(size_and_type.first)));
6083  }
6084 
6085  if (size_and_type.second != 0)
6086  {
6087  if (size_and_type.second != 'N')
6088  {
6089  std::generate_n(std::back_inserter(*result.m_value.array),
6090  size_and_type.first, [this, size_and_type]()
6091  {
6092  return get_ubjson_value(size_and_type.second);
6093  });
6094  }
6095  }
6096  else
6097  {
6098  std::generate_n(std::back_inserter(*result.m_value.array),
6099  size_and_type.first, [this]()
6100  {
6101  return parse_ubjson_internal();
6102  });
6103  }
6104  }
6105  else
6106  {
6107  while (current != ']')
6108  {
6109  result.push_back(parse_ubjson_internal(false));
6110  get_ignore_noop();
6111  }
6112  }
6113 
6114  return result;
6115  }
6116 
6117  BasicJsonType get_ubjson_object()
6118  {
6119  BasicJsonType result = value_t::object;
6120  const auto size_and_type = get_ubjson_size_type();
6121 
6122  if (size_and_type.first != string_t::npos)
6123  {
6124  if (JSON_UNLIKELY(size_and_type.first > result.max_size()))
6125  {
6127  "excessive object size: " + std::to_string(size_and_type.first)));
6128  }
6129 
6130  if (size_and_type.second != 0)
6131  {
6132  std::generate_n(std::inserter(*result.m_value.object,
6133  result.m_value.object->end()),
6134  size_and_type.first, [this, size_and_type]()
6135  {
6136  auto key = get_ubjson_string();
6137  auto val = get_ubjson_value(size_and_type.second);
6138  return std::make_pair(std::move(key), std::move(val));
6139  });
6140  }
6141  else
6142  {
6143  std::generate_n(std::inserter(*result.m_value.object,
6144  result.m_value.object->end()),
6145  size_and_type.first, [this]()
6146  {
6147  auto key = get_ubjson_string();
6148  auto val = parse_ubjson_internal();
6149  return std::make_pair(std::move(key), std::move(val));
6150  });
6151  }
6152  }
6153  else
6154  {
6155  while (current != '}')
6156  {
6157  auto key = get_ubjson_string(false);
6158  result[std::move(key)] = parse_ubjson_internal();
6159  get_ignore_noop();
6160  }
6161  }
6162 
6163  return result;
6164  }
6165 
6170  void expect_eof() const
6171  {
6172  if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6173  {
6174  JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
6175  }
6176  }
6177 
6182  void unexpect_eof() const
6183  {
6184  if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
6185  {
6186  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
6187  }
6188  }
6189 
6190  private:
6192  input_adapter_t ia = nullptr;
6193 
6195  int current = std::char_traits<char>::eof();
6196 
6198  std::size_t chars_read = 0;
6199 
6201  const bool is_little_endian = little_endianess();
6202 };
6203 }
6204 }
6205 
6206 // #include <nlohmann/detail/output/binary_writer.hpp>
6207 
6208 
6209 #include <algorithm> // reverse
6210 #include <array> // array
6211 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6212 #include <cstring> // memcpy
6213 #include <limits> // numeric_limits
6214 
6215 // #include <nlohmann/detail/input/binary_reader.hpp>
6216 
6217 // #include <nlohmann/detail/output/output_adapters.hpp>
6218 
6219 
6220 namespace nlohmann
6221 {
6222 namespace detail
6223 {
6225 // binary writer //
6227 
6231 template<typename BasicJsonType, typename CharType>
6233 {
6234  public:
6240  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
6241  {
6242  assert(oa);
6243  }
6244 
6248  void write_cbor(const BasicJsonType& j)
6249  {
6250  switch (j.type())
6251  {
6252  case value_t::null:
6253  {
6254  oa->write_character(static_cast<CharType>(0xF6));
6255  break;
6256  }
6257 
6258  case value_t::boolean:
6259  {
6260  oa->write_character(j.m_value.boolean
6261  ? static_cast<CharType>(0xF5)
6262  : static_cast<CharType>(0xF4));
6263  break;
6264  }
6265 
6267  {
6268  if (j.m_value.number_integer >= 0)
6269  {
6270  // CBOR does not differentiate between positive signed
6271  // integers and unsigned integers. Therefore, we used the
6272  // code from the value_t::number_unsigned case here.
6273  if (j.m_value.number_integer <= 0x17)
6274  {
6275  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6276  }
6277  else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
6278  {
6279  oa->write_character(static_cast<CharType>(0x18));
6280  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6281  }
6282  else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
6283  {
6284  oa->write_character(static_cast<CharType>(0x19));
6285  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6286  }
6287  else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
6288  {
6289  oa->write_character(static_cast<CharType>(0x1A));
6290  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6291  }
6292  else
6293  {
6294  oa->write_character(static_cast<CharType>(0x1B));
6295  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6296  }
6297  }
6298  else
6299  {
6300  // The conversions below encode the sign in the first
6301  // byte, and the value is converted to a positive number.
6302  const auto positive_number = -1 - j.m_value.number_integer;
6303  if (j.m_value.number_integer >= -24)
6304  {
6305  write_number(static_cast<uint8_t>(0x20 + positive_number));
6306  }
6307  else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
6308  {
6309  oa->write_character(static_cast<CharType>(0x38));
6310  write_number(static_cast<uint8_t>(positive_number));
6311  }
6312  else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
6313  {
6314  oa->write_character(static_cast<CharType>(0x39));
6315  write_number(static_cast<uint16_t>(positive_number));
6316  }
6317  else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
6318  {
6319  oa->write_character(static_cast<CharType>(0x3A));
6320  write_number(static_cast<uint32_t>(positive_number));
6321  }
6322  else
6323  {
6324  oa->write_character(static_cast<CharType>(0x3B));
6325  write_number(static_cast<uint64_t>(positive_number));
6326  }
6327  }
6328  break;
6329  }
6330 
6332  {
6333  if (j.m_value.number_unsigned <= 0x17)
6334  {
6335  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6336  }
6337  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6338  {
6339  oa->write_character(static_cast<CharType>(0x18));
6340  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
6341  }
6342  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6343  {
6344  oa->write_character(static_cast<CharType>(0x19));
6345  write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
6346  }
6347  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6348  {
6349  oa->write_character(static_cast<CharType>(0x1A));
6350  write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
6351  }
6352  else
6353  {
6354  oa->write_character(static_cast<CharType>(0x1B));
6355  write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
6356  }
6357  break;
6358  }
6359 
6360  case value_t::number_float: // Double-Precision Float
6361  {
6362  oa->write_character(static_cast<CharType>(0xFB));
6363  write_number(j.m_value.number_float);
6364  break;
6365  }
6366 
6367  case value_t::string:
6368  {
6369  // step 1: write control byte and the string length
6370  const auto N = j.m_value.string->size();
6371  if (N <= 0x17)
6372  {
6373  write_number(static_cast<uint8_t>(0x60 + N));
6374  }
6375  else if (N <= (std::numeric_limits<uint8_t>::max)())
6376  {
6377  oa->write_character(static_cast<CharType>(0x78));
6378  write_number(static_cast<uint8_t>(N));
6379  }
6380  else if (N <= (std::numeric_limits<uint16_t>::max)())
6381  {
6382  oa->write_character(static_cast<CharType>(0x79));
6383  write_number(static_cast<uint16_t>(N));
6384  }
6385  else if (N <= (std::numeric_limits<uint32_t>::max)())
6386  {
6387  oa->write_character(static_cast<CharType>(0x7A));
6388  write_number(static_cast<uint32_t>(N));
6389  }
6390  // LCOV_EXCL_START
6391  else if (N <= (std::numeric_limits<uint64_t>::max)())
6392  {
6393  oa->write_character(static_cast<CharType>(0x7B));
6394  write_number(static_cast<uint64_t>(N));
6395  }
6396  // LCOV_EXCL_STOP
6397 
6398  // step 2: write the string
6399  oa->write_characters(
6400  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6401  j.m_value.string->size());
6402  break;
6403  }
6404 
6405  case value_t::array:
6406  {
6407  // step 1: write control byte and the array size
6408  const auto N = j.m_value.array->size();
6409  if (N <= 0x17)
6410  {
6411  write_number(static_cast<uint8_t>(0x80 + N));
6412  }
6413  else if (N <= (std::numeric_limits<uint8_t>::max)())
6414  {
6415  oa->write_character(static_cast<CharType>(0x98));
6416  write_number(static_cast<uint8_t>(N));
6417  }
6418  else if (N <= (std::numeric_limits<uint16_t>::max)())
6419  {
6420  oa->write_character(static_cast<CharType>(0x99));
6421  write_number(static_cast<uint16_t>(N));
6422  }
6423  else if (N <= (std::numeric_limits<uint32_t>::max)())
6424  {
6425  oa->write_character(static_cast<CharType>(0x9A));
6426  write_number(static_cast<uint32_t>(N));
6427  }
6428  // LCOV_EXCL_START
6429  else if (N <= (std::numeric_limits<uint64_t>::max)())
6430  {
6431  oa->write_character(static_cast<CharType>(0x9B));
6432  write_number(static_cast<uint64_t>(N));
6433  }
6434  // LCOV_EXCL_STOP
6435 
6436  // step 2: write each element
6437  for (const auto& el : *j.m_value.array)
6438  {
6439  write_cbor(el);
6440  }
6441  break;
6442  }
6443 
6444  case value_t::object:
6445  {
6446  // step 1: write control byte and the object size
6447  const auto N = j.m_value.object->size();
6448  if (N <= 0x17)
6449  {
6450  write_number(static_cast<uint8_t>(0xA0 + N));
6451  }
6452  else if (N <= (std::numeric_limits<uint8_t>::max)())
6453  {
6454  oa->write_character(static_cast<CharType>(0xB8));
6455  write_number(static_cast<uint8_t>(N));
6456  }
6457  else if (N <= (std::numeric_limits<uint16_t>::max)())
6458  {
6459  oa->write_character(static_cast<CharType>(0xB9));
6460  write_number(static_cast<uint16_t>(N));
6461  }
6462  else if (N <= (std::numeric_limits<uint32_t>::max)())
6463  {
6464  oa->write_character(static_cast<CharType>(0xBA));
6465  write_number(static_cast<uint32_t>(N));
6466  }
6467  // LCOV_EXCL_START
6468  else if (N <= (std::numeric_limits<uint64_t>::max)())
6469  {
6470  oa->write_character(static_cast<CharType>(0xBB));
6471  write_number(static_cast<uint64_t>(N));
6472  }
6473  // LCOV_EXCL_STOP
6474 
6475  // step 2: write each element
6476  for (const auto& el : *j.m_value.object)
6477  {
6478  write_cbor(el.first);
6479  write_cbor(el.second);
6480  }
6481  break;
6482  }
6483 
6484  default:
6485  break;
6486  }
6487  }
6488 
6492  void write_msgpack(const BasicJsonType& j)
6493  {
6494  switch (j.type())
6495  {
6496  case value_t::null: // nil
6497  {
6498  oa->write_character(static_cast<CharType>(0xC0));
6499  break;
6500  }
6501 
6502  case value_t::boolean: // true and false
6503  {
6504  oa->write_character(j.m_value.boolean
6505  ? static_cast<CharType>(0xC3)
6506  : static_cast<CharType>(0xC2));
6507  break;
6508  }
6509 
6511  {
6512  if (j.m_value.number_integer >= 0)
6513  {
6514  // MessagePack does not differentiate between positive
6515  // signed integers and unsigned integers. Therefore, we used
6516  // the code from the value_t::number_unsigned case here.
6517  if (j.m_value.number_unsigned < 128)
6518  {
6519  // positive fixnum
6520  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6521  }
6522  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6523  {
6524  // uint 8
6525  oa->write_character(static_cast<CharType>(0xCC));
6526  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6527  }
6528  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6529  {
6530  // uint 16
6531  oa->write_character(static_cast<CharType>(0xCD));
6532  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6533  }
6534  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6535  {
6536  // uint 32
6537  oa->write_character(static_cast<CharType>(0xCE));
6538  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6539  }
6540  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6541  {
6542  // uint 64
6543  oa->write_character(static_cast<CharType>(0xCF));
6544  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6545  }
6546  }
6547  else
6548  {
6549  if (j.m_value.number_integer >= -32)
6550  {
6551  // negative fixnum
6552  write_number(static_cast<int8_t>(j.m_value.number_integer));
6553  }
6554  else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
6555  j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
6556  {
6557  // int 8
6558  oa->write_character(static_cast<CharType>(0xD0));
6559  write_number(static_cast<int8_t>(j.m_value.number_integer));
6560  }
6561  else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
6562  j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
6563  {
6564  // int 16
6565  oa->write_character(static_cast<CharType>(0xD1));
6566  write_number(static_cast<int16_t>(j.m_value.number_integer));
6567  }
6568  else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
6569  j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
6570  {
6571  // int 32
6572  oa->write_character(static_cast<CharType>(0xD2));
6573  write_number(static_cast<int32_t>(j.m_value.number_integer));
6574  }
6575  else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
6576  j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
6577  {
6578  // int 64
6579  oa->write_character(static_cast<CharType>(0xD3));
6580  write_number(static_cast<int64_t>(j.m_value.number_integer));
6581  }
6582  }
6583  break;
6584  }
6585 
6587  {
6588  if (j.m_value.number_unsigned < 128)
6589  {
6590  // positive fixnum
6591  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6592  }
6593  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
6594  {
6595  // uint 8
6596  oa->write_character(static_cast<CharType>(0xCC));
6597  write_number(static_cast<uint8_t>(j.m_value.number_integer));
6598  }
6599  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
6600  {
6601  // uint 16
6602  oa->write_character(static_cast<CharType>(0xCD));
6603  write_number(static_cast<uint16_t>(j.m_value.number_integer));
6604  }
6605  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
6606  {
6607  // uint 32
6608  oa->write_character(static_cast<CharType>(0xCE));
6609  write_number(static_cast<uint32_t>(j.m_value.number_integer));
6610  }
6611  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
6612  {
6613  // uint 64
6614  oa->write_character(static_cast<CharType>(0xCF));
6615  write_number(static_cast<uint64_t>(j.m_value.number_integer));
6616  }
6617  break;
6618  }
6619 
6620  case value_t::number_float: // float 64
6621  {
6622  oa->write_character(static_cast<CharType>(0xCB));
6623  write_number(j.m_value.number_float);
6624  break;
6625  }
6626 
6627  case value_t::string:
6628  {
6629  // step 1: write control byte and the string length
6630  const auto N = j.m_value.string->size();
6631  if (N <= 31)
6632  {
6633  // fixstr
6634  write_number(static_cast<uint8_t>(0xA0 | N));
6635  }
6636  else if (N <= (std::numeric_limits<uint8_t>::max)())
6637  {
6638  // str 8
6639  oa->write_character(static_cast<CharType>(0xD9));
6640  write_number(static_cast<uint8_t>(N));
6641  }
6642  else if (N <= (std::numeric_limits<uint16_t>::max)())
6643  {
6644  // str 16
6645  oa->write_character(static_cast<CharType>(0xDA));
6646  write_number(static_cast<uint16_t>(N));
6647  }
6648  else if (N <= (std::numeric_limits<uint32_t>::max)())
6649  {
6650  // str 32
6651  oa->write_character(static_cast<CharType>(0xDB));
6652  write_number(static_cast<uint32_t>(N));
6653  }
6654 
6655  // step 2: write the string
6656  oa->write_characters(
6657  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6658  j.m_value.string->size());
6659  break;
6660  }
6661 
6662  case value_t::array:
6663  {
6664  // step 1: write control byte and the array size
6665  const auto N = j.m_value.array->size();
6666  if (N <= 15)
6667  {
6668  // fixarray
6669  write_number(static_cast<uint8_t>(0x90 | N));
6670  }
6671  else if (N <= (std::numeric_limits<uint16_t>::max)())
6672  {
6673  // array 16
6674  oa->write_character(static_cast<CharType>(0xDC));
6675  write_number(static_cast<uint16_t>(N));
6676  }
6677  else if (N <= (std::numeric_limits<uint32_t>::max)())
6678  {
6679  // array 32
6680  oa->write_character(static_cast<CharType>(0xDD));
6681  write_number(static_cast<uint32_t>(N));
6682  }
6683 
6684  // step 2: write each element
6685  for (const auto& el : *j.m_value.array)
6686  {
6687  write_msgpack(el);
6688  }
6689  break;
6690  }
6691 
6692  case value_t::object:
6693  {
6694  // step 1: write control byte and the object size
6695  const auto N = j.m_value.object->size();
6696  if (N <= 15)
6697  {
6698  // fixmap
6699  write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
6700  }
6701  else if (N <= (std::numeric_limits<uint16_t>::max)())
6702  {
6703  // map 16
6704  oa->write_character(static_cast<CharType>(0xDE));
6705  write_number(static_cast<uint16_t>(N));
6706  }
6707  else if (N <= (std::numeric_limits<uint32_t>::max)())
6708  {
6709  // map 32
6710  oa->write_character(static_cast<CharType>(0xDF));
6711  write_number(static_cast<uint32_t>(N));
6712  }
6713 
6714  // step 2: write each element
6715  for (const auto& el : *j.m_value.object)
6716  {
6717  write_msgpack(el.first);
6718  write_msgpack(el.second);
6719  }
6720  break;
6721  }
6722 
6723  default:
6724  break;
6725  }
6726  }
6727 
6734  void write_ubjson(const BasicJsonType& j, const bool use_count,
6735  const bool use_type, const bool add_prefix = true)
6736  {
6737  switch (j.type())
6738  {
6739  case value_t::null:
6740  {
6741  if (add_prefix)
6742  {
6743  oa->write_character(static_cast<CharType>('Z'));
6744  }
6745  break;
6746  }
6747 
6748  case value_t::boolean:
6749  {
6750  if (add_prefix)
6751  oa->write_character(j.m_value.boolean
6752  ? static_cast<CharType>('T')
6753  : static_cast<CharType>('F'));
6754  break;
6755  }
6756 
6758  {
6759  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
6760  break;
6761  }
6762 
6764  {
6765  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
6766  break;
6767  }
6768 
6769  case value_t::number_float:
6770  {
6771  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
6772  break;
6773  }
6774 
6775  case value_t::string:
6776  {
6777  if (add_prefix)
6778  {
6779  oa->write_character(static_cast<CharType>('S'));
6780  }
6781  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
6782  oa->write_characters(
6783  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
6784  j.m_value.string->size());
6785  break;
6786  }
6787 
6788  case value_t::array:
6789  {
6790  if (add_prefix)
6791  {
6792  oa->write_character(static_cast<CharType>('['));
6793  }
6794 
6795  bool prefix_required = true;
6796  if (use_type and not j.m_value.array->empty())
6797  {
6798  assert(use_count);
6799  const char first_prefix = ubjson_prefix(j.front());
6800  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
6801  [this, first_prefix](const BasicJsonType & v)
6802  {
6803  return ubjson_prefix(v) == first_prefix;
6804  });
6805 
6806  if (same_prefix)
6807  {
6808  prefix_required = false;
6809  oa->write_character(static_cast<CharType>('$'));
6810  oa->write_character(static_cast<CharType>(first_prefix));
6811  }
6812  }
6813 
6814  if (use_count)
6815  {
6816  oa->write_character(static_cast<CharType>('#'));
6817  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
6818  }
6819 
6820  for (const auto& el : *j.m_value.array)
6821  {
6822  write_ubjson(el, use_count, use_type, prefix_required);
6823  }
6824 
6825  if (not use_count)
6826  {
6827  oa->write_character(static_cast<CharType>(']'));
6828  }
6829 
6830  break;
6831  }
6832 
6833  case value_t::object:
6834  {
6835  if (add_prefix)
6836  {
6837  oa->write_character(static_cast<CharType>('{'));
6838  }
6839 
6840  bool prefix_required = true;
6841  if (use_type and not j.m_value.object->empty())
6842  {
6843  assert(use_count);
6844  const char first_prefix = ubjson_prefix(j.front());
6845  const bool same_prefix = std::all_of(j.begin(), j.end(),
6846  [this, first_prefix](const BasicJsonType & v)
6847  {
6848  return ubjson_prefix(v) == first_prefix;
6849  });
6850 
6851  if (same_prefix)
6852  {
6853  prefix_required = false;
6854  oa->write_character(static_cast<CharType>('$'));
6855  oa->write_character(static_cast<CharType>(first_prefix));
6856  }
6857  }
6858 
6859  if (use_count)
6860  {
6861  oa->write_character(static_cast<CharType>('#'));
6862  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
6863  }
6864 
6865  for (const auto& el : *j.m_value.object)
6866  {
6867  write_number_with_ubjson_prefix(el.first.size(), true);
6868  oa->write_characters(
6869  reinterpret_cast<const CharType*>(el.first.c_str()),
6870  el.first.size());
6871  write_ubjson(el.second, use_count, use_type, prefix_required);
6872  }
6873 
6874  if (not use_count)
6875  {
6876  oa->write_character(static_cast<CharType>('}'));
6877  }
6878 
6879  break;
6880  }
6881 
6882  default:
6883  break;
6884  }
6885  }
6886 
6887  private:
6888  /*
6889  @brief write a number to output input
6890 
6891  @param[in] n number of type @a NumberType
6892  @tparam NumberType the type of the number
6893 
6894  @note This function needs to respect the system's endianess, because bytes
6895  in CBOR, MessagePack, and UBJSON are stored in network order (big
6896  endian) and therefore need reordering on little endian systems.
6897  */
6898  template<typename NumberType>
6899  void write_number(const NumberType n)
6900  {
6901  // step 1: write number to array of length NumberType
6902  std::array<CharType, sizeof(NumberType)> vec;
6903  std::memcpy(vec.data(), &n, sizeof(NumberType));
6904 
6905  // step 2: write array to output (with possible reordering)
6906  if (is_little_endian)
6907  {
6908  // reverse byte order prior to conversion if necessary
6909  std::reverse(vec.begin(), vec.end());
6910  }
6911 
6912  oa->write_characters(vec.data(), sizeof(NumberType));
6913  }
6914 
6915  // UBJSON: write number (floating point)
6916  template<typename NumberType, typename std::enable_if<
6917  std::is_floating_point<NumberType>::value, int>::type = 0>
6918  void write_number_with_ubjson_prefix(const NumberType n,
6919  const bool add_prefix)
6920  {
6921  if (add_prefix)
6922  {
6923  oa->write_character(static_cast<CharType>('D')); // float64
6924  }
6925  write_number(n);
6926  }
6927 
6928  // UBJSON: write number (unsigned integer)
6929  template<typename NumberType, typename std::enable_if<
6930  std::is_unsigned<NumberType>::value, int>::type = 0>
6931  void write_number_with_ubjson_prefix(const NumberType n,
6932  const bool add_prefix)
6933  {
6934  if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
6935  {
6936  if (add_prefix)
6937  {
6938  oa->write_character(static_cast<CharType>('i')); // int8
6939  }
6940  write_number(static_cast<uint8_t>(n));
6941  }
6942  else if (n <= (std::numeric_limits<uint8_t>::max)())
6943  {
6944  if (add_prefix)
6945  {
6946  oa->write_character(static_cast<CharType>('U')); // uint8
6947  }
6948  write_number(static_cast<uint8_t>(n));
6949  }
6950  else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
6951  {
6952  if (add_prefix)
6953  {
6954  oa->write_character(static_cast<CharType>('I')); // int16
6955  }
6956  write_number(static_cast<int16_t>(n));
6957  }
6958  else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
6959  {
6960  if (add_prefix)
6961  {
6962  oa->write_character(static_cast<CharType>('l')); // int32
6963  }
6964  write_number(static_cast<int32_t>(n));
6965  }
6966  else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
6967  {
6968  if (add_prefix)
6969  {
6970  oa->write_character(static_cast<CharType>('L')); // int64
6971  }
6972  write_number(static_cast<int64_t>(n));
6973  }
6974  else
6975  {
6976  JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
6977  }
6978  }
6979 
6980  // UBJSON: write number (signed integer)
6981  template<typename NumberType, typename std::enable_if<
6982  std::is_signed<NumberType>::value and
6983  not std::is_floating_point<NumberType>::value, int>::type = 0>
6984  void write_number_with_ubjson_prefix(const NumberType n,
6985  const bool add_prefix)
6986  {
6987  if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
6988  {
6989  if (add_prefix)
6990  {
6991  oa->write_character(static_cast<CharType>('i')); // int8
6992  }
6993  write_number(static_cast<int8_t>(n));
6994  }
6995  else if (static_cast<int64_t>((std::numeric_limits<uint8_t>::min)()) <= n and n <= static_cast<int64_t>((std::numeric_limits<uint8_t>::max)()))
6996  {
6997  if (add_prefix)
6998  {
6999  oa->write_character(static_cast<CharType>('U')); // uint8
7000  }
7001  write_number(static_cast<uint8_t>(n));
7002  }
7003  else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
7004  {
7005  if (add_prefix)
7006  {
7007  oa->write_character(static_cast<CharType>('I')); // int16
7008  }
7009  write_number(static_cast<int16_t>(n));
7010  }
7011  else if ((std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
7012  {
7013  if (add_prefix)
7014  {
7015  oa->write_character(static_cast<CharType>('l')); // int32
7016  }
7017  write_number(static_cast<int32_t>(n));
7018  }
7019  else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
7020  {
7021  if (add_prefix)
7022  {
7023  oa->write_character(static_cast<CharType>('L')); // int64
7024  }
7025  write_number(static_cast<int64_t>(n));
7026  }
7027  // LCOV_EXCL_START
7028  else
7029  {
7030  JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n)));
7031  }
7032  // LCOV_EXCL_STOP
7033  }
7034 
7044  char ubjson_prefix(const BasicJsonType& j) const noexcept
7045  {
7046  switch (j.type())
7047  {
7048  case value_t::null:
7049  return 'Z';
7050 
7051  case value_t::boolean:
7052  return j.m_value.boolean ? 'T' : 'F';
7053 
7055  {
7056  if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
7057  {
7058  return 'i';
7059  }
7060  else if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7061  {
7062  return 'U';
7063  }
7064  else if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
7065  {
7066  return 'I';
7067  }
7068  else if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
7069  {
7070  return 'l';
7071  }
7072  else // no check and assume int64_t (see note above)
7073  {
7074  return 'L';
7075  }
7076  }
7077 
7079  {
7080  if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
7081  {
7082  return 'i';
7083  }
7084  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7085  {
7086  return 'U';
7087  }
7088  else if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
7089  {
7090  return 'I';
7091  }
7092  else if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
7093  {
7094  return 'l';
7095  }
7096  else // no check and assume int64_t (see note above)
7097  {
7098  return 'L';
7099  }
7100  }
7101 
7102  case value_t::number_float:
7103  return 'D';
7104 
7105  case value_t::string:
7106  return 'S';
7107 
7108  case value_t::array:
7109  return '[';
7110 
7111  case value_t::object:
7112  return '{';
7113 
7114  default: // discarded values
7115  return 'N';
7116  }
7117  }
7118 
7119  private:
7121  const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
7122 
7125 };
7126 }
7127 }
7128 
7129 // #include <nlohmann/detail/output/serializer.hpp>
7130 
7131 
7132 #include <algorithm> // reverse, remove, fill, find, none_of
7133 #include <array> // array
7134 #include <cassert> // assert
7135 #include <ciso646> // and, or
7136 #include <clocale> // localeconv, lconv
7137 #include <cmath> // labs, isfinite, isnan, signbit
7138 #include <cstddef> // size_t, ptrdiff_t
7139 #include <cstdint> // uint8_t
7140 #include <cstdio> // snprintf
7141 #include <iomanip> // setfill
7142 #include <iterator> // next
7143 #include <limits> // numeric_limits
7144 #include <string> // string
7145 #include <sstream> // stringstream
7146 #include <type_traits> // is_same
7147 
7148 // #include <nlohmann/detail/exceptions.hpp>
7149 
7150 // #include <nlohmann/detail/conversions/to_chars.hpp>
7151 
7152 
7153 #include <cassert> // assert
7154 #include <ciso646> // or, and, not
7155 #include <cmath> // signbit, isfinite
7156 #include <cstdint> // intN_t, uintN_t
7157 #include <cstring> // memcpy, memmove
7158 
7159 namespace nlohmann
7160 {
7161 namespace detail
7162 {
7163 
7183 namespace dtoa_impl
7184 {
7185 
7186 template <typename Target, typename Source>
7187 Target reinterpret_bits(const Source source)
7188 {
7189  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
7190 
7191  Target target;
7192  std::memcpy(&target, &source, sizeof(Source));
7193  return target;
7194 }
7195 
7196 struct diyfp // f * 2^e
7197 {
7198  static constexpr int kPrecision = 64; // = q
7199 
7200  uint64_t f;
7201  int e;
7202 
7203  constexpr diyfp() noexcept : f(0), e(0) {}
7204  constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
7205 
7210  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
7211  {
7212  assert(x.e == y.e);
7213  assert(x.f >= y.f);
7214 
7215  return diyfp(x.f - y.f, x.e);
7216  }
7217 
7222  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
7223  {
7224  static_assert(kPrecision == 64, "internal error");
7225 
7226  // Computes:
7227  // f = round((x.f * y.f) / 2^q)
7228  // e = x.e + y.e + q
7229 
7230  // Emulate the 64-bit * 64-bit multiplication:
7231  //
7232  // p = u * v
7233  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
7234  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
7235  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
7236  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
7237  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
7238  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
7239  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
7240  //
7241  // (Since Q might be larger than 2^32 - 1)
7242  //
7243  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
7244  //
7245  // (Q_hi + H does not overflow a 64-bit int)
7246  //
7247  // = p_lo + 2^64 p_hi
7248 
7249  const uint64_t u_lo = x.f & 0xFFFFFFFF;
7250  const uint64_t u_hi = x.f >> 32;
7251  const uint64_t v_lo = y.f & 0xFFFFFFFF;
7252  const uint64_t v_hi = y.f >> 32;
7253 
7254  const uint64_t p0 = u_lo * v_lo;
7255  const uint64_t p1 = u_lo * v_hi;
7256  const uint64_t p2 = u_hi * v_lo;
7257  const uint64_t p3 = u_hi * v_hi;
7258 
7259  const uint64_t p0_hi = p0 >> 32;
7260  const uint64_t p1_lo = p1 & 0xFFFFFFFF;
7261  const uint64_t p1_hi = p1 >> 32;
7262  const uint64_t p2_lo = p2 & 0xFFFFFFFF;
7263  const uint64_t p2_hi = p2 >> 32;
7264 
7265  uint64_t Q = p0_hi + p1_lo + p2_lo;
7266 
7267  // The full product might now be computed as
7268  //
7269  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
7270  // p_lo = p0_lo + (Q << 32)
7271  //
7272  // But in this particular case here, the full p_lo is not required.
7273  // Effectively we only need to add the highest bit in p_lo to p_hi (and
7274  // Q_hi + 1 does not overflow).
7275 
7276  Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
7277 
7278  const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
7279 
7280  return diyfp(h, x.e + y.e + 64);
7281  }
7282 
7287  static diyfp normalize(diyfp x) noexcept
7288  {
7289  assert(x.f != 0);
7290 
7291  while ((x.f >> 63) == 0)
7292  {
7293  x.f <<= 1;
7294  x.e--;
7295  }
7296 
7297  return x;
7298  }
7299 
7304  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
7305  {
7306  const int delta = x.e - target_exponent;
7307 
7308  assert(delta >= 0);
7309  assert(((x.f << delta) >> delta) == x.f);
7310 
7311  return diyfp(x.f << delta, target_exponent);
7312  }
7313 };
7314 
7316 {
7320 };
7321 
7328 template <typename FloatType>
7330 {
7331  assert(std::isfinite(value));
7332  assert(value > 0);
7333 
7334  // Convert the IEEE representation into a diyfp.
7335  //
7336  // If v is denormal:
7337  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
7338  // If v is normalized:
7339  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
7340 
7341  static_assert(std::numeric_limits<FloatType>::is_iec559,
7342  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
7343 
7344  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
7345  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
7346  constexpr int kMinExp = 1 - kBias;
7347  constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
7348 
7349  using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
7350 
7351  const uint64_t bits = reinterpret_bits<bits_type>(value);
7352  const uint64_t E = bits >> (kPrecision - 1);
7353  const uint64_t F = bits & (kHiddenBit - 1);
7354 
7355  const bool is_denormal = (E == 0);
7356  const diyfp v = is_denormal
7357  ? diyfp(F, kMinExp)
7358  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
7359 
7360  // Compute the boundaries m- and m+ of the floating-point value
7361  // v = f * 2^e.
7362  //
7363  // Determine v- and v+, the floating-point predecessor and successor if v,
7364  // respectively.
7365  //
7366  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
7367  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
7368  //
7369  // v+ = v + 2^e
7370  //
7371  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
7372  // between m- and m+ round to v, regardless of how the input rounding
7373  // algorithm breaks ties.
7374  //
7375  // ---+-------------+-------------+-------------+-------------+--- (A)
7376  // v- m- v m+ v+
7377  //
7378  // -----------------+------+------+-------------+-------------+--- (B)
7379  // v- m- v m+ v+
7380 
7381  const bool lower_boundary_is_closer = (F == 0 and E > 1);
7382  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
7383  const diyfp m_minus = lower_boundary_is_closer
7384  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
7385  : diyfp(2 * v.f - 1, v.e - 1); // (A)
7386 
7387  // Determine the normalized w+ = m+.
7388  const diyfp w_plus = diyfp::normalize(m_plus);
7389 
7390  // Determine w- = m- such that e_(w-) = e_(w+).
7391  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
7392 
7393  return {diyfp::normalize(v), w_minus, w_plus};
7394 }
7395 
7396 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
7397 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
7398 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
7399 //
7400 // alpha <= e = e_c + e_w + q <= gamma
7401 //
7402 // or
7403 //
7404 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
7405 // <= f_c * f_w * 2^gamma
7406 //
7407 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
7408 //
7409 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
7410 //
7411 // or
7412 //
7413 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
7414 //
7415 // The choice of (alpha,gamma) determines the size of the table and the form of
7416 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
7417 // in practice:
7418 //
7419 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
7420 // processed independently: An integral part p1, and a fractional part p2:
7421 //
7422 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
7423 // = (f div 2^-e) + (f mod 2^-e) * 2^e
7424 // = p1 + p2 * 2^e
7425 //
7426 // The conversion of p1 into decimal form requires a series of divisions and
7427 // modulos by (a power of) 10. These operations are faster for 32-bit than for
7428 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
7429 // achieved by choosing
7430 //
7431 // -e >= 32 or e <= -32 := gamma
7432 //
7433 // In order to convert the fractional part
7434 //
7435 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
7436 //
7437 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
7438 // d[-i] are extracted in order:
7439 //
7440 // (10 * p2) div 2^-e = d[-1]
7441 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
7442 //
7443 // The multiplication by 10 must not overflow. It is sufficient to choose
7444 //
7445 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
7446 //
7447 // Since p2 = f mod 2^-e < 2^-e,
7448 //
7449 // -e <= 60 or e >= -60 := alpha
7450 
7451 constexpr int kAlpha = -60;
7452 constexpr int kGamma = -32;
7453 
7454 struct cached_power // c = f * 2^e ~= 10^k
7455 {
7456  uint64_t f;
7457  int e;
7458  int k;
7459 };
7460 
7469 {
7470  // Now
7471  //
7472  // alpha <= e_c + e + q <= gamma (1)
7473  // ==> f_c * 2^alpha <= c * 2^e * 2^q
7474  //
7475  // and since the c's are normalized, 2^(q-1) <= f_c,
7476  //
7477  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
7478  // ==> 2^(alpha - e - 1) <= c
7479  //
7480  // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
7481  //
7482  // k = ceil( log_10( 2^(alpha - e - 1) ) )
7483  // = ceil( (alpha - e - 1) * log_10(2) )
7484  //
7485  // From the paper:
7486  // "In theory the result of the procedure could be wrong since c is rounded,
7487  // and the computation itself is approximated [...]. In practice, however,
7488  // this simple function is sufficient."
7489  //
7490  // For IEEE double precision floating-point numbers converted into
7491  // normalized diyfp's w = f * 2^e, with q = 64,
7492  //
7493  // e >= -1022 (min IEEE exponent)
7494  // -52 (p - 1)
7495  // -52 (p - 1, possibly normalize denormal IEEE numbers)
7496  // -11 (normalize the diyfp)
7497  // = -1137
7498  //
7499  // and
7500  //
7501  // e <= +1023 (max IEEE exponent)
7502  // -52 (p - 1)
7503  // -11 (normalize the diyfp)
7504  // = 960
7505  //
7506  // This binary exponent range [-1137,960] results in a decimal exponent
7507  // range [-307,324]. One does not need to store a cached power for each
7508  // k in this range. For each such k it suffices to find a cached power
7509  // such that the exponent of the product lies in [alpha,gamma].
7510  // This implies that the difference of the decimal exponents of adjacent
7511  // table entries must be less than or equal to
7512  //
7513  // floor( (gamma - alpha) * log_10(2) ) = 8.
7514  //
7515  // (A smaller distance gamma-alpha would require a larger table.)
7516 
7517  // NB:
7518  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
7519 
7520  constexpr int kCachedPowersSize = 79;
7521  constexpr int kCachedPowersMinDecExp = -300;
7522  constexpr int kCachedPowersDecStep = 8;
7523 
7524  static constexpr cached_power kCachedPowers[] =
7525  {
7526  { 0xAB70FE17C79AC6CA, -1060, -300 },
7527  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
7528  { 0xBE5691EF416BD60C, -1007, -284 },
7529  { 0x8DD01FAD907FFC3C, -980, -276 },
7530  { 0xD3515C2831559A83, -954, -268 },
7531  { 0x9D71AC8FADA6C9B5, -927, -260 },
7532  { 0xEA9C227723EE8BCB, -901, -252 },
7533  { 0xAECC49914078536D, -874, -244 },
7534  { 0x823C12795DB6CE57, -847, -236 },
7535  { 0xC21094364DFB5637, -821, -228 },
7536  { 0x9096EA6F3848984F, -794, -220 },
7537  { 0xD77485CB25823AC7, -768, -212 },
7538  { 0xA086CFCD97BF97F4, -741, -204 },
7539  { 0xEF340A98172AACE5, -715, -196 },
7540  { 0xB23867FB2A35B28E, -688, -188 },
7541  { 0x84C8D4DFD2C63F3B, -661, -180 },
7542  { 0xC5DD44271AD3CDBA, -635, -172 },
7543  { 0x936B9FCEBB25C996, -608, -164 },
7544  { 0xDBAC6C247D62A584, -582, -156 },
7545  { 0xA3AB66580D5FDAF6, -555, -148 },
7546  { 0xF3E2F893DEC3F126, -529, -140 },
7547  { 0xB5B5ADA8AAFF80B8, -502, -132 },
7548  { 0x87625F056C7C4A8B, -475, -124 },
7549  { 0xC9BCFF6034C13053, -449, -116 },
7550  { 0x964E858C91BA2655, -422, -108 },
7551  { 0xDFF9772470297EBD, -396, -100 },
7552  { 0xA6DFBD9FB8E5B88F, -369, -92 },
7553  { 0xF8A95FCF88747D94, -343, -84 },
7554  { 0xB94470938FA89BCF, -316, -76 },
7555  { 0x8A08F0F8BF0F156B, -289, -68 },
7556  { 0xCDB02555653131B6, -263, -60 },
7557  { 0x993FE2C6D07B7FAC, -236, -52 },
7558  { 0xE45C10C42A2B3B06, -210, -44 },
7559  { 0xAA242499697392D3, -183, -36 },
7560  { 0xFD87B5F28300CA0E, -157, -28 },
7561  { 0xBCE5086492111AEB, -130, -20 },
7562  { 0x8CBCCC096F5088CC, -103, -12 },
7563  { 0xD1B71758E219652C, -77, -4 },
7564  { 0x9C40000000000000, -50, 4 },
7565  { 0xE8D4A51000000000, -24, 12 },
7566  { 0xAD78EBC5AC620000, 3, 20 },
7567  { 0x813F3978F8940984, 30, 28 },
7568  { 0xC097CE7BC90715B3, 56, 36 },
7569  { 0x8F7E32CE7BEA5C70, 83, 44 },
7570  { 0xD5D238A4ABE98068, 109, 52 },
7571  { 0x9F4F2726179A2245, 136, 60 },
7572  { 0xED63A231D4C4FB27, 162, 68 },
7573  { 0xB0DE65388CC8ADA8, 189, 76 },
7574  { 0x83C7088E1AAB65DB, 216, 84 },
7575  { 0xC45D1DF942711D9A, 242, 92 },
7576  { 0x924D692CA61BE758, 269, 100 },
7577  { 0xDA01EE641A708DEA, 295, 108 },
7578  { 0xA26DA3999AEF774A, 322, 116 },
7579  { 0xF209787BB47D6B85, 348, 124 },
7580  { 0xB454E4A179DD1877, 375, 132 },
7581  { 0x865B86925B9BC5C2, 402, 140 },
7582  { 0xC83553C5C8965D3D, 428, 148 },
7583  { 0x952AB45CFA97A0B3, 455, 156 },
7584  { 0xDE469FBD99A05FE3, 481, 164 },
7585  { 0xA59BC234DB398C25, 508, 172 },
7586  { 0xF6C69A72A3989F5C, 534, 180 },
7587  { 0xB7DCBF5354E9BECE, 561, 188 },
7588  { 0x88FCF317F22241E2, 588, 196 },
7589  { 0xCC20CE9BD35C78A5, 614, 204 },
7590  { 0x98165AF37B2153DF, 641, 212 },
7591  { 0xE2A0B5DC971F303A, 667, 220 },
7592  { 0xA8D9D1535CE3B396, 694, 228 },
7593  { 0xFB9B7CD9A4A7443C, 720, 236 },
7594  { 0xBB764C4CA7A44410, 747, 244 },
7595  { 0x8BAB8EEFB6409C1A, 774, 252 },
7596  { 0xD01FEF10A657842C, 800, 260 },
7597  { 0x9B10A4E5E9913129, 827, 268 },
7598  { 0xE7109BFBA19C0C9D, 853, 276 },
7599  { 0xAC2820D9623BF429, 880, 284 },
7600  { 0x80444B5E7AA7CF85, 907, 292 },
7601  { 0xBF21E44003ACDD2D, 933, 300 },
7602  { 0x8E679C2F5E44FF8F, 960, 308 },
7603  { 0xD433179D9C8CB841, 986, 316 },
7604  { 0x9E19DB92B4E31BA9, 1013, 324 },
7605  };
7606 
7607  // This computation gives exactly the same results for k as
7608  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
7609  // for |e| <= 1500, but doesn't require floating-point operations.
7610  // NB: log_10(2) ~= 78913 / 2^18
7611  assert(e >= -1500);
7612  assert(e <= 1500);
7613  const int f = kAlpha - e - 1;
7614  const int k = (f * 78913) / (1 << 18) + (f > 0);
7615 
7616  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
7617  assert(index >= 0);
7618  assert(index < kCachedPowersSize);
7619  static_cast<void>(kCachedPowersSize); // Fix warning.
7620 
7621  const cached_power cached = kCachedPowers[index];
7622  assert(kAlpha <= cached.e + e + 64);
7623  assert(kGamma >= cached.e + e + 64);
7624 
7625  return cached;
7626 }
7627 
7632 inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
7633 {
7634  // LCOV_EXCL_START
7635  if (n >= 1000000000)
7636  {
7637  pow10 = 1000000000;
7638  return 10;
7639  }
7640  // LCOV_EXCL_STOP
7641  else if (n >= 100000000)
7642  {
7643  pow10 = 100000000;
7644  return 9;
7645  }
7646  else if (n >= 10000000)
7647  {
7648  pow10 = 10000000;
7649  return 8;
7650  }
7651  else if (n >= 1000000)
7652  {
7653  pow10 = 1000000;
7654  return 7;
7655  }
7656  else if (n >= 100000)
7657  {
7658  pow10 = 100000;
7659  return 6;
7660  }
7661  else if (n >= 10000)
7662  {
7663  pow10 = 10000;
7664  return 5;
7665  }
7666  else if (n >= 1000)
7667  {
7668  pow10 = 1000;
7669  return 4;
7670  }
7671  else if (n >= 100)
7672  {
7673  pow10 = 100;
7674  return 3;
7675  }
7676  else if (n >= 10)
7677  {
7678  pow10 = 10;
7679  return 2;
7680  }
7681  else
7682  {
7683  pow10 = 1;
7684  return 1;
7685  }
7686 }
7687 
7688 inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
7689  uint64_t rest, uint64_t ten_k)
7690 {
7691  assert(len >= 1);
7692  assert(dist <= delta);
7693  assert(rest <= delta);
7694  assert(ten_k > 0);
7695 
7696  // <--------------------------- delta ---->
7697  // <---- dist --------->
7698  // --------------[------------------+-------------------]--------------
7699  // M- w M+
7700  //
7701  // ten_k
7702  // <------>
7703  // <---- rest ---->
7704  // --------------[------------------+----+--------------]--------------
7705  // w V
7706  // = buf * 10^k
7707  //
7708  // ten_k represents a unit-in-the-last-place in the decimal representation
7709  // stored in buf.
7710  // Decrement buf by ten_k while this takes buf closer to w.
7711 
7712  // The tests are written in this order to avoid overflow in unsigned
7713  // integer arithmetic.
7714 
7715  while (rest < dist
7716  and delta - rest >= ten_k
7717  and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
7718  {
7719  assert(buf[len - 1] != '0');
7720  buf[len - 1]--;
7721  rest += ten_k;
7722  }
7723 }
7724 
7729 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
7730  diyfp M_minus, diyfp w, diyfp M_plus)
7731 {
7732  static_assert(kAlpha >= -60, "internal error");
7733  static_assert(kGamma <= -32, "internal error");
7734 
7735  // Generates the digits (and the exponent) of a decimal floating-point
7736  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
7737  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
7738  //
7739  // <--------------------------- delta ---->
7740  // <---- dist --------->
7741  // --------------[------------------+-------------------]--------------
7742  // M- w M+
7743  //
7744  // Grisu2 generates the digits of M+ from left to right and stops as soon as
7745  // V is in [M-,M+].
7746 
7747  assert(M_plus.e >= kAlpha);
7748  assert(M_plus.e <= kGamma);
7749 
7750  uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
7751  uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
7752 
7753  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
7754  //
7755  // M+ = f * 2^e
7756  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
7757  // = ((p1 ) * 2^-e + (p2 )) * 2^e
7758  // = p1 + p2 * 2^e
7759 
7760  const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
7761 
7762  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.)
7763  uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
7764 
7765  // 1)
7766  //
7767  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
7768 
7769  assert(p1 > 0);
7770 
7771  uint32_t pow10;
7772  const int k = find_largest_pow10(p1, pow10);
7773 
7774  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
7775  //
7776  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
7777  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
7778  //
7779  // M+ = p1 + p2 * 2^e
7780  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
7781  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
7782  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
7783  //
7784  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
7785  //
7786  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
7787  //
7788  // but stop as soon as
7789  //
7790  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
7791 
7792  int n = k;
7793  while (n > 0)
7794  {
7795  // Invariants:
7796  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
7797  // pow10 = 10^(n-1) <= p1 < 10^n
7798  //
7799  const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
7800  const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
7801  //
7802  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
7803  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
7804  //
7805  assert(d <= 9);
7806  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7807  //
7808  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
7809  //
7810  p1 = r;
7811  n--;
7812  //
7813  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
7814  // pow10 = 10^n
7815  //
7816 
7817  // Now check if enough digits have been generated.
7818  // Compute
7819  //
7820  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
7821  //
7822  // Note:
7823  // Since rest and delta share the same exponent e, it suffices to
7824  // compare the significands.
7825  const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
7826  if (rest <= delta)
7827  {
7828  // V = buffer * 10^n, with M- <= V <= M+.
7829 
7830  decimal_exponent += n;
7831 
7832  // We may now just stop. But instead look if the buffer could be
7833  // decremented to bring V closer to w.
7834  //
7835  // pow10 = 10^n is now 1 ulp in the decimal representation V.
7836  // The rounding procedure works with diyfp's with an implicit
7837  // exponent of e.
7838  //
7839  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
7840  //
7841  const uint64_t ten_n = uint64_t{pow10} << -one.e;
7842  grisu2_round(buffer, length, dist, delta, rest, ten_n);
7843 
7844  return;
7845  }
7846 
7847  pow10 /= 10;
7848  //
7849  // pow10 = 10^(n-1) <= p1 < 10^n
7850  // Invariants restored.
7851  }
7852 
7853  // 2)
7854  //
7855  // The digits of the integral part have been generated:
7856  //
7857  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
7858  // = buffer + p2 * 2^e
7859  //
7860  // Now generate the digits of the fractional part p2 * 2^e.
7861  //
7862  // Note:
7863  // No decimal point is generated: the exponent is adjusted instead.
7864  //
7865  // p2 actually represents the fraction
7866  //
7867  // p2 * 2^e
7868  // = p2 / 2^-e
7869  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
7870  //
7871  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
7872  //
7873  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
7874  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
7875  //
7876  // using
7877  //
7878  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
7879  // = ( d) * 2^-e + ( r)
7880  //
7881  // or
7882  // 10^m * p2 * 2^e = d + r * 2^e
7883  //
7884  // i.e.
7885  //
7886  // M+ = buffer + p2 * 2^e
7887  // = buffer + 10^-m * (d + r * 2^e)
7888  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
7889  //
7890  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
7891 
7892  assert(p2 > delta);
7893 
7894  int m = 0;
7895  for (;;)
7896  {
7897  // Invariant:
7898  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
7899  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
7900  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
7901  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
7902  //
7903  assert(p2 <= UINT64_MAX / 10);
7904  p2 *= 10;
7905  const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
7906  const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
7907  //
7908  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
7909  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
7910  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
7911  //
7912  assert(d <= 9);
7913  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
7914  //
7915  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
7916  //
7917  p2 = r;
7918  m++;
7919  //
7920  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
7921  // Invariant restored.
7922 
7923  // Check if enough digits have been generated.
7924  //
7925  // 10^-m * p2 * 2^e <= delta * 2^e
7926  // p2 * 2^e <= 10^m * delta * 2^e
7927  // p2 <= 10^m * delta
7928  delta *= 10;
7929  dist *= 10;
7930  if (p2 <= delta)
7931  {
7932  break;
7933  }
7934  }
7935 
7936  // V = buffer * 10^-m, with M- <= V <= M+.
7937 
7938  decimal_exponent -= m;
7939 
7940  // 1 ulp in the decimal representation is now 10^-m.
7941  // Since delta and dist are now scaled by 10^m, we need to do the
7942  // same with ulp in order to keep the units in sync.
7943  //
7944  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
7945  //
7946  const uint64_t ten_m = one.f;
7947  grisu2_round(buffer, length, dist, delta, p2, ten_m);
7948 
7949  // By construction this algorithm generates the shortest possible decimal
7950  // number (Loitsch, Theorem 6.2) which rounds back to w.
7951  // For an input number of precision p, at least
7952  //
7953  // N = 1 + ceil(p * log_10(2))
7954  //
7955  // decimal digits are sufficient to identify all binary floating-point
7956  // numbers (Matula, "In-and-Out conversions").
7957  // This implies that the algorithm does not produce more than N decimal
7958  // digits.
7959  //
7960  // N = 17 for p = 53 (IEEE double precision)
7961  // N = 9 for p = 24 (IEEE single precision)
7962 }
7963 
7969 inline void grisu2(char* buf, int& len, int& decimal_exponent,
7970  diyfp m_minus, diyfp v, diyfp m_plus)
7971 {
7972  assert(m_plus.e == m_minus.e);
7973  assert(m_plus.e == v.e);
7974 
7975  // --------(-----------------------+-----------------------)-------- (A)
7976  // m- v m+
7977  //
7978  // --------------------(-----------+-----------------------)-------- (B)
7979  // m- v m+
7980  //
7981  // First scale v (and m- and m+) such that the exponent is in the range
7982  // [alpha, gamma].
7983 
7984  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
7985 
7986  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
7987 
7988  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
7989  const diyfp w = diyfp::mul(v, c_minus_k);
7990  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
7991  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
7992 
7993  // ----(---+---)---------------(---+---)---------------(---+---)----
7994  // w- w w+
7995  // = c*m- = c*v = c*m+
7996  //
7997  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
7998  // w+ are now off by a small amount.
7999  // In fact:
8000  //
8001  // w - v * 10^k < 1 ulp
8002  //
8003  // To account for this inaccuracy, add resp. subtract 1 ulp.
8004  //
8005  // --------+---[---------------(---+---)---------------]---+--------
8006  // w- M- w M+ w+
8007  //
8008  // Now any number in [M-, M+] (bounds included) will round to w when input,
8009  // regardless of how the input rounding algorithm breaks ties.
8010  //
8011  // And digit_gen generates the shortest possible such number in [M-, M+].
8012  // Note that this does not mean that Grisu2 always generates the shortest
8013  // possible number in the interval (m-, m+).
8014  const diyfp M_minus(w_minus.f + 1, w_minus.e);
8015  const diyfp M_plus (w_plus.f - 1, w_plus.e );
8016 
8017  decimal_exponent = -cached.k; // = -(-k) = k
8018 
8019  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
8020 }
8021 
8027 template <typename FloatType>
8028 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
8029 {
8030  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
8031  "internal error: not enough precision");
8032 
8033  assert(std::isfinite(value));
8034  assert(value > 0);
8035 
8036  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
8037  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
8038  // decimal representations are not exactly "short".
8039  //
8040  // The documentation for 'std::to_chars' (http://en.cppreference.com/w/cpp/utility/to_chars)
8041  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
8042  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
8043  // does.
8044  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
8045  // representation using the corresponding std::from_chars function recovers value exactly". That
8046  // indicates that single precision floating-point numbers should be recovered using
8047  // 'std::strtof'.
8048  //
8049  // NB: If the neighbors are computed for single-precision numbers, there is a single float
8050  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
8051  // value is off by 1 ulp.
8052 #if 0
8053  const boundaries w = compute_boundaries(static_cast<double>(value));
8054 #else
8055  const boundaries w = compute_boundaries(value);
8056 #endif
8057 
8058  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
8059 }
8060 
8066 inline char* append_exponent(char* buf, int e)
8067 {
8068  assert(e > -1000);
8069  assert(e < 1000);
8070 
8071  if (e < 0)
8072  {
8073  e = -e;
8074  *buf++ = '-';
8075  }
8076  else
8077  {
8078  *buf++ = '+';
8079  }
8080 
8081  uint32_t k = static_cast<uint32_t>(e);
8082  if (k < 10)
8083  {
8084  // Always print at least two digits in the exponent.
8085  // This is for compatibility with printf("%g").
8086  *buf++ = '0';
8087  *buf++ = static_cast<char>('0' + k);
8088  }
8089  else if (k < 100)
8090  {
8091  *buf++ = static_cast<char>('0' + k / 10);
8092  k %= 10;
8093  *buf++ = static_cast<char>('0' + k);
8094  }
8095  else
8096  {
8097  *buf++ = static_cast<char>('0' + k / 100);
8098  k %= 100;
8099  *buf++ = static_cast<char>('0' + k / 10);
8100  k %= 10;
8101  *buf++ = static_cast<char>('0' + k);
8102  }
8103 
8104  return buf;
8105 }
8106 
8116 inline char* format_buffer(char* buf, int len, int decimal_exponent,
8117  int min_exp, int max_exp)
8118 {
8119  assert(min_exp < 0);
8120  assert(max_exp > 0);
8121 
8122  const int k = len;
8123  const int n = len + decimal_exponent;
8124 
8125  // v = buf * 10^(n-k)
8126  // k is the length of the buffer (number of decimal digits)
8127  // n is the position of the decimal point relative to the start of the buffer.
8128 
8129  if (k <= n and n <= max_exp)
8130  {
8131  // digits[000]
8132  // len <= max_exp + 2
8133 
8134  std::memset(buf + k, '0', static_cast<size_t>(n - k));
8135  // Make it look like a floating-point number (#362, #378)
8136  buf[n + 0] = '.';
8137  buf[n + 1] = '0';
8138  return buf + (n + 2);
8139  }
8140 
8141  if (0 < n and n <= max_exp)
8142  {
8143  // dig.its
8144  // len <= max_digits10 + 1
8145 
8146  assert(k > n);
8147 
8148  std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
8149  buf[n] = '.';
8150  return buf + (k + 1);
8151  }
8152 
8153  if (min_exp < n and n <= 0)
8154  {
8155  // 0.[000]digits
8156  // len <= 2 + (-min_exp - 1) + max_digits10
8157 
8158  std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
8159  buf[0] = '0';
8160  buf[1] = '.';
8161  std::memset(buf + 2, '0', static_cast<size_t>(-n));
8162  return buf + (2 + (-n) + k);
8163  }
8164 
8165  if (k == 1)
8166  {
8167  // dE+123
8168  // len <= 1 + 5
8169 
8170  buf += 1;
8171  }
8172  else
8173  {
8174  // d.igitsE+123
8175  // len <= max_digits10 + 1 + 5
8176 
8177  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
8178  buf[1] = '.';
8179  buf += 1 + k;
8180  }
8181 
8182  *buf++ = 'e';
8183  return append_exponent(buf, n - 1);
8184 }
8185 
8186 } // namespace dtoa_impl
8187 
8198 template <typename FloatType>
8199 char* to_chars(char* first, char* last, FloatType value)
8200 {
8201  static_cast<void>(last); // maybe unused - fix warning
8202  assert(std::isfinite(value));
8203 
8204  // Use signbit(value) instead of (value < 0) since signbit works for -0.
8205  if (std::signbit(value))
8206  {
8207  value = -value;
8208  *first++ = '-';
8209  }
8210 
8211  if (value == 0) // +-0
8212  {
8213  *first++ = '0';
8214  // Make it look like a floating-point number (#362, #378)
8215  *first++ = '.';
8216  *first++ = '0';
8217  return first;
8218  }
8219 
8220  assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
8221 
8222  // Compute v = buffer * 10^decimal_exponent.
8223  // The decimal digits are stored in the buffer, which needs to be interpreted
8224  // as an unsigned decimal integer.
8225  // len is the length of the buffer, i.e. the number of decimal digits.
8226  int len = 0;
8227  int decimal_exponent = 0;
8228  dtoa_impl::grisu2(first, len, decimal_exponent, value);
8229 
8230  assert(len <= std::numeric_limits<FloatType>::max_digits10);
8231 
8232  // Format the buffer like printf("%.*g", prec, value)
8233  constexpr int kMinExp = -4;
8234  // Use digits10 here to increase compatibility with version 2.
8235  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
8236 
8237  assert(last - first >= kMaxExp + 2);
8238  assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
8239  assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
8240 
8241  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
8242 }
8243 
8244 } // namespace detail
8245 } // namespace nlohmann
8246 
8247 // #include <nlohmann/detail/macro_scope.hpp>
8248 
8249 // #include <nlohmann/detail/meta.hpp>
8250 
8251 // #include <nlohmann/detail/output/output_adapters.hpp>
8252 
8253 // #include <nlohmann/detail/value_t.hpp>
8254 
8255 
8256 namespace nlohmann
8257 {
8258 namespace detail
8259 {
8261 // serialization //
8263 
8264 template<typename BasicJsonType>
8266 {
8267  using string_t = typename BasicJsonType::string_t;
8268  using number_float_t = typename BasicJsonType::number_float_t;
8269  using number_integer_t = typename BasicJsonType::number_integer_t;
8270  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8271  static constexpr uint8_t UTF8_ACCEPT = 0;
8272  static constexpr uint8_t UTF8_REJECT = 1;
8273 
8274  public:
8279  serializer(output_adapter_t<char> s, const char ichar)
8280  : o(std::move(s)), loc(std::localeconv()),
8281  thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep)),
8282  decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point)),
8283  indent_char(ichar), indent_string(512, indent_char)
8284  {}
8285 
8286  // delete because of pointer members
8287  serializer(const serializer&) = delete;
8288  serializer& operator=(const serializer&) = delete;
8289 
8307  void dump(const BasicJsonType& val, const bool pretty_print,
8308  const bool ensure_ascii,
8309  const unsigned int indent_step,
8310  const unsigned int current_indent = 0)
8311  {
8312  switch (val.m_type)
8313  {
8314  case value_t::object:
8315  {
8316  if (val.m_value.object->empty())
8317  {
8318  o->write_characters("{}", 2);
8319  return;
8320  }
8321 
8322  if (pretty_print)
8323  {
8324  o->write_characters("{\n", 2);
8325 
8326  // variable to hold indentation for recursive calls
8327  const auto new_indent = current_indent + indent_step;
8328  if (JSON_UNLIKELY(indent_string.size() < new_indent))
8329  {
8330  indent_string.resize(indent_string.size() * 2, ' ');
8331  }
8332 
8333  // first n-1 elements
8334  auto i = val.m_value.object->cbegin();
8335  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8336  {
8337  o->write_characters(indent_string.c_str(), new_indent);
8338  o->write_character('\"');
8339  dump_escaped(i->first, ensure_ascii);
8340  o->write_characters("\": ", 3);
8341  dump(i->second, true, ensure_ascii, indent_step, new_indent);
8342  o->write_characters(",\n", 2);
8343  }
8344 
8345  // last element
8346  assert(i != val.m_value.object->cend());
8347  assert(std::next(i) == val.m_value.object->cend());
8348  o->write_characters(indent_string.c_str(), new_indent);
8349  o->write_character('\"');
8350  dump_escaped(i->first, ensure_ascii);
8351  o->write_characters("\": ", 3);
8352  dump(i->second, true, ensure_ascii, indent_step, new_indent);
8353 
8354  o->write_character('\n');
8355  o->write_characters(indent_string.c_str(), current_indent);
8356  o->write_character('}');
8357  }
8358  else
8359  {
8360  o->write_character('{');
8361 
8362  // first n-1 elements
8363  auto i = val.m_value.object->cbegin();
8364  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
8365  {
8366  o->write_character('\"');
8367  dump_escaped(i->first, ensure_ascii);
8368  o->write_characters("\":", 2);
8369  dump(i->second, false, ensure_ascii, indent_step, current_indent);
8370  o->write_character(',');
8371  }
8372 
8373  // last element
8374  assert(i != val.m_value.object->cend());
8375  assert(std::next(i) == val.m_value.object->cend());
8376  o->write_character('\"');
8377  dump_escaped(i->first, ensure_ascii);
8378  o->write_characters("\":", 2);
8379  dump(i->second, false, ensure_ascii, indent_step, current_indent);
8380 
8381  o->write_character('}');
8382  }
8383 
8384  return;
8385  }
8386 
8387  case value_t::array:
8388  {
8389  if (val.m_value.array->empty())
8390  {
8391  o->write_characters("[]", 2);
8392  return;
8393  }
8394 
8395  if (pretty_print)
8396  {
8397  o->write_characters("[\n", 2);
8398 
8399  // variable to hold indentation for recursive calls
8400  const auto new_indent = current_indent + indent_step;
8401  if (JSON_UNLIKELY(indent_string.size() < new_indent))
8402  {
8403  indent_string.resize(indent_string.size() * 2, ' ');
8404  }
8405 
8406  // first n-1 elements
8407  for (auto i = val.m_value.array->cbegin();
8408  i != val.m_value.array->cend() - 1; ++i)
8409  {
8410  o->write_characters(indent_string.c_str(), new_indent);
8411  dump(*i, true, ensure_ascii, indent_step, new_indent);
8412  o->write_characters(",\n", 2);
8413  }
8414 
8415  // last element
8416  assert(not val.m_value.array->empty());
8417  o->write_characters(indent_string.c_str(), new_indent);
8418  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
8419 
8420  o->write_character('\n');
8421  o->write_characters(indent_string.c_str(), current_indent);
8422  o->write_character(']');
8423  }
8424  else
8425  {
8426  o->write_character('[');
8427 
8428  // first n-1 elements
8429  for (auto i = val.m_value.array->cbegin();
8430  i != val.m_value.array->cend() - 1; ++i)
8431  {
8432  dump(*i, false, ensure_ascii, indent_step, current_indent);
8433  o->write_character(',');
8434  }
8435 
8436  // last element
8437  assert(not val.m_value.array->empty());
8438  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
8439 
8440  o->write_character(']');
8441  }
8442 
8443  return;
8444  }
8445 
8446  case value_t::string:
8447  {
8448  o->write_character('\"');
8449  dump_escaped(*val.m_value.string, ensure_ascii);
8450  o->write_character('\"');
8451  return;
8452  }
8453 
8454  case value_t::boolean:
8455  {
8456  if (val.m_value.boolean)
8457  {
8458  o->write_characters("true", 4);
8459  }
8460  else
8461  {
8462  o->write_characters("false", 5);
8463  }
8464  return;
8465  }
8466 
8468  {
8469  dump_integer(val.m_value.number_integer);
8470  return;
8471  }
8472 
8474  {
8475  dump_integer(val.m_value.number_unsigned);
8476  return;
8477  }
8478 
8479  case value_t::number_float:
8480  {
8481  dump_float(val.m_value.number_float);
8482  return;
8483  }
8484 
8485  case value_t::discarded:
8486  {
8487  o->write_characters("<discarded>", 11);
8488  return;
8489  }
8490 
8491  case value_t::null:
8492  {
8493  o->write_characters("null", 4);
8494  return;
8495  }
8496  }
8497  }
8498 
8499  private:
8514  void dump_escaped(const string_t& s, const bool ensure_ascii)
8515  {
8516  uint32_t codepoint;
8517  uint8_t state = UTF8_ACCEPT;
8518  std::size_t bytes = 0; // number of bytes written to string_buffer
8519 
8520  for (std::size_t i = 0; i < s.size(); ++i)
8521  {
8522  const auto byte = static_cast<uint8_t>(s[i]);
8523 
8524  switch (decode(state, codepoint, byte))
8525  {
8526  case UTF8_ACCEPT: // decode found a new code point
8527  {
8528  switch (codepoint)
8529  {
8530  case 0x08: // backspace
8531  {
8532  string_buffer[bytes++] = '\\';
8533  string_buffer[bytes++] = 'b';
8534  break;
8535  }
8536 
8537  case 0x09: // horizontal tab
8538  {
8539  string_buffer[bytes++] = '\\';
8540  string_buffer[bytes++] = 't';
8541  break;
8542  }
8543 
8544  case 0x0A: // newline
8545  {
8546  string_buffer[bytes++] = '\\';
8547  string_buffer[bytes++] = 'n';
8548  break;
8549  }
8550 
8551  case 0x0C: // formfeed
8552  {
8553  string_buffer[bytes++] = '\\';
8554  string_buffer[bytes++] = 'f';
8555  break;
8556  }
8557 
8558  case 0x0D: // carriage return
8559  {
8560  string_buffer[bytes++] = '\\';
8561  string_buffer[bytes++] = 'r';
8562  break;
8563  }
8564 
8565  case 0x22: // quotation mark
8566  {
8567  string_buffer[bytes++] = '\\';
8568  string_buffer[bytes++] = '\"';
8569  break;
8570  }
8571 
8572  case 0x5C: // reverse solidus
8573  {
8574  string_buffer[bytes++] = '\\';
8575  string_buffer[bytes++] = '\\';
8576  break;
8577  }
8578 
8579  default:
8580  {
8581  // escape control characters (0x00..0x1F) or, if
8582  // ensure_ascii parameter is used, non-ASCII characters
8583  if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
8584  {
8585  if (codepoint <= 0xFFFF)
8586  {
8587  std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
8588  static_cast<uint16_t>(codepoint));
8589  bytes += 6;
8590  }
8591  else
8592  {
8593  std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
8594  static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
8595  static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
8596  bytes += 12;
8597  }
8598  }
8599  else
8600  {
8601  // copy byte to buffer (all previous bytes
8602  // been copied have in default case above)
8603  string_buffer[bytes++] = s[i];
8604  }
8605  break;
8606  }
8607  }
8608 
8609  // write buffer and reset index; there must be 13 bytes
8610  // left, as this is the maximal number of bytes to be
8611  // written ("\uxxxx\uxxxx\0") for one code point
8612  if (string_buffer.size() - bytes < 13)
8613  {
8614  o->write_characters(string_buffer.data(), bytes);
8615  bytes = 0;
8616  }
8617  break;
8618  }
8619 
8620  case UTF8_REJECT: // decode found invalid UTF-8 byte
8621  {
8622  std::stringstream ss;
8623  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(byte);
8624  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str()));
8625  }
8626 
8627  default: // decode found yet incomplete multi-byte code point
8628  {
8629  if (not ensure_ascii)
8630  {
8631  // code point will not be escaped - copy byte to buffer
8632  string_buffer[bytes++] = s[i];
8633  }
8634  break;
8635  }
8636  }
8637  }
8638 
8639  if (JSON_LIKELY(state == UTF8_ACCEPT))
8640  {
8641  // write buffer
8642  if (bytes > 0)
8643  {
8644  o->write_characters(string_buffer.data(), bytes);
8645  }
8646  }
8647  else
8648  {
8649  // we finish reading, but do not accept: string was incomplete
8650  std::stringstream ss;
8651  ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << static_cast<int>(static_cast<uint8_t>(s.back()));
8652  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str()));
8653  }
8654  }
8655 
8665  template<typename NumberType, detail::enable_if_t<
8666  std::is_same<NumberType, number_unsigned_t>::value or
8667  std::is_same<NumberType, number_integer_t>::value,
8668  int> = 0>
8669  void dump_integer(NumberType x)
8670  {
8671  // special case for "0"
8672  if (x == 0)
8673  {
8674  o->write_character('0');
8675  return;
8676  }
8677 
8678  const bool is_negative = (x <= 0) and (x != 0); // see issue #755
8679  std::size_t i = 0;
8680 
8681  while (x != 0)
8682  {
8683  // spare 1 byte for '\0'
8684  assert(i < number_buffer.size() - 1);
8685 
8686  const auto digit = std::labs(static_cast<long>(x % 10));
8687  number_buffer[i++] = static_cast<char>('0' + digit);
8688  x /= 10;
8689  }
8690 
8691  if (is_negative)
8692  {
8693  // make sure there is capacity for the '-'
8694  assert(i < number_buffer.size() - 2);
8695  number_buffer[i++] = '-';
8696  }
8697 
8698  std::reverse(number_buffer.begin(), number_buffer.begin() + i);
8699  o->write_characters(number_buffer.data(), i);
8700  }
8701 
8711  {
8712  // NaN / inf
8713  if (not std::isfinite(x))
8714  {
8715  o->write_characters("null", 4);
8716  return;
8717  }
8718 
8719  // If number_float_t is an IEEE-754 single or double precision number,
8720  // use the Grisu2 algorithm to produce short numbers which are
8721  // guaranteed to round-trip, using strtof and strtod, resp.
8722  //
8723  // NB: The test below works if <long double> == <double>.
8724  static constexpr bool is_ieee_single_or_double
8725  = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
8726  (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
8727 
8728  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
8729  }
8730 
8731  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
8732  {
8733  char* begin = number_buffer.data();
8734  char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
8735 
8736  o->write_characters(begin, static_cast<size_t>(end - begin));
8737  }
8738 
8739  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
8740  {
8741  // get number of digits for a float -> text -> float round-trip
8742  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
8743 
8744  // the actual conversion
8745  std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
8746 
8747  // negative value indicates an error
8748  assert(len > 0);
8749  // check if buffer was large enough
8750  assert(static_cast<std::size_t>(len) < number_buffer.size());
8751 
8752  // erase thousands separator
8753  if (thousands_sep != '\0')
8754  {
8755  const auto end = std::remove(number_buffer.begin(),
8756  number_buffer.begin() + len, thousands_sep);
8757  std::fill(end, number_buffer.end(), '\0');
8758  assert((end - number_buffer.begin()) <= len);
8759  len = (end - number_buffer.begin());
8760  }
8761 
8762  // convert decimal point to '.'
8763  if (decimal_point != '\0' and decimal_point != '.')
8764  {
8765  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
8766  if (dec_pos != number_buffer.end())
8767  {
8768  *dec_pos = '.';
8769  }
8770  }
8771 
8772  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
8773 
8774  // determine if need to append ".0"
8775  const bool value_is_int_like =
8776  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
8777  [](char c)
8778  {
8779  return (c == '.' or c == 'e');
8780  });
8781 
8782  if (value_is_int_like)
8783  {
8784  o->write_characters(".0", 2);
8785  }
8786  }
8787 
8809  static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
8810  {
8811  static const std::array<uint8_t, 400> utf8d =
8812  {
8813  {
8814  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
8815  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
8816  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
8817  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
8818  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
8819  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
8820  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
8821  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
8822  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
8823  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
8824  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
8825  1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
8826  1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
8827  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
8828  }
8829  };
8830 
8831  const uint8_t type = utf8d[byte];
8832 
8833  codep = (state != UTF8_ACCEPT)
8834  ? (byte & 0x3fu) | (codep << 6)
8835  : static_cast<uint32_t>(0xff >> type) & (byte);
8836 
8837  state = utf8d[256u + state * 16u + type];
8838  return state;
8839  }
8840 
8841  private:
8844 
8846  std::array<char, 64> number_buffer{{}};
8847 
8849  const std::lconv* loc = nullptr;
8851  const char thousands_sep = '\0';
8853  const char decimal_point = '\0';
8854 
8856  std::array<char, 512> string_buffer{{}};
8857 
8859  const char indent_char;
8862 };
8863 }
8864 }
8865 
8866 // #include <nlohmann/detail/json_ref.hpp>
8867 
8868 
8869 #include <initializer_list>
8870 #include <utility>
8871 
8872 namespace nlohmann
8873 {
8874 namespace detail
8875 {
8876 template<typename BasicJsonType>
8878 {
8879  public:
8880  using value_type = BasicJsonType;
8881 
8883  : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
8884  {}
8885 
8886  json_ref(const value_type& value)
8887  : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
8888  {}
8889 
8890  json_ref(std::initializer_list<json_ref> init)
8891  : owned_value(init), value_ref(&owned_value), is_rvalue(true)
8892  {}
8893 
8894  template<class... Args>
8895  json_ref(Args&& ... args)
8896  : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
8897  {}
8898 
8899  // class should be movable only
8900  json_ref(json_ref&&) = default;
8901  json_ref(const json_ref&) = delete;
8902  json_ref& operator=(const json_ref&) = delete;
8903 
8905  {
8906  if (is_rvalue)
8907  {
8908  return std::move(*value_ref);
8909  }
8910  return *value_ref;
8911  }
8912 
8913  value_type const& operator*() const
8914  {
8915  return *static_cast<value_type const*>(value_ref);
8916  }
8917 
8918  value_type const* operator->() const
8919  {
8920  return static_cast<value_type const*>(value_ref);
8921  }
8922 
8923  private:
8924  mutable value_type owned_value = nullptr;
8925  value_type* value_ref = nullptr;
8926  const bool is_rvalue;
8927 };
8928 }
8929 }
8930 
8931 // #include <nlohmann/detail/json_pointer.hpp>
8932 
8933 
8934 #include <cassert> // assert
8935 #include <numeric> // accumulate
8936 #include <string> // string
8937 #include <vector> // vector
8938 
8939 // #include <nlohmann/detail/macro_scope.hpp>
8940 
8941 // #include <nlohmann/detail/exceptions.hpp>
8942 
8943 // #include <nlohmann/detail/value_t.hpp>
8944 
8945 
8946 namespace nlohmann
8947 {
8948 template<typename BasicJsonType>
8949 class json_pointer
8950 {
8951  // allow basic_json to access private members
8953  friend class basic_json;
8954 
8955  public:
8977  explicit json_pointer(const std::string& s = "")
8978  : reference_tokens(split(s))
8979  {}
8980 
8996  std::string to_string() const noexcept
8997  {
8998  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8999  std::string{},
9000  [](const std::string & a, const std::string & b)
9001  {
9002  return a + "/" + escape(b);
9003  });
9004  }
9005 
9007  operator std::string() const
9008  {
9009  return to_string();
9010  }
9011 
9019  static int array_index(const std::string& s)
9020  {
9021  std::size_t processed_chars = 0;
9022  const int res = std::stoi(s, &processed_chars);
9023 
9024  // check if the string was completely read
9025  if (JSON_UNLIKELY(processed_chars != s.size()))
9026  {
9027  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
9028  }
9029 
9030  return res;
9031  }
9032 
9033  private:
9039  {
9040  if (JSON_UNLIKELY(is_root()))
9041  {
9042  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
9043  }
9044 
9045  auto last = reference_tokens.back();
9046  reference_tokens.pop_back();
9047  return last;
9048  }
9049 
9051  bool is_root() const
9052  {
9053  return reference_tokens.empty();
9054  }
9055 
9057  {
9058  if (JSON_UNLIKELY(is_root()))
9059  {
9060  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
9061  }
9062 
9063  json_pointer result = *this;
9064  result.reference_tokens = {reference_tokens[0]};
9065  return result;
9066  }
9067 
9076  BasicJsonType& get_and_create(BasicJsonType& j) const
9077  {
9078  using size_type = typename BasicJsonType::size_type;
9079  auto result = &j;
9080 
9081  // in case no reference tokens exist, return a reference to the JSON value
9082  // j which will be overwritten by a primitive value
9083  for (const auto& reference_token : reference_tokens)
9084  {
9085  switch (result->m_type)
9086  {
9087  case detail::value_t::null:
9088  {
9089  if (reference_token == "0")
9090  {
9091  // start a new array if reference token is 0
9092  result = &result->operator[](0);
9093  }
9094  else
9095  {
9096  // start a new object otherwise
9097  result = &result->operator[](reference_token);
9098  }
9099  break;
9100  }
9101 
9103  {
9104  // create an entry in the object
9105  result = &result->operator[](reference_token);
9106  break;
9107  }
9108 
9110  {
9111  // create an entry in the array
9112  JSON_TRY
9113  {
9114  result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
9115  }
9116  JSON_CATCH(std::invalid_argument&)
9117  {
9118  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9119  }
9120  break;
9121  }
9122 
9123  /*
9124  The following code is only reached if there exists a reference
9125  token _and_ the current value is primitive. In this case, we have
9126  an error situation, because primitive values may only occur as
9127  single value; that is, with an empty list of reference tokens.
9128  */
9129  default:
9130  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
9131  }
9132  }
9133 
9134  return *result;
9135  }
9136 
9156  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
9157  {
9158  using size_type = typename BasicJsonType::size_type;
9159  for (const auto& reference_token : reference_tokens)
9160  {
9161  // convert null values to arrays or objects before continuing
9162  if (ptr->m_type == detail::value_t::null)
9163  {
9164  // check if reference token is a number
9165  const bool nums =
9166  std::all_of(reference_token.begin(), reference_token.end(),
9167  [](const char x)
9168  {
9169  return (x >= '0' and x <= '9');
9170  });
9171 
9172  // change value to array for numbers or "-" or to object otherwise
9173  *ptr = (nums or reference_token == "-")
9176  }
9177 
9178  switch (ptr->m_type)
9179  {
9181  {
9182  // use unchecked object access
9183  ptr = &ptr->operator[](reference_token);
9184  break;
9185  }
9186 
9188  {
9189  // error condition (cf. RFC 6901, Sect. 4)
9190  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9191  {
9193  "array index '" + reference_token +
9194  "' must not begin with '0'"));
9195  }
9196 
9197  if (reference_token == "-")
9198  {
9199  // explicitly treat "-" as index beyond the end
9200  ptr = &ptr->operator[](ptr->m_value.array->size());
9201  }
9202  else
9203  {
9204  // convert array index to number; unchecked access
9205  JSON_TRY
9206  {
9207  ptr = &ptr->operator[](
9208  static_cast<size_type>(array_index(reference_token)));
9209  }
9210  JSON_CATCH(std::invalid_argument&)
9211  {
9212  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9213  }
9214  }
9215  break;
9216  }
9217 
9218  default:
9219  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9220  }
9221  }
9222 
9223  return *ptr;
9224  }
9225 
9232  BasicJsonType& get_checked(BasicJsonType* ptr) const
9233  {
9234  using size_type = typename BasicJsonType::size_type;
9235  for (const auto& reference_token : reference_tokens)
9236  {
9237  switch (ptr->m_type)
9238  {
9240  {
9241  // note: at performs range check
9242  ptr = &ptr->at(reference_token);
9243  break;
9244  }
9245 
9247  {
9248  if (JSON_UNLIKELY(reference_token == "-"))
9249  {
9250  // "-" always fails the range check
9252  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9253  ") is out of range"));
9254  }
9255 
9256  // error condition (cf. RFC 6901, Sect. 4)
9257  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9258  {
9260  "array index '" + reference_token +
9261  "' must not begin with '0'"));
9262  }
9263 
9264  // note: at performs range check
9265  JSON_TRY
9266  {
9267  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9268  }
9269  JSON_CATCH(std::invalid_argument&)
9270  {
9271  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9272  }
9273  break;
9274  }
9275 
9276  default:
9277  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9278  }
9279  }
9280 
9281  return *ptr;
9282  }
9283 
9297  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
9298  {
9299  using size_type = typename BasicJsonType::size_type;
9300  for (const auto& reference_token : reference_tokens)
9301  {
9302  switch (ptr->m_type)
9303  {
9305  {
9306  // use unchecked object access
9307  ptr = &ptr->operator[](reference_token);
9308  break;
9309  }
9310 
9312  {
9313  if (JSON_UNLIKELY(reference_token == "-"))
9314  {
9315  // "-" cannot be used for const access
9317  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9318  ") is out of range"));
9319  }
9320 
9321  // error condition (cf. RFC 6901, Sect. 4)
9322  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9323  {
9325  "array index '" + reference_token +
9326  "' must not begin with '0'"));
9327  }
9328 
9329  // use unchecked array access
9330  JSON_TRY
9331  {
9332  ptr = &ptr->operator[](
9333  static_cast<size_type>(array_index(reference_token)));
9334  }
9335  JSON_CATCH(std::invalid_argument&)
9336  {
9337  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9338  }
9339  break;
9340  }
9341 
9342  default:
9343  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9344  }
9345  }
9346 
9347  return *ptr;
9348  }
9349 
9356  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
9357  {
9358  using size_type = typename BasicJsonType::size_type;
9359  for (const auto& reference_token : reference_tokens)
9360  {
9361  switch (ptr->m_type)
9362  {
9364  {
9365  // note: at performs range check
9366  ptr = &ptr->at(reference_token);
9367  break;
9368  }
9369 
9371  {
9372  if (JSON_UNLIKELY(reference_token == "-"))
9373  {
9374  // "-" always fails the range check
9376  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9377  ") is out of range"));
9378  }
9379 
9380  // error condition (cf. RFC 6901, Sect. 4)
9381  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9382  {
9384  "array index '" + reference_token +
9385  "' must not begin with '0'"));
9386  }
9387 
9388  // note: at performs range check
9389  JSON_TRY
9390  {
9391  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9392  }
9393  JSON_CATCH(std::invalid_argument&)
9394  {
9395  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9396  }
9397  break;
9398  }
9399 
9400  default:
9401  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9402  }
9403  }
9404 
9405  return *ptr;
9406  }
9407 
9417  static std::vector<std::string> split(const std::string& reference_string)
9418  {
9419  std::vector<std::string> result;
9420 
9421  // special case: empty reference string -> no reference tokens
9422  if (reference_string.empty())
9423  {
9424  return result;
9425  }
9426 
9427  // check if nonempty reference string begins with slash
9428  if (JSON_UNLIKELY(reference_string[0] != '/'))
9429  {
9431  "JSON pointer must be empty or begin with '/' - was: '" +
9432  reference_string + "'"));
9433  }
9434 
9435  // extract the reference tokens:
9436  // - slash: position of the last read slash (or end of string)
9437  // - start: position after the previous slash
9438  for (
9439  // search for the first slash after the first character
9440  std::size_t slash = reference_string.find_first_of('/', 1),
9441  // set the beginning of the first reference token
9442  start = 1;
9443  // we can stop if start == string::npos+1 = 0
9444  start != 0;
9445  // set the beginning of the next reference token
9446  // (will eventually be 0 if slash == std::string::npos)
9447  start = slash + 1,
9448  // find next slash
9449  slash = reference_string.find_first_of('/', start))
9450  {
9451  // use the text between the beginning of the reference token
9452  // (start) and the last slash (slash).
9453  auto reference_token = reference_string.substr(start, slash - start);
9454 
9455  // check reference tokens are properly escaped
9456  for (std::size_t pos = reference_token.find_first_of('~');
9457  pos != std::string::npos;
9458  pos = reference_token.find_first_of('~', pos + 1))
9459  {
9460  assert(reference_token[pos] == '~');
9461 
9462  // ~ must be followed by 0 or 1
9463  if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9464  (reference_token[pos + 1] != '0' and
9465  reference_token[pos + 1] != '1')))
9466  {
9467  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
9468  }
9469  }
9470 
9471  // finally, store the reference token
9472  unescape(reference_token);
9473  result.push_back(reference_token);
9474  }
9475 
9476  return result;
9477  }
9478 
9492  static void replace_substring(std::string& s, const std::string& f,
9493  const std::string& t)
9494  {
9495  assert(not f.empty());
9496  for (auto pos = s.find(f); // find first occurrence of f
9497  pos != std::string::npos; // make sure f was found
9498  s.replace(pos, f.size(), t), // replace with t, and
9499  pos = s.find(f, pos + t.size())) // find next occurrence of f
9500  {}
9501  }
9502 
9505  {
9506  replace_substring(s, "~", "~0");
9507  replace_substring(s, "/", "~1");
9508  return s;
9509  }
9510 
9512  static void unescape(std::string& s)
9513  {
9514  replace_substring(s, "~1", "/");
9515  replace_substring(s, "~0", "~");
9516  }
9517 
9525  static void flatten(const std::string& reference_string,
9526  const BasicJsonType& value,
9527  BasicJsonType& result)
9528  {
9529  switch (value.m_type)
9530  {
9532  {
9533  if (value.m_value.array->empty())
9534  {
9535  // flatten empty array as null
9536  result[reference_string] = nullptr;
9537  }
9538  else
9539  {
9540  // iterate array and use index as reference string
9541  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9542  {
9543  flatten(reference_string + "/" + std::to_string(i),
9544  value.m_value.array->operator[](i), result);
9545  }
9546  }
9547  break;
9548  }
9549 
9551  {
9552  if (value.m_value.object->empty())
9553  {
9554  // flatten empty object as null
9555  result[reference_string] = nullptr;
9556  }
9557  else
9558  {
9559  // iterate object and use keys as reference string
9560  for (const auto& element : *value.m_value.object)
9561  {
9562  flatten(reference_string + "/" + escape(element.first), element.second, result);
9563  }
9564  }
9565  break;
9566  }
9567 
9568  default:
9569  {
9570  // add primitive value with its reference string
9571  result[reference_string] = value;
9572  break;
9573  }
9574  }
9575  }
9576 
9587  static BasicJsonType
9588  unflatten(const BasicJsonType& value)
9589  {
9590  if (JSON_UNLIKELY(not value.is_object()))
9591  {
9592  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
9593  }
9594 
9595  BasicJsonType result;
9596 
9597  // iterate the JSON object values
9598  for (const auto& element : *value.m_value.object)
9599  {
9600  if (JSON_UNLIKELY(not element.second.is_primitive()))
9601  {
9602  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
9603  }
9604 
9605  // assign value to reference pointed to by JSON pointer; Note that if
9606  // the JSON pointer is "" (i.e., points to the whole value), function
9607  // get_and_create returns a reference to result itself. An assignment
9608  // will then create a primitive value.
9609  json_pointer(element.first).get_and_create(result) = element.second;
9610  }
9611 
9612  return result;
9613  }
9614 
9615  friend bool operator==(json_pointer const& lhs,
9616  json_pointer const& rhs) noexcept
9617  {
9618  return (lhs.reference_tokens == rhs.reference_tokens);
9619  }
9620 
9621  friend bool operator!=(json_pointer const& lhs,
9622  json_pointer const& rhs) noexcept
9623  {
9624  return not (lhs == rhs);
9625  }
9626 
9628  std::vector<std::string> reference_tokens;
9629 };
9630 }
9631 
9632 // #include <nlohmann/adl_serializer.hpp>
9633 
9634 
9635 #include <utility>
9636 
9637 // #include <nlohmann/detail/conversions/from_json.hpp>
9638 
9639 // #include <nlohmann/detail/conversions/to_json.hpp>
9640 
9641 
9642 namespace nlohmann
9643 {
9644 template<typename, typename>
9645 struct adl_serializer
9646 {
9656  template<typename BasicJsonType, typename ValueType>
9657  static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
9658  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
9659  {
9660  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
9661  }
9662 
9672  template<typename BasicJsonType, typename ValueType>
9673  static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
9674  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
9675  {
9676  ::nlohmann::to_json(j, std::forward<ValueType>(val));
9677  }
9678 };
9679 }
9680 
9681 
9687 namespace nlohmann
9688 {
9689 
9772 class basic_json
9773 {
9774  private:
9775  template<detail::value_t> friend struct detail::external_constructor;
9776  friend ::nlohmann::json_pointer<basic_json>;
9777  friend ::nlohmann::detail::parser<basic_json>;
9778  friend ::nlohmann::detail::serializer<basic_json>;
9779  template<typename BasicJsonType>
9780  friend class ::nlohmann::detail::iter_impl;
9781  template<typename BasicJsonType, typename CharType>
9782  friend class ::nlohmann::detail::binary_writer;
9783  template<typename BasicJsonType>
9784  friend class ::nlohmann::detail::binary_reader;
9785 
9788 
9789  // convenience aliases for types residing in namespace detail;
9792 
9794  template<typename BasicJsonType>
9796  template<typename BasicJsonType>
9798  template<typename Iterator>
9801 
9802  template<typename CharType>
9804 
9807 
9809 
9810  public:
9814  template<typename T, typename SFINAE>
9815  using json_serializer = JSONSerializer<T, SFINAE>;
9817  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
9818 
9820  // exceptions //
9822 
9826 
9839 
9841 
9842 
9844  // container types //
9846 
9851 
9854 
9858  using const_reference = const value_type&;
9859 
9861  using difference_type = std::ptrdiff_t;
9863  using size_type = std::size_t;
9864 
9866  using allocator_type = AllocatorType<basic_json>;
9867 
9869  using pointer = typename std::allocator_traits<allocator_type>::pointer;
9871  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
9872 
9881 
9883 
9884 
9889  {
9890  return allocator_type();
9891  }
9892 
9919  static basic_json meta()
9920  {
9921  basic_json result;
9922 
9923  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
9924  result["name"] = "JSON for Modern C++";
9925  result["url"] = "https://github.com/nlohmann/json";
9926  result["version"]["string"] =
9927  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
9928  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
9929  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
9930  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
9931  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
9932  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
9933 
9934 #ifdef _WIN32
9935  result["platform"] = "win32";
9936 #elif defined __linux__
9937  result["platform"] = "linux";
9938 #elif defined __APPLE__
9939  result["platform"] = "apple";
9940 #elif defined __unix__
9941  result["platform"] = "unix";
9942 #else
9943  result["platform"] = "unknown";
9944 #endif
9945 
9946 #if defined(__ICC) || defined(__INTEL_COMPILER)
9947  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
9948 #elif defined(__clang__)
9949  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
9950 #elif defined(__GNUC__) || defined(__GNUG__)
9951  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
9952 #elif defined(__HP_cc) || defined(__HP_aCC)
9953  result["compiler"] = "hp"
9954 #elif defined(__IBMCPP__)
9955  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
9956 #elif defined(_MSC_VER)
9957  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
9958 #elif defined(__PGI)
9959  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
9960 #elif defined(__SUNPRO_CC)
9961  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
9962 #else
9963  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
9964 #endif
9965 
9966 #ifdef __cplusplus
9967  result["compiler"]["c++"] = std::to_string(__cplusplus);
9968 #else
9969  result["compiler"]["c++"] = "unknown";
9970 #endif
9971  return result;
9972  }
9973 
9974 
9976  // JSON value data types //
9978 
9983 
9984 #if defined(JSON_HAS_CPP_14)
9985  // Use transparent comparator if possible, combined with perfect forwarding
9986  // on find() and count() calls prevents unnecessary string construction.
9987  using object_comparator_t = std::less<>;
9988 #else
9989  using object_comparator_t = std::less<StringType>;
9990 #endif
9991 
10075  using object_t = ObjectType<StringType,
10076  basic_json,
10078  AllocatorType<std::pair<const StringType,
10079  basic_json>>>;
10080 
10125  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
10126 
10178  using string_t = StringType;
10179 
10204  using boolean_t = BooleanType;
10205 
10276  using number_integer_t = NumberIntegerType;
10277 
10347  using number_unsigned_t = NumberUnsignedType;
10348 
10415  using number_float_t = NumberFloatType;
10416 
10418 
10419  private:
10420 
10422  template<typename T, typename... Args>
10423  static T* create(Args&& ... args)
10424  {
10425  AllocatorType<T> alloc;
10426  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
10427 
10428  auto deleter = [&](T * object)
10429  {
10430  AllocatorTraits::deallocate(alloc, object, 1);
10431  };
10432  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
10433  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
10434  assert(object != nullptr);
10435  return object.release();
10436  }
10437 
10439  // JSON value storage //
10441 
10467  {
10482 
10484  json_value() = default;
10486  json_value(boolean_t v) noexcept : boolean(v) {}
10495  {
10496  switch (t)
10497  {
10498  case value_t::object:
10499  {
10500  object = create<object_t>();
10501  break;
10502  }
10503 
10504  case value_t::array:
10505  {
10506  array = create<array_t>();
10507  break;
10508  }
10509 
10510  case value_t::string:
10511  {
10512  string = create<string_t>("");
10513  break;
10514  }
10515 
10516  case value_t::boolean:
10517  {
10518  boolean = boolean_t(false);
10519  break;
10520  }
10521 
10523  {
10524  number_integer = number_integer_t(0);
10525  break;
10526  }
10527 
10529  {
10530  number_unsigned = number_unsigned_t(0);
10531  break;
10532  }
10533 
10534  case value_t::number_float:
10535  {
10536  number_float = number_float_t(0.0);
10537  break;
10538  }
10539 
10540  case value_t::null:
10541  {
10542  object = nullptr; // silence warning, see #821
10543  break;
10544  }
10545 
10546  default:
10547  {
10548  object = nullptr; // silence warning, see #821
10549  if (JSON_UNLIKELY(t == value_t::null))
10550  {
10551  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.1.2")); // LCOV_EXCL_LINE
10552  }
10553  break;
10554  }
10555  }
10556  }
10557 
10559  json_value(const string_t& value)
10560  {
10561  string = create<string_t>(value);
10562  }
10563 
10566  {
10567  string = create<string_t>(std::move(value));
10568  }
10569 
10571  json_value(const object_t& value)
10572  {
10573  object = create<object_t>(value);
10574  }
10575 
10578  {
10579  object = create<object_t>(std::move(value));
10580  }
10581 
10583  json_value(const array_t& value)
10584  {
10585  array = create<array_t>(value);
10586  }
10587 
10590  {
10591  array = create<array_t>(std::move(value));
10592  }
10593 
10594  void destroy(value_t t) noexcept
10595  {
10596  switch (t)
10597  {
10598  case value_t::object:
10599  {
10600  AllocatorType<object_t> alloc;
10601  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
10602  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
10603  break;
10604  }
10605 
10606  case value_t::array:
10607  {
10608  AllocatorType<array_t> alloc;
10609  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
10610  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
10611  break;
10612  }
10613 
10614  case value_t::string:
10615  {
10616  AllocatorType<string_t> alloc;
10617  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
10618  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
10619  break;
10620  }
10621 
10622  default:
10623  {
10624  break;
10625  }
10626  }
10627  }
10628  };
10629 
10639  void assert_invariant() const noexcept
10640  {
10641  assert(m_type != value_t::object or m_value.object != nullptr);
10642  assert(m_type != value_t::array or m_value.array != nullptr);
10643  assert(m_type != value_t::string or m_value.string != nullptr);
10644  }
10645 
10646  public:
10648  // JSON parser callback //
10650 
10667 
10718 
10719 
10721  // constructors //
10723 
10728 
10759  : m_type(v), m_value(v)
10760  {
10761  assert_invariant();
10762  }
10763 
10782  basic_json(std::nullptr_t = nullptr) noexcept
10783  : basic_json(value_t::null)
10784  {
10785  assert_invariant();
10786  }
10787 
10845  template <typename CompatibleType,
10846  typename U = detail::uncvref_t<CompatibleType>,
10849  basic_json(CompatibleType && val) noexcept(noexcept(
10850  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
10851  std::forward<CompatibleType>(val))))
10852  {
10853  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
10854  assert_invariant();
10855  }
10856 
10883  template <typename BasicJsonType,
10885  detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
10886  basic_json(const BasicJsonType& val)
10887  {
10888  using other_boolean_t = typename BasicJsonType::boolean_t;
10889  using other_number_float_t = typename BasicJsonType::number_float_t;
10890  using other_number_integer_t = typename BasicJsonType::number_integer_t;
10891  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10892  using other_string_t = typename BasicJsonType::string_t;
10893  using other_object_t = typename BasicJsonType::object_t;
10894  using other_array_t = typename BasicJsonType::array_t;
10895 
10896  switch (val.type())
10897  {
10898  case value_t::boolean:
10899  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
10900  break;
10901  case value_t::number_float:
10902  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
10903  break;
10905  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
10906  break;
10908  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
10909  break;
10910  case value_t::string:
10911  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
10912  break;
10913  case value_t::object:
10914  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
10915  break;
10916  case value_t::array:
10917  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
10918  break;
10919  case value_t::null:
10920  *this = nullptr;
10921  break;
10922  case value_t::discarded:
10923  m_type = value_t::discarded;
10924  break;
10925  }
10926  assert_invariant();
10927  }
10928 
11004  bool type_deduction = true,
11005  value_t manual_type = value_t::array)
11006  {
11007  // check if each element is an array with two elements whose first
11008  // element is a string
11009  bool is_an_object = std::all_of(init.begin(), init.end(),
11010  [](const detail::json_ref<basic_json>& element_ref)
11011  {
11012  return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
11013  });
11014 
11015  // adjust type if type deduction is not wanted
11016  if (not type_deduction)
11017  {
11018  // if array is wanted, do not create an object though possible
11019  if (manual_type == value_t::array)
11020  {
11021  is_an_object = false;
11022  }
11023 
11024  // if object is wanted but impossible, throw an exception
11025  if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
11026  {
11027  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
11028  }
11029  }
11030 
11031  if (is_an_object)
11032  {
11033  // the initializer list is a list of pairs -> create object
11034  m_type = value_t::object;
11035  m_value = value_t::object;
11036 
11037  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
11038  {
11039  auto element = element_ref.moved_or_copied();
11040  m_value.object->emplace(
11041  std::move(*((*element.m_value.array)[0].m_value.string)),
11042  std::move((*element.m_value.array)[1]));
11043  });
11044  }
11045  else
11046  {
11047  // the initializer list describes an array -> create array
11048  m_type = value_t::array;
11049  m_value.array = create<array_t>(init.begin(), init.end());
11050  }
11051 
11052  assert_invariant();
11053  }
11054 
11092  static basic_json array(initializer_list_t init = {})
11093  {
11094  return basic_json(init, false, value_t::array);
11095  }
11096 
11135  static basic_json object(initializer_list_t init = {})
11136  {
11137  return basic_json(init, false, value_t::object);
11138  }
11139 
11162  basic_json(size_type cnt, const basic_json& val)
11163  : m_type(value_t::array)
11164  {
11165  m_value.array = create<array_t>(cnt, val);
11166  assert_invariant();
11167  }
11168 
11224  template<class InputIT, typename std::enable_if<
11225  std::is_same<InputIT, typename basic_json_t::iterator>::value or
11226  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
11227  basic_json(InputIT first, InputIT last)
11228  {
11229  assert(first.m_object != nullptr);
11230  assert(last.m_object != nullptr);
11231 
11232  // make sure iterator fits the current value
11233  if (JSON_UNLIKELY(first.m_object != last.m_object))
11234  {
11235  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
11236  }
11237 
11238  // copy type from first iterator
11239  m_type = first.m_object->m_type;
11240 
11241  // check if iterator range is complete for primitive values
11242  switch (m_type)
11243  {
11244  case value_t::boolean:
11245  case value_t::number_float:
11248  case value_t::string:
11249  {
11250  if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
11251  or not last.m_it.primitive_iterator.is_end()))
11252  {
11253  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
11254  }
11255  break;
11256  }
11257 
11258  default:
11259  break;
11260  }
11261 
11262  switch (m_type)
11263  {
11265  {
11266  m_value.number_integer = first.m_object->m_value.number_integer;
11267  break;
11268  }
11269 
11271  {
11272  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
11273  break;
11274  }
11275 
11276  case value_t::number_float:
11277  {
11278  m_value.number_float = first.m_object->m_value.number_float;
11279  break;
11280  }
11281 
11282  case value_t::boolean:
11283  {
11284  m_value.boolean = first.m_object->m_value.boolean;
11285  break;
11286  }
11287 
11288  case value_t::string:
11289  {
11290  m_value = *first.m_object->m_value.string;
11291  break;
11292  }
11293 
11294  case value_t::object:
11295  {
11296  m_value.object = create<object_t>(first.m_it.object_iterator,
11297  last.m_it.object_iterator);
11298  break;
11299  }
11300 
11301  case value_t::array:
11302  {
11303  m_value.array = create<array_t>(first.m_it.array_iterator,
11304  last.m_it.array_iterator);
11305  break;
11306  }
11307 
11308  default:
11309  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
11310  std::string(first.m_object->type_name())));
11311  }
11312 
11313  assert_invariant();
11314  }
11315 
11316 
11318  // other constructors and destructor //
11320 
11323  : basic_json(ref.moved_or_copied())
11324  {}
11325 
11351  basic_json(const basic_json& other)
11352  : m_type(other.m_type)
11353  {
11354  // check of passed value is valid
11355  other.assert_invariant();
11356 
11357  switch (m_type)
11358  {
11359  case value_t::object:
11360  {
11361  m_value = *other.m_value.object;
11362  break;
11363  }
11364 
11365  case value_t::array:
11366  {
11367  m_value = *other.m_value.array;
11368  break;
11369  }
11370 
11371  case value_t::string:
11372  {
11373  m_value = *other.m_value.string;
11374  break;
11375  }
11376 
11377  case value_t::boolean:
11378  {
11379  m_value = other.m_value.boolean;
11380  break;
11381  }
11382 
11384  {
11385  m_value = other.m_value.number_integer;
11386  break;
11387  }
11388 
11390  {
11391  m_value = other.m_value.number_unsigned;
11392  break;
11393  }
11394 
11395  case value_t::number_float:
11396  {
11397  m_value = other.m_value.number_float;
11398  break;
11399  }
11400 
11401  default:
11402  break;
11403  }
11404 
11405  assert_invariant();
11406  }
11407 
11434  basic_json(basic_json&& other) noexcept
11435  : m_type(std::move(other.m_type)),
11436  m_value(std::move(other.m_value))
11437  {
11438  // check that passed value is valid
11439  other.assert_invariant();
11440 
11441  // invalidate payload
11442  other.m_type = value_t::null;
11443  other.m_value = {};
11444 
11445  assert_invariant();
11446  }
11447 
11471  reference& operator=(basic_json other) noexcept (
11472  std::is_nothrow_move_constructible<value_t>::value and
11473  std::is_nothrow_move_assignable<value_t>::value and
11474  std::is_nothrow_move_constructible<json_value>::value and
11475  std::is_nothrow_move_assignable<json_value>::value
11476  )
11477  {
11478  // check that passed value is valid
11479  other.assert_invariant();
11480 
11481  using std::swap;
11482  swap(m_type, other.m_type);
11483  swap(m_value, other.m_value);
11484 
11485  assert_invariant();
11486  return *this;
11487  }
11488 
11504  ~basic_json() noexcept
11505  {
11506  assert_invariant();
11507  m_value.destroy(m_type);
11508  }
11509 
11511 
11512  public:
11514  // object inspection //
11516 
11520 
11557  string_t dump(const int indent = -1, const char indent_char = ' ',
11558  const bool ensure_ascii = false) const
11559  {
11560  string_t result;
11561  serializer s(detail::output_adapter<char, string_t>(result), indent_char);
11562 
11563  if (indent >= 0)
11564  {
11565  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
11566  }
11567  else
11568  {
11569  s.dump(*this, false, ensure_ascii, 0);
11570  }
11571 
11572  return result;
11573  }
11574 
11607  constexpr value_t type() const noexcept
11608  {
11609  return m_type;
11610  }
11611 
11637  constexpr bool is_primitive() const noexcept
11638  {
11639  return is_null() or is_string() or is_boolean() or is_number();
11640  }
11641 
11664  constexpr bool is_structured() const noexcept
11665  {
11666  return is_array() or is_object();
11667  }
11668 
11686  constexpr bool is_null() const noexcept
11687  {
11688  return (m_type == value_t::null);
11689  }
11690 
11708  constexpr bool is_boolean() const noexcept
11709  {
11710  return (m_type == value_t::boolean);
11711  }
11712 
11738  constexpr bool is_number() const noexcept
11739  {
11740  return is_number_integer() or is_number_float();
11741  }
11742 
11767  constexpr bool is_number_integer() const noexcept
11768  {
11769  return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
11770  }
11771 
11795  constexpr bool is_number_unsigned() const noexcept
11796  {
11797  return (m_type == value_t::number_unsigned);
11798  }
11799 
11823  constexpr bool is_number_float() const noexcept
11824  {
11825  return (m_type == value_t::number_float);
11826  }
11827 
11845  constexpr bool is_object() const noexcept
11846  {
11847  return (m_type == value_t::object);
11848  }
11849 
11867  constexpr bool is_array() const noexcept
11868  {
11869  return (m_type == value_t::array);
11870  }
11871 
11889  constexpr bool is_string() const noexcept
11890  {
11891  return (m_type == value_t::string);
11892  }
11893 
11916  constexpr bool is_discarded() const noexcept
11917  {
11918  return (m_type == value_t::discarded);
11919  }
11920 
11942  constexpr operator value_t() const noexcept
11943  {
11944  return m_type;
11945  }
11946 
11948 
11949  private:
11951  // value access //
11953 
11955  boolean_t get_impl(boolean_t* /*unused*/) const
11956  {
11957  if (JSON_LIKELY(is_boolean()))
11958  {
11959  return m_value.boolean;
11960  }
11961 
11962  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
11963  }
11964 
11966  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
11967  {
11968  return is_object() ? m_value.object : nullptr;
11969  }
11970 
11972  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
11973  {
11974  return is_object() ? m_value.object : nullptr;
11975  }
11976 
11978  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
11979  {
11980  return is_array() ? m_value.array : nullptr;
11981  }
11982 
11984  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
11985  {
11986  return is_array() ? m_value.array : nullptr;
11987  }
11988 
11990  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
11991  {
11992  return is_string() ? m_value.string : nullptr;
11993  }
11994 
11996  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
11997  {
11998  return is_string() ? m_value.string : nullptr;
11999  }
12000 
12002  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
12003  {
12004  return is_boolean() ? &m_value.boolean : nullptr;
12005  }
12006 
12008  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
12009  {
12010  return is_boolean() ? &m_value.boolean : nullptr;
12011  }
12012 
12015  {
12016  return is_number_integer() ? &m_value.number_integer : nullptr;
12017  }
12018 
12020  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
12021  {
12022  return is_number_integer() ? &m_value.number_integer : nullptr;
12023  }
12024 
12027  {
12028  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
12029  }
12030 
12032  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
12033  {
12034  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
12035  }
12036 
12039  {
12040  return is_number_float() ? &m_value.number_float : nullptr;
12041  }
12042 
12044  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
12045  {
12046  return is_number_float() ? &m_value.number_float : nullptr;
12047  }
12048 
12060  template<typename ReferenceType, typename ThisType>
12061  static ReferenceType get_ref_impl(ThisType& obj)
12062  {
12063  // delegate the call to get_ptr<>()
12064  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
12065 
12066  if (JSON_LIKELY(ptr != nullptr))
12067  {
12068  return *ptr;
12069  }
12070 
12071  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
12072  }
12073 
12074  public:
12078 
12093  template<typename BasicJsonType, detail::enable_if_t<
12094  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
12095  int> = 0>
12096  basic_json get() const
12097  {
12098  return *this;
12099  }
12100 
12116  template<typename BasicJsonType, detail::enable_if_t<
12117  not std::is_same<BasicJsonType, basic_json>::value and
12119  BasicJsonType get() const
12120  {
12121  return *this;
12122  }
12123 
12163  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
12164  detail::enable_if_t <
12165  not detail::is_basic_json<ValueType>::value and
12166  detail::has_from_json<basic_json_t, ValueType>::value and
12167  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12168  int> = 0>
12169  ValueType get() const noexcept(noexcept(
12170  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
12171  {
12172  // we cannot static_assert on ValueTypeCV being non-const, because
12173  // there is support for get<const basic_json_t>(), which is why we
12174  // still need the uncvref
12175  static_assert(not std::is_reference<ValueTypeCV>::value,
12176  "get() cannot be used with reference types, you might want to use get_ref()");
12177  static_assert(std::is_default_constructible<ValueType>::value,
12178  "types must be DefaultConstructible when used with get()");
12179 
12180  ValueType ret;
12182  return ret;
12183  }
12184 
12216  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
12217  detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
12218  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
12219  int> = 0>
12220  ValueType get() const noexcept(noexcept(
12221  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
12222  {
12223  static_assert(not std::is_reference<ValueTypeCV>::value,
12224  "get() cannot be used with reference types, you might want to use get_ref()");
12226  }
12227 
12255  template<typename PointerType, typename std::enable_if<
12256  std::is_pointer<PointerType>::value, int>::type = 0>
12257  PointerType get() noexcept
12258  {
12259  // delegate the call to get_ptr
12260  return get_ptr<PointerType>();
12261  }
12262 
12267  template<typename PointerType, typename std::enable_if<
12268  std::is_pointer<PointerType>::value, int>::type = 0>
12269  constexpr const PointerType get() const noexcept
12270  {
12271  // delegate the call to get_ptr
12272  return get_ptr<PointerType>();
12273  }
12274 
12301  template<typename PointerType, typename std::enable_if<
12302  std::is_pointer<PointerType>::value, int>::type = 0>
12303  PointerType get_ptr() noexcept
12304  {
12305  // get the type of the PointerType (remove pointer and const)
12306  using pointee_t = typename std::remove_const<typename
12307  std::remove_pointer<typename
12308  std::remove_const<PointerType>::type>::type>::type;
12309  // make sure the type matches the allowed types
12310  static_assert(
12311  std::is_same<object_t, pointee_t>::value
12312  or std::is_same<array_t, pointee_t>::value
12313  or std::is_same<string_t, pointee_t>::value
12314  or std::is_same<boolean_t, pointee_t>::value
12315  or std::is_same<number_integer_t, pointee_t>::value
12316  or std::is_same<number_unsigned_t, pointee_t>::value
12317  or std::is_same<number_float_t, pointee_t>::value
12318  , "incompatible pointer type");
12319 
12320  // delegate the call to get_impl_ptr<>()
12321  return get_impl_ptr(static_cast<PointerType>(nullptr));
12322  }
12323 
12328  template<typename PointerType, typename std::enable_if<
12329  std::is_pointer<PointerType>::value and
12330  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
12331  constexpr const PointerType get_ptr() const noexcept
12332  {
12333  // get the type of the PointerType (remove pointer and const)
12334  using pointee_t = typename std::remove_const<typename
12335  std::remove_pointer<typename
12336  std::remove_const<PointerType>::type>::type>::type;
12337  // make sure the type matches the allowed types
12338  static_assert(
12339  std::is_same<object_t, pointee_t>::value
12340  or std::is_same<array_t, pointee_t>::value
12341  or std::is_same<string_t, pointee_t>::value
12342  or std::is_same<boolean_t, pointee_t>::value
12343  or std::is_same<number_integer_t, pointee_t>::value
12344  or std::is_same<number_unsigned_t, pointee_t>::value
12345  or std::is_same<number_float_t, pointee_t>::value
12346  , "incompatible pointer type");
12347 
12348  // delegate the call to get_impl_ptr<>() const
12349  return get_impl_ptr(static_cast<PointerType>(nullptr));
12350  }
12351 
12378  template<typename ReferenceType, typename std::enable_if<
12379  std::is_reference<ReferenceType>::value, int>::type = 0>
12380  ReferenceType get_ref()
12381  {
12382  // delegate call to get_ref_impl
12383  return get_ref_impl<ReferenceType>(*this);
12384  }
12385 
12390  template<typename ReferenceType, typename std::enable_if<
12391  std::is_reference<ReferenceType>::value and
12392  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
12393  ReferenceType get_ref() const
12394  {
12395  // delegate call to get_ref_impl
12396  return get_ref_impl<ReferenceType>(*this);
12397  }
12398 
12428  template < typename ValueType, typename std::enable_if <
12429  not std::is_pointer<ValueType>::value and
12430  not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
12431  not std::is_same<ValueType, typename string_t::value_type>::value and
12433 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
12434  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
12435 #endif
12436 #if defined(JSON_HAS_CPP_17)
12437  and not std::is_same<ValueType, typename std::string_view>::value
12438 #endif
12439  , int >::type = 0 >
12440  operator ValueType() const
12441  {
12442  // delegate the call to get<>() const
12443  return get<ValueType>();
12444  }
12445 
12447 
12448 
12450  // element access //
12452 
12456 
12484  {
12485  // at only works for arrays
12486  if (JSON_LIKELY(is_array()))
12487  {
12488  JSON_TRY
12489  {
12490  return m_value.array->at(idx);
12491  }
12492  JSON_CATCH (std::out_of_range&)
12493  {
12494  // create better exception explanation
12495  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
12496  }
12497  }
12498  else
12499  {
12500  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12501  }
12502  }
12503 
12531  {
12532  // at only works for arrays
12533  if (JSON_LIKELY(is_array()))
12534  {
12535  JSON_TRY
12536  {
12537  return m_value.array->at(idx);
12538  }
12539  JSON_CATCH (std::out_of_range&)
12540  {
12541  // create better exception explanation
12542  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
12543  }
12544  }
12545  else
12546  {
12547  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12548  }
12549  }
12550 
12581  reference at(const typename object_t::key_type& key)
12582  {
12583  // at only works for objects
12584  if (JSON_LIKELY(is_object()))
12585  {
12586  JSON_TRY
12587  {
12588  return m_value.object->at(key);
12589  }
12590  JSON_CATCH (std::out_of_range&)
12591  {
12592  // create better exception explanation
12593  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
12594  }
12595  }
12596  else
12597  {
12598  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12599  }
12600  }
12601 
12632  const_reference at(const typename object_t::key_type& key) const
12633  {
12634  // at only works for objects
12635  if (JSON_LIKELY(is_object()))
12636  {
12637  JSON_TRY
12638  {
12639  return m_value.object->at(key);
12640  }
12641  JSON_CATCH (std::out_of_range&)
12642  {
12643  // create better exception explanation
12644  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
12645  }
12646  }
12647  else
12648  {
12649  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
12650  }
12651  }
12652 
12679  {
12680  // implicitly convert null value to an empty array
12681  if (is_null())
12682  {
12683  m_type = value_t::array;
12684  m_value.array = create<array_t>();
12685  assert_invariant();
12686  }
12687 
12688  // operator[] only works for arrays
12689  if (JSON_LIKELY(is_array()))
12690  {
12691  // fill up array with null values if given idx is outside range
12692  if (idx >= m_value.array->size())
12693  {
12694  m_value.array->insert(m_value.array->end(),
12695  idx - m_value.array->size() + 1,
12696  basic_json());
12697  }
12698 
12699  return m_value.array->operator[](idx);
12700  }
12701 
12702  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12703  }
12704 
12725  {
12726  // const operator[] only works for arrays
12727  if (JSON_LIKELY(is_array()))
12728  {
12729  return m_value.array->operator[](idx);
12730  }
12731 
12732  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12733  }
12734 
12762  reference operator[](const typename object_t::key_type& key)
12763  {
12764  // implicitly convert null value to an empty object
12765  if (is_null())
12766  {
12767  m_type = value_t::object;
12768  m_value.object = create<object_t>();
12769  assert_invariant();
12770  }
12771 
12772  // operator[] only works for objects
12773  if (JSON_LIKELY(is_object()))
12774  {
12775  return m_value.object->operator[](key);
12776  }
12777 
12778  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12779  }
12780 
12811  const_reference operator[](const typename object_t::key_type& key) const
12812  {
12813  // const operator[] only works for objects
12814  if (JSON_LIKELY(is_object()))
12815  {
12816  assert(m_value.object->find(key) != m_value.object->end());
12817  return m_value.object->find(key)->second;
12818  }
12819 
12820  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12821  }
12822 
12850  template<typename T>
12852  {
12853  // implicitly convert null to object
12854  if (is_null())
12855  {
12856  m_type = value_t::object;
12857  m_value = value_t::object;
12858  assert_invariant();
12859  }
12860 
12861  // at only works for objects
12862  if (JSON_LIKELY(is_object()))
12863  {
12864  return m_value.object->operator[](key);
12865  }
12866 
12867  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12868  }
12869 
12900  template<typename T>
12902  {
12903  // at only works for objects
12904  if (JSON_LIKELY(is_object()))
12905  {
12906  assert(m_value.object->find(key) != m_value.object->end());
12907  return m_value.object->find(key)->second;
12908  }
12909 
12910  JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
12911  }
12912 
12961  template<class ValueType, typename std::enable_if<
12962  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
12963  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
12964  {
12965  // at only works for objects
12966  if (JSON_LIKELY(is_object()))
12967  {
12968  // if key is found, return value and given default value otherwise
12969  const auto it = find(key);
12970  if (it != end())
12971  {
12972  return *it;
12973  }
12974 
12975  return default_value;
12976  }
12977 
12978  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
12979  }
12980 
12985  string_t value(const typename object_t::key_type& key, const char* default_value) const
12986  {
12987  return value(key, string_t(default_value));
12988  }
12989 
13031  template<class ValueType, typename std::enable_if<
13032  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
13033  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
13034  {
13035  // at only works for objects
13036  if (JSON_LIKELY(is_object()))
13037  {
13038  // if pointer resolves a value, return it or use default value
13039  JSON_TRY
13040  {
13041  return ptr.get_checked(this);
13042  }
13044  {
13045  return default_value;
13046  }
13047  }
13048 
13049  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
13050  }
13051 
13056  string_t value(const json_pointer& ptr, const char* default_value) const
13057  {
13058  return value(ptr, string_t(default_value));
13059  }
13060 
13087  {
13088  return *begin();
13089  }
13090 
13095  {
13096  return *cbegin();
13097  }
13098 
13131  {
13132  auto tmp = end();
13133  --tmp;
13134  return *tmp;
13135  }
13136 
13141  {
13142  auto tmp = cend();
13143  --tmp;
13144  return *tmp;
13145  }
13146 
13193  template<class IteratorType, typename std::enable_if<
13194  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
13195  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
13196  = 0>
13197  IteratorType erase(IteratorType pos)
13198  {
13199  // make sure iterator fits the current value
13200  if (JSON_UNLIKELY(this != pos.m_object))
13201  {
13202  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
13203  }
13204 
13205  IteratorType result = end();
13206 
13207  switch (m_type)
13208  {
13209  case value_t::boolean:
13210  case value_t::number_float:
13213  case value_t::string:
13214  {
13215  if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
13216  {
13217  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
13218  }
13219 
13220  if (is_string())
13221  {
13222  AllocatorType<string_t> alloc;
13223  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
13224  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13225  m_value.string = nullptr;
13226  }
13227 
13228  m_type = value_t::null;
13229  assert_invariant();
13230  break;
13231  }
13232 
13233  case value_t::object:
13234  {
13235  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
13236  break;
13237  }
13238 
13239  case value_t::array:
13240  {
13241  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
13242  break;
13243  }
13244 
13245  default:
13246  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
13247  }
13248 
13249  return result;
13250  }
13251 
13298  template<class IteratorType, typename std::enable_if<
13299  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
13300  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
13301  = 0>
13302  IteratorType erase(IteratorType first, IteratorType last)
13303  {
13304  // make sure iterator fits the current value
13305  if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
13306  {
13307  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
13308  }
13309 
13310  IteratorType result = end();
13311 
13312  switch (m_type)
13313  {
13314  case value_t::boolean:
13315  case value_t::number_float:
13318  case value_t::string:
13319  {
13320  if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
13321  or not last.m_it.primitive_iterator.is_end()))
13322  {
13323  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
13324  }
13325 
13326  if (is_string())
13327  {
13328  AllocatorType<string_t> alloc;
13329  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
13330  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
13331  m_value.string = nullptr;
13332  }
13333 
13334  m_type = value_t::null;
13335  assert_invariant();
13336  break;
13337  }
13338 
13339  case value_t::object:
13340  {
13341  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
13342  last.m_it.object_iterator);
13343  break;
13344  }
13345 
13346  case value_t::array:
13347  {
13348  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
13349  last.m_it.array_iterator);
13350  break;
13351  }
13352 
13353  default:
13354  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
13355  }
13356 
13357  return result;
13358  }
13359 
13389  size_type erase(const typename object_t::key_type& key)
13390  {
13391  // this erase only works for objects
13392  if (JSON_LIKELY(is_object()))
13393  {
13394  return m_value.object->erase(key);
13395  }
13396 
13397  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
13398  }
13399 
13424  void erase(const size_type idx)
13425  {
13426  // this erase only works for arrays
13427  if (JSON_LIKELY(is_array()))
13428  {
13429  if (JSON_UNLIKELY(idx >= size()))
13430  {
13431  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
13432  }
13433 
13434  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
13435  }
13436  else
13437  {
13438  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
13439  }
13440  }
13441 
13443 
13444 
13446  // lookup //
13448 
13451 
13474  template<typename KeyT>
13475  iterator find(KeyT&& key)
13476  {
13477  auto result = end();
13478 
13479  if (is_object())
13480  {
13481  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13482  }
13483 
13484  return result;
13485  }
13486 
13491  template<typename KeyT>
13492  const_iterator find(KeyT&& key) const
13493  {
13494  auto result = cend();
13495 
13496  if (is_object())
13497  {
13498  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
13499  }
13500 
13501  return result;
13502  }
13503 
13525  template<typename KeyT>
13526  size_type count(KeyT&& key) const
13527  {
13528  // return 0 for all nonobject types
13529  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
13530  }
13531 
13533 
13534 
13536  // iterators //
13538 
13541 
13566  iterator begin() noexcept
13567  {
13568  iterator result(this);
13569  result.set_begin();
13570  return result;
13571  }
13572 
13576  const_iterator begin() const noexcept
13577  {
13578  return cbegin();
13579  }
13580 
13606  const_iterator cbegin() const noexcept
13607  {
13608  const_iterator result(this);
13609  result.set_begin();
13610  return result;
13611  }
13612 
13637  iterator end() noexcept
13638  {
13639  iterator result(this);
13640  result.set_end();
13641  return result;
13642  }
13643 
13647  const_iterator end() const noexcept
13648  {
13649  return cend();
13650  }
13651 
13677  const_iterator cend() const noexcept
13678  {
13679  const_iterator result(this);
13680  result.set_end();
13681  return result;
13682  }
13683 
13708  {
13709  return reverse_iterator(end());
13710  }
13711 
13716  {
13717  return crbegin();
13718  }
13719 
13745  {
13746  return reverse_iterator(begin());
13747  }
13748 
13752  const_reverse_iterator rend() const noexcept
13753  {
13754  return crend();
13755  }
13756 
13782  {
13783  return const_reverse_iterator(cend());
13784  }
13785 
13811  {
13812  return const_reverse_iterator(cbegin());
13813  }
13814 
13815  public:
13875  {
13876  return ref.items();
13877  }
13878 
13884  {
13885  return ref.items();
13886  }
13887 
13941  {
13942  return iteration_proxy<iterator>(*this);
13943  }
13944 
13949  {
13950  return iteration_proxy<const_iterator>(*this);
13951  }
13952 
13954 
13955 
13957  // capacity //
13959 
13962 
14004  bool empty() const noexcept
14005  {
14006  switch (m_type)
14007  {
14008  case value_t::null:
14009  {
14010  // null values are empty
14011  return true;
14012  }
14013 
14014  case value_t::array:
14015  {
14016  // delegate call to array_t::empty()
14017  return m_value.array->empty();
14018  }
14019 
14020  case value_t::object:
14021  {
14022  // delegate call to object_t::empty()
14023  return m_value.object->empty();
14024  }
14025 
14026  default:
14027  {
14028  // all other types are nonempty
14029  return false;
14030  }
14031  }
14032  }
14033 
14076  size_type size() const noexcept
14077  {
14078  switch (m_type)
14079  {
14080  case value_t::null:
14081  {
14082  // null values are empty
14083  return 0;
14084  }
14085 
14086  case value_t::array:
14087  {
14088  // delegate call to array_t::size()
14089  return m_value.array->size();
14090  }
14091 
14092  case value_t::object:
14093  {
14094  // delegate call to object_t::size()
14095  return m_value.object->size();
14096  }
14097 
14098  default:
14099  {
14100  // all other types have size 1
14101  return 1;
14102  }
14103  }
14104  }
14105 
14146  size_type max_size() const noexcept
14147  {
14148  switch (m_type)
14149  {
14150  case value_t::array:
14151  {
14152  // delegate call to array_t::max_size()
14153  return m_value.array->max_size();
14154  }
14155 
14156  case value_t::object:
14157  {
14158  // delegate call to object_t::max_size()
14159  return m_value.object->max_size();
14160  }
14161 
14162  default:
14163  {
14164  // all other types have max_size() == size()
14165  return size();
14166  }
14167  }
14168  }
14169 
14171 
14172 
14174  // modifiers //
14176 
14179 
14216  void clear() noexcept
14217  {
14218  switch (m_type)
14219  {
14221  {
14222  m_value.number_integer = 0;
14223  break;
14224  }
14225 
14227  {
14228  m_value.number_unsigned = 0;
14229  break;
14230  }
14231 
14232  case value_t::number_float:
14233  {
14234  m_value.number_float = 0.0;
14235  break;
14236  }
14237 
14238  case value_t::boolean:
14239  {
14240  m_value.boolean = false;
14241  break;
14242  }
14243 
14244  case value_t::string:
14245  {
14246  m_value.string->clear();
14247  break;
14248  }
14249 
14250  case value_t::array:
14251  {
14252  m_value.array->clear();
14253  break;
14254  }
14255 
14256  case value_t::object:
14257  {
14258  m_value.object->clear();
14259  break;
14260  }
14261 
14262  default:
14263  break;
14264  }
14265  }
14266 
14287  void push_back(basic_json&& val)
14288  {
14289  // push_back only works for null objects or arrays
14290  if (JSON_UNLIKELY(not(is_null() or is_array())))
14291  {
14292  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
14293  }
14294 
14295  // transform null object into an array
14296  if (is_null())
14297  {
14298  m_type = value_t::array;
14299  m_value = value_t::array;
14300  assert_invariant();
14301  }
14302 
14303  // add element to array (move semantics)
14304  m_value.array->push_back(std::move(val));
14305  // invalidate object
14306  val.m_type = value_t::null;
14307  }
14308 
14313  reference operator+=(basic_json&& val)
14314  {
14315  push_back(std::move(val));
14316  return *this;
14317  }
14318 
14323  void push_back(const basic_json& val)
14324  {
14325  // push_back only works for null objects or arrays
14326  if (JSON_UNLIKELY(not(is_null() or is_array())))
14327  {
14328  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
14329  }
14330 
14331  // transform null object into an array
14332  if (is_null())
14333  {
14334  m_type = value_t::array;
14335  m_value = value_t::array;
14336  assert_invariant();
14337  }
14338 
14339  // add element to array
14340  m_value.array->push_back(val);
14341  }
14342 
14347  reference operator+=(const basic_json& val)
14348  {
14349  push_back(val);
14350  return *this;
14351  }
14352 
14373  void push_back(const typename object_t::value_type& val)
14374  {
14375  // push_back only works for null objects or objects
14376  if (JSON_UNLIKELY(not(is_null() or is_object())))
14377  {
14378  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
14379  }
14380 
14381  // transform null object into an object
14382  if (is_null())
14383  {
14384  m_type = value_t::object;
14385  m_value = value_t::object;
14386  assert_invariant();
14387  }
14388 
14389  // add element to array
14390  m_value.object->insert(val);
14391  }
14392 
14397  reference operator+=(const typename object_t::value_type& val)
14398  {
14399  push_back(val);
14400  return *this;
14401  }
14402 
14429  {
14430  if (is_object() and init.size() == 2 and (*init.begin())->is_string())
14431  {
14432  basic_json&& key = init.begin()->moved_or_copied();
14433  push_back(typename object_t::value_type(
14434  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
14435  }
14436  else
14437  {
14438  push_back(basic_json(init));
14439  }
14440  }
14441 
14447  {
14448  push_back(init);
14449  return *this;
14450  }
14451 
14473  template<class... Args>
14474  void emplace_back(Args&& ... args)
14475  {
14476  // emplace_back only works for null objects or arrays
14477  if (JSON_UNLIKELY(not(is_null() or is_array())))
14478  {
14479  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
14480  }
14481 
14482  // transform null object into an array
14483  if (is_null())
14484  {
14485  m_type = value_t::array;
14486  m_value = value_t::array;
14487  assert_invariant();
14488  }
14489 
14490  // add element to array (perfect forwarding)
14491  m_value.array->emplace_back(std::forward<Args>(args)...);
14492  }
14493 
14521  template<class... Args>
14522  std::pair<iterator, bool> emplace(Args&& ... args)
14523  {
14524  // emplace only works for null objects or arrays
14525  if (JSON_UNLIKELY(not(is_null() or is_object())))
14526  {
14527  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
14528  }
14529 
14530  // transform null object into an object
14531  if (is_null())
14532  {
14533  m_type = value_t::object;
14534  m_value = value_t::object;
14535  assert_invariant();
14536  }
14537 
14538  // add element to array (perfect forwarding)
14539  auto res = m_value.object->emplace(std::forward<Args>(args)...);
14540  // create result iterator and set iterator to the result of emplace
14541  auto it = begin();
14542  it.m_it.object_iterator = res.first;
14543 
14544  // return pair of iterator and boolean
14545  return {it, res.second};
14546  }
14547 
14570  iterator insert(const_iterator pos, const basic_json& val)
14571  {
14572  // insert only works for arrays
14573  if (JSON_LIKELY(is_array()))
14574  {
14575  // check if iterator pos fits to this JSON value
14576  if (JSON_UNLIKELY(pos.m_object != this))
14577  {
14578  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14579  }
14580 
14581  // insert to array and return iterator
14582  iterator result(this);
14583  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
14584  return result;
14585  }
14586 
14587  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14588  }
14589 
14594  iterator insert(const_iterator pos, basic_json&& val)
14595  {
14596  return insert(pos, val);
14597  }
14598 
14623  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
14624  {
14625  // insert only works for arrays
14626  if (JSON_LIKELY(is_array()))
14627  {
14628  // check if iterator pos fits to this JSON value
14629  if (JSON_UNLIKELY(pos.m_object != this))
14630  {
14631  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14632  }
14633 
14634  // insert to array and return iterator
14635  iterator result(this);
14636  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
14637  return result;
14638  }
14639 
14640  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14641  }
14642 
14674  {
14675  // insert only works for arrays
14676  if (JSON_UNLIKELY(not is_array()))
14677  {
14678  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14679  }
14680 
14681  // check if iterator pos fits to this JSON value
14682  if (JSON_UNLIKELY(pos.m_object != this))
14683  {
14684  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14685  }
14686 
14687  // check if range iterators belong to the same JSON object
14688  if (JSON_UNLIKELY(first.m_object != last.m_object))
14689  {
14690  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14691  }
14692 
14693  if (JSON_UNLIKELY(first.m_object == this))
14694  {
14695  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
14696  }
14697 
14698  // insert to array and return iterator
14699  iterator result(this);
14700  result.m_it.array_iterator = m_value.array->insert(
14701  pos.m_it.array_iterator,
14702  first.m_it.array_iterator,
14703  last.m_it.array_iterator);
14704  return result;
14705  }
14706 
14732  {
14733  // insert only works for arrays
14734  if (JSON_UNLIKELY(not is_array()))
14735  {
14736  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14737  }
14738 
14739  // check if iterator pos fits to this JSON value
14740  if (JSON_UNLIKELY(pos.m_object != this))
14741  {
14742  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
14743  }
14744 
14745  // insert to array and return iterator
14746  iterator result(this);
14747  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
14748  return result;
14749  }
14750 
14775  {
14776  // insert only works for objects
14777  if (JSON_UNLIKELY(not is_object()))
14778  {
14779  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
14780  }
14781 
14782  // check if range iterators belong to the same JSON object
14783  if (JSON_UNLIKELY(first.m_object != last.m_object))
14784  {
14785  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14786  }
14787 
14788  // passed iterators must belong to objects
14789  if (JSON_UNLIKELY(not first.m_object->is_object()))
14790  {
14791  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
14792  }
14793 
14794  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
14795  }
14796 
14817  {
14818  // implicitly convert null value to an empty object
14819  if (is_null())
14820  {
14821  m_type = value_t::object;
14822  m_value.object = create<object_t>();
14823  assert_invariant();
14824  }
14825 
14826  if (JSON_UNLIKELY(not is_object()))
14827  {
14828  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
14829  }
14830  if (JSON_UNLIKELY(not j.is_object()))
14831  {
14832  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
14833  }
14834 
14835  for (auto it = j.cbegin(); it != j.cend(); ++it)
14836  {
14837  m_value.object->operator[](it.key()) = it.value();
14838  }
14839  }
14840 
14868  {
14869  // implicitly convert null value to an empty object
14870  if (is_null())
14871  {
14872  m_type = value_t::object;
14873  m_value.object = create<object_t>();
14874  assert_invariant();
14875  }
14876 
14877  if (JSON_UNLIKELY(not is_object()))
14878  {
14879  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
14880  }
14881 
14882  // check if range iterators belong to the same JSON object
14883  if (JSON_UNLIKELY(first.m_object != last.m_object))
14884  {
14885  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
14886  }
14887 
14888  // passed iterators must belong to objects
14889  if (JSON_UNLIKELY(not first.m_object->is_object()
14890  or not last.m_object->is_object()))
14891  {
14892  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
14893  }
14894 
14895  for (auto it = first; it != last; ++it)
14896  {
14897  m_value.object->operator[](it.key()) = it.value();
14898  }
14899  }
14900 
14918  void swap(reference other) noexcept (
14919  std::is_nothrow_move_constructible<value_t>::value and
14920  std::is_nothrow_move_assignable<value_t>::value and
14921  std::is_nothrow_move_constructible<json_value>::value and
14922  std::is_nothrow_move_assignable<json_value>::value
14923  )
14924  {
14925  std::swap(m_type, other.m_type);
14926  std::swap(m_value, other.m_value);
14927  assert_invariant();
14928  }
14929 
14950  void swap(array_t& other)
14951  {
14952  // swap only works for arrays
14953  if (JSON_LIKELY(is_array()))
14954  {
14955  std::swap(*(m_value.array), other);
14956  }
14957  else
14958  {
14959  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14960  }
14961  }
14962 
14983  void swap(object_t& other)
14984  {
14985  // swap only works for objects
14986  if (JSON_LIKELY(is_object()))
14987  {
14988  std::swap(*(m_value.object), other);
14989  }
14990  else
14991  {
14992  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
14993  }
14994  }
14995 
15016  void swap(string_t& other)
15017  {
15018  // swap only works for strings
15019  if (JSON_LIKELY(is_string()))
15020  {
15021  std::swap(*(m_value.string), other);
15022  }
15023  else
15024  {
15025  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
15026  }
15027  }
15028 
15030 
15031  public:
15033  // lexicographical comparison operators //
15035 
15038 
15078  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
15079  {
15080  const auto lhs_type = lhs.type();
15081  const auto rhs_type = rhs.type();
15082 
15083  if (lhs_type == rhs_type)
15084  {
15085  switch (lhs_type)
15086  {
15087  case value_t::array:
15088  return (*lhs.m_value.array == *rhs.m_value.array);
15089 
15090  case value_t::object:
15091  return (*lhs.m_value.object == *rhs.m_value.object);
15092 
15093  case value_t::null:
15094  return true;
15095 
15096  case value_t::string:
15097  return (*lhs.m_value.string == *rhs.m_value.string);
15098 
15099  case value_t::boolean:
15100  return (lhs.m_value.boolean == rhs.m_value.boolean);
15101 
15103  return (lhs.m_value.number_integer == rhs.m_value.number_integer);
15104 
15106  return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
15107 
15108  case value_t::number_float:
15109  return (lhs.m_value.number_float == rhs.m_value.number_float);
15110 
15111  default:
15112  return false;
15113  }
15114  }
15115  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
15116  {
15117  return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
15118  }
15119  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
15120  {
15121  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
15122  }
15123  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
15124  {
15125  return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
15126  }
15127  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
15128  {
15129  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
15130  }
15131  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
15132  {
15133  return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
15134  }
15135  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
15136  {
15137  return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
15138  }
15139 
15140  return false;
15141  }
15142 
15147  template<typename ScalarType, typename std::enable_if<
15148  std::is_scalar<ScalarType>::value, int>::type = 0>
15149  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
15150  {
15151  return (lhs == basic_json(rhs));
15152  }
15153 
15158  template<typename ScalarType, typename std::enable_if<
15159  std::is_scalar<ScalarType>::value, int>::type = 0>
15160  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
15161  {
15162  return (basic_json(lhs) == rhs);
15163  }
15164 
15183  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
15184  {
15185  return not (lhs == rhs);
15186  }
15187 
15192  template<typename ScalarType, typename std::enable_if<
15193  std::is_scalar<ScalarType>::value, int>::type = 0>
15194  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
15195  {
15196  return (lhs != basic_json(rhs));
15197  }
15198 
15203  template<typename ScalarType, typename std::enable_if<
15204  std::is_scalar<ScalarType>::value, int>::type = 0>
15205  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
15206  {
15207  return (basic_json(lhs) != rhs);
15208  }
15209 
15236  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
15237  {
15238  const auto lhs_type = lhs.type();
15239  const auto rhs_type = rhs.type();
15240 
15241  if (lhs_type == rhs_type)
15242  {
15243  switch (lhs_type)
15244  {
15245  case value_t::array:
15246  return (*lhs.m_value.array) < (*rhs.m_value.array);
15247 
15248  case value_t::object:
15249  return *lhs.m_value.object < *rhs.m_value.object;
15250 
15251  case value_t::null:
15252  return false;
15253 
15254  case value_t::string:
15255  return *lhs.m_value.string < *rhs.m_value.string;
15256 
15257  case value_t::boolean:
15258  return lhs.m_value.boolean < rhs.m_value.boolean;
15259 
15261  return lhs.m_value.number_integer < rhs.m_value.number_integer;
15262 
15264  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
15265 
15266  case value_t::number_float:
15267  return lhs.m_value.number_float < rhs.m_value.number_float;
15268 
15269  default:
15270  return false;
15271  }
15272  }
15273  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
15274  {
15275  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
15276  }
15277  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
15278  {
15279  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
15280  }
15281  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
15282  {
15283  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
15284  }
15285  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
15286  {
15287  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
15288  }
15289  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
15290  {
15291  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
15292  }
15293  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
15294  {
15295  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
15296  }
15297 
15298  // We only reach this line if we cannot compare values. In that case,
15299  // we compare types. Note we have to call the operator explicitly,
15300  // because MSVC has problems otherwise.
15301  return operator<(lhs_type, rhs_type);
15302  }
15303 
15308  template<typename ScalarType, typename std::enable_if<
15309  std::is_scalar<ScalarType>::value, int>::type = 0>
15310  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
15311  {
15312  return (lhs < basic_json(rhs));
15313  }
15314 
15319  template<typename ScalarType, typename std::enable_if<
15320  std::is_scalar<ScalarType>::value, int>::type = 0>
15321  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
15322  {
15323  return (basic_json(lhs) < rhs);
15324  }
15325 
15345  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
15346  {
15347  return not (rhs < lhs);
15348  }
15349 
15354  template<typename ScalarType, typename std::enable_if<
15355  std::is_scalar<ScalarType>::value, int>::type = 0>
15356  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
15357  {
15358  return (lhs <= basic_json(rhs));
15359  }
15360 
15365  template<typename ScalarType, typename std::enable_if<
15366  std::is_scalar<ScalarType>::value, int>::type = 0>
15367  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
15368  {
15369  return (basic_json(lhs) <= rhs);
15370  }
15371 
15391  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
15392  {
15393  return not (lhs <= rhs);
15394  }
15395 
15400  template<typename ScalarType, typename std::enable_if<
15401  std::is_scalar<ScalarType>::value, int>::type = 0>
15402  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
15403  {
15404  return (lhs > basic_json(rhs));
15405  }
15406 
15411  template<typename ScalarType, typename std::enable_if<
15412  std::is_scalar<ScalarType>::value, int>::type = 0>
15413  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
15414  {
15415  return (basic_json(lhs) > rhs);
15416  }
15417 
15437  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
15438  {
15439  return not (lhs < rhs);
15440  }
15441 
15446  template<typename ScalarType, typename std::enable_if<
15447  std::is_scalar<ScalarType>::value, int>::type = 0>
15448  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
15449  {
15450  return (lhs >= basic_json(rhs));
15451  }
15452 
15457  template<typename ScalarType, typename std::enable_if<
15458  std::is_scalar<ScalarType>::value, int>::type = 0>
15459  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
15460  {
15461  return (basic_json(lhs) >= rhs);
15462  }
15463 
15465 
15467  // serialization //
15469 
15472 
15504  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
15505  {
15506  // read width member and use it as indentation parameter if nonzero
15507  const bool pretty_print = (o.width() > 0);
15508  const auto indentation = (pretty_print ? o.width() : 0);
15509 
15510  // reset width to 0 for subsequent calls to this stream
15511  o.width(0);
15512 
15513  // do the actual serialization
15515  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
15516  return o;
15517  }
15518 
15528  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
15529  {
15530  return o << j;
15531  }
15532 
15534 
15535 
15537  // deserialization //
15539 
15542 
15605  static basic_json parse(detail::input_adapter i,
15606  const parser_callback_t cb = nullptr,
15607  const bool allow_exceptions = true)
15608  {
15609  basic_json result;
15610  parser(i, cb, allow_exceptions).parse(true, result);
15611  return result;
15612  }
15613 
15617  static basic_json parse(detail::input_adapter& i,
15618  const parser_callback_t cb = nullptr,
15619  const bool allow_exceptions = true)
15620  {
15621  basic_json result;
15622  parser(i, cb, allow_exceptions).parse(true, result);
15623  return result;
15624  }
15625 
15627  {
15628  return parser(i).accept(true);
15629  }
15630 
15632  {
15633  return parser(i).accept(true);
15634  }
15635 
15683  template<class IteratorType, typename std::enable_if<
15684  std::is_base_of<
15685  std::random_access_iterator_tag,
15686  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
15687  static basic_json parse(IteratorType first, IteratorType last,
15688  const parser_callback_t cb = nullptr,
15689  const bool allow_exceptions = true)
15690  {
15691  basic_json result;
15692  parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
15693  return result;
15694  }
15695 
15696  template<class IteratorType, typename std::enable_if<
15697  std::is_base_of<
15698  std::random_access_iterator_tag,
15699  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
15700  static bool accept(IteratorType first, IteratorType last)
15701  {
15702  return parser(detail::input_adapter(first, last)).accept(true);
15703  }
15704 
15714  friend std::istream& operator<<(basic_json& j, std::istream& i)
15715  {
15716  return operator>>(i, j);
15717  }
15718 
15744  friend std::istream& operator>>(std::istream& i, basic_json& j)
15745  {
15746  parser(detail::input_adapter(i)).parse(false, j);
15747  return i;
15748  }
15749 
15751 
15753  // convenience functions //
15755 
15786  const char* type_name() const noexcept
15787  {
15788  {
15789  switch (m_type)
15790  {
15791  case value_t::null:
15792  return "null";
15793  case value_t::object:
15794  return "object";
15795  case value_t::array:
15796  return "array";
15797  case value_t::string:
15798  return "string";
15799  case value_t::boolean:
15800  return "boolean";
15801  case value_t::discarded:
15802  return "discarded";
15803  default:
15804  return "number";
15805  }
15806  }
15807  }
15808 
15809 
15810  private:
15812  // member variables //
15814 
15817 
15819  json_value m_value = {};
15820 
15822  // binary serialization/deserialization //
15824 
15827 
15828  public:
15917  static std::vector<uint8_t> to_cbor(const basic_json& j)
15918  {
15919  std::vector<uint8_t> result;
15920  to_cbor(j, result);
15921  return result;
15922  }
15923 
15924  static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
15925  {
15926  binary_writer<uint8_t>(o).write_cbor(j);
15927  }
15928 
15929  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
15930  {
15931  binary_writer<char>(o).write_cbor(j);
15932  }
15933 
16014  static std::vector<uint8_t> to_msgpack(const basic_json& j)
16015  {
16016  std::vector<uint8_t> result;
16017  to_msgpack(j, result);
16018  return result;
16019  }
16020 
16021  static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
16022  {
16023  binary_writer<uint8_t>(o).write_msgpack(j);
16024  }
16025 
16026  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
16027  {
16028  binary_writer<char>(o).write_msgpack(j);
16029  }
16030 
16111  static std::vector<uint8_t> to_ubjson(const basic_json& j,
16112  const bool use_size = false,
16113  const bool use_type = false)
16114  {
16115  std::vector<uint8_t> result;
16116  to_ubjson(j, result, use_size, use_type);
16117  return result;
16118  }
16119 
16120  static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
16121  const bool use_size = false, const bool use_type = false)
16122  {
16123  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
16124  }
16125 
16126  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
16127  const bool use_size = false, const bool use_type = false)
16128  {
16129  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
16130  }
16131 
16225  static basic_json from_cbor(detail::input_adapter i,
16226  const bool strict = true)
16227  {
16228  return binary_reader(i).parse_cbor(strict);
16229  }
16230 
16234  template<typename A1, typename A2,
16236  static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true)
16237  {
16238  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
16239  }
16240 
16315  const bool strict = true)
16316  {
16317  return binary_reader(i).parse_msgpack(strict);
16318  }
16319 
16323  template<typename A1, typename A2,
16324  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
16325  static basic_json from_msgpack(A1 && a1, A2 && a2, const bool strict = true)
16326  {
16327  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
16328  }
16329 
16383  static basic_json from_ubjson(detail::input_adapter i,
16384  const bool strict = true)
16385  {
16386  return binary_reader(i).parse_ubjson(strict);
16387  }
16388 
16389  template<typename A1, typename A2,
16390  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
16391  static basic_json from_ubjson(A1 && a1, A2 && a2, const bool strict = true)
16392  {
16393  return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
16394  }
16395 
16397 
16399  // JSON Pointer support //
16401 
16404 
16439  {
16440  return ptr.get_unchecked(this);
16441  }
16442 
16467  {
16468  return ptr.get_unchecked(this);
16469  }
16470 
16510  {
16511  return ptr.get_checked(this);
16512  }
16513 
16552  const_reference at(const json_pointer& ptr) const
16553  {
16554  return ptr.get_checked(this);
16555  }
16556 
16579  basic_json flatten() const
16580  {
16581  basic_json result(value_t::object);
16582  json_pointer::flatten("", *this, result);
16583  return result;
16584  }
16585 
16616  basic_json unflatten() const
16617  {
16618  return json_pointer::unflatten(*this);
16619  }
16620 
16622 
16624  // JSON Patch functions //
16626 
16629 
16677  basic_json patch(const basic_json& json_patch) const
16678  {
16679  // make a working copy to apply the patch to
16680  basic_json result = *this;
16681 
16682  // the valid JSON Patch operations
16683  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
16684 
16685  const auto get_op = [](const std::string & op)
16686  {
16687  if (op == "add")
16688  {
16689  return patch_operations::add;
16690  }
16691  if (op == "remove")
16692  {
16693  return patch_operations::remove;
16694  }
16695  if (op == "replace")
16696  {
16697  return patch_operations::replace;
16698  }
16699  if (op == "move")
16700  {
16701  return patch_operations::move;
16702  }
16703  if (op == "copy")
16704  {
16705  return patch_operations::copy;
16706  }
16707  if (op == "test")
16708  {
16709  return patch_operations::test;
16710  }
16711 
16712  return patch_operations::invalid;
16713  };
16714 
16715  // wrapper for "add" operation; add value at ptr
16716  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
16717  {
16718  // adding to the root of the target document means replacing it
16719  if (ptr.is_root())
16720  {
16721  result = val;
16722  }
16723  else
16724  {
16725  // make sure the top element of the pointer exists
16726  json_pointer top_pointer = ptr.top();
16727  if (top_pointer != ptr)
16728  {
16729  result.at(top_pointer);
16730  }
16731 
16732  // get reference to parent of JSON pointer ptr
16733  const auto last_path = ptr.pop_back();
16734  basic_json& parent = result[ptr];
16735 
16736  switch (parent.m_type)
16737  {
16738  case value_t::null:
16739  case value_t::object:
16740  {
16741  // use operator[] to add value
16742  parent[last_path] = val;
16743  break;
16744  }
16745 
16746  case value_t::array:
16747  {
16748  if (last_path == "-")
16749  {
16750  // special case: append to back
16751  parent.push_back(val);
16752  }
16753  else
16754  {
16755  const auto idx = json_pointer::array_index(last_path);
16756  if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
16757  {
16758  // avoid undefined behavior
16759  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
16760  }
16761  else
16762  {
16763  // default case: insert add offset
16764  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
16765  }
16766  }
16767  break;
16768  }
16769 
16770  default:
16771  {
16772  // if there exists a parent it cannot be primitive
16773  assert(false); // LCOV_EXCL_LINE
16774  }
16775  }
16776  }
16777  };
16778 
16779  // wrapper for "remove" operation; remove value at ptr
16780  const auto operation_remove = [&result](json_pointer & ptr)
16781  {
16782  // get reference to parent of JSON pointer ptr
16783  const auto last_path = ptr.pop_back();
16784  basic_json& parent = result.at(ptr);
16785 
16786  // remove child
16787  if (parent.is_object())
16788  {
16789  // perform range check
16790  auto it = parent.find(last_path);
16791  if (JSON_LIKELY(it != parent.end()))
16792  {
16793  parent.erase(it);
16794  }
16795  else
16796  {
16797  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
16798  }
16799  }
16800  else if (parent.is_array())
16801  {
16802  // note erase performs range check
16803  parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
16804  }
16805  };
16806 
16807  // type check: top level value must be an array
16808  if (JSON_UNLIKELY(not json_patch.is_array()))
16809  {
16810  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
16811  }
16812 
16813  // iterate and apply the operations
16814  for (const auto& val : json_patch)
16815  {
16816  // wrapper to get a value for an operation
16817  const auto get_value = [&val](const std::string & op,
16818  const std::string & member,
16819  bool string_type) -> basic_json &
16820  {
16821  // find value
16822  auto it = val.m_value.object->find(member);
16823 
16824  // context-sensitive error message
16825  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
16826 
16827  // check if desired value is present
16828  if (JSON_UNLIKELY(it == val.m_value.object->end()))
16829  {
16830  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
16831  }
16832 
16833  // check if result is of type string
16834  if (JSON_UNLIKELY(string_type and not it->second.is_string()))
16835  {
16836  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
16837  }
16838 
16839  // no error: return value
16840  return it->second;
16841  };
16842 
16843  // type check: every element of the array must be an object
16844  if (JSON_UNLIKELY(not val.is_object()))
16845  {
16846  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
16847  }
16848 
16849  // collect mandatory members
16850  const std::string op = get_value("op", "op", true);
16851  const std::string path = get_value(op, "path", true);
16852  json_pointer ptr(path);
16853 
16854  switch (get_op(op))
16855  {
16856  case patch_operations::add:
16857  {
16858  operation_add(ptr, get_value("add", "value", false));
16859  break;
16860  }
16861 
16862  case patch_operations::remove:
16863  {
16864  operation_remove(ptr);
16865  break;
16866  }
16867 
16868  case patch_operations::replace:
16869  {
16870  // the "path" location must exist - use at()
16871  result.at(ptr) = get_value("replace", "value", false);
16872  break;
16873  }
16874 
16875  case patch_operations::move:
16876  {
16877  const std::string from_path = get_value("move", "from", true);
16878  json_pointer from_ptr(from_path);
16879 
16880  // the "from" location must exist - use at()
16881  basic_json v = result.at(from_ptr);
16882 
16883  // The move operation is functionally identical to a
16884  // "remove" operation on the "from" location, followed
16885  // immediately by an "add" operation at the target
16886  // location with the value that was just removed.
16887  operation_remove(from_ptr);
16888  operation_add(ptr, v);
16889  break;
16890  }
16891 
16892  case patch_operations::copy:
16893  {
16894  const std::string from_path = get_value("copy", "from", true);
16895  const json_pointer from_ptr(from_path);
16896 
16897  // the "from" location must exist - use at()
16898  basic_json v = result.at(from_ptr);
16899 
16900  // The copy is functionally identical to an "add"
16901  // operation at the target location using the value
16902  // specified in the "from" member.
16903  operation_add(ptr, v);
16904  break;
16905  }
16906 
16907  case patch_operations::test:
16908  {
16909  bool success = false;
16910  JSON_TRY
16911  {
16912  // check if "value" matches the one at "path"
16913  // the "path" location must exist - use at()
16914  success = (result.at(ptr) == get_value("test", "value", false));
16915  }
16917  {
16918  // ignore out of range errors: success remains false
16919  }
16920 
16921  // throw an exception if test fails
16922  if (JSON_UNLIKELY(not success))
16923  {
16924  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
16925  }
16926 
16927  break;
16928  }
16929 
16930  case patch_operations::invalid:
16931  {
16932  // op must be "add", "remove", "replace", "move", "copy", or
16933  // "test"
16934  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
16935  }
16936  }
16937  }
16938 
16939  return result;
16940  }
16941 
16975  static basic_json diff(const basic_json& source, const basic_json& target,
16976  const std::string& path = "")
16977  {
16978  // the patch
16979  basic_json result(value_t::array);
16980 
16981  // if the values are the same, return empty patch
16982  if (source == target)
16983  {
16984  return result;
16985  }
16986 
16987  if (source.type() != target.type())
16988  {
16989  // different types: replace value
16990  result.push_back(
16991  {
16992  {"op", "replace"}, {"path", path}, {"value", target}
16993  });
16994  }
16995  else
16996  {
16997  switch (source.type())
16998  {
16999  case value_t::array:
17000  {
17001  // first pass: traverse common elements
17002  std::size_t i = 0;
17003  while (i < source.size() and i < target.size())
17004  {
17005  // recursive call to compare array values at index i
17006  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
17007  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
17008  ++i;
17009  }
17010 
17011  // i now reached the end of at least one array
17012  // in a second pass, traverse the remaining elements
17013 
17014  // remove my remaining elements
17015  const auto end_index = static_cast<difference_type>(result.size());
17016  while (i < source.size())
17017  {
17018  // add operations in reverse order to avoid invalid
17019  // indices
17020  result.insert(result.begin() + end_index, object(
17021  {
17022  {"op", "remove"},
17023  {"path", path + "/" + std::to_string(i)}
17024  }));
17025  ++i;
17026  }
17027 
17028  // add other remaining elements
17029  while (i < target.size())
17030  {
17031  result.push_back(
17032  {
17033  {"op", "add"},
17034  {"path", path + "/" + std::to_string(i)},
17035  {"value", target[i]}
17036  });
17037  ++i;
17038  }
17039 
17040  break;
17041  }
17042 
17043  case value_t::object:
17044  {
17045  // first pass: traverse this object's elements
17046  for (auto it = source.cbegin(); it != source.cend(); ++it)
17047  {
17048  // escape the key name to be used in a JSON patch
17049  const auto key = json_pointer::escape(it.key());
17050 
17051  if (target.find(it.key()) != target.end())
17052  {
17053  // recursive call to compare object values at key it
17054  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
17055  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
17056  }
17057  else
17058  {
17059  // found a key that is not in o -> remove it
17060  result.push_back(object(
17061  {
17062  {"op", "remove"}, {"path", path + "/" + key}
17063  }));
17064  }
17065  }
17066 
17067  // second pass: traverse other object's elements
17068  for (auto it = target.cbegin(); it != target.cend(); ++it)
17069  {
17070  if (source.find(it.key()) == source.end())
17071  {
17072  // found a key that is not in this -> add it
17073  const auto key = json_pointer::escape(it.key());
17074  result.push_back(
17075  {
17076  {"op", "add"}, {"path", path + "/" + key},
17077  {"value", it.value()}
17078  });
17079  }
17080  }
17081 
17082  break;
17083  }
17084 
17085  default:
17086  {
17087  // both primitive type: replace value
17088  result.push_back(
17089  {
17090  {"op", "replace"}, {"path", path}, {"value", target}
17091  });
17092  break;
17093  }
17094  }
17095  }
17096 
17097  return result;
17098  }
17099 
17101 
17103  // JSON Merge Patch functions //
17105 
17108 
17151  void merge_patch(const basic_json& patch)
17152  {
17153  if (patch.is_object())
17154  {
17155  if (not is_object())
17156  {
17157  *this = object();
17158  }
17159  for (auto it = patch.begin(); it != patch.end(); ++it)
17160  {
17161  if (it.value().is_null())
17162  {
17163  erase(it.key());
17164  }
17165  else
17166  {
17167  operator[](it.key()).merge_patch(it.value());
17168  }
17169  }
17170  }
17171  else
17172  {
17173  *this = patch;
17174  }
17175  }
17176 
17178 };
17179 } // namespace nlohmann
17180 
17182 // nonmember support //
17184 
17185 // specialization of std::swap, and std::hash
17186 namespace std
17187 {
17193 template<>
17194 inline void swap(nlohmann::json& j1,
17195  nlohmann::json& j2) noexcept(
17196  is_nothrow_move_constructible<nlohmann::json>::value and
17197  is_nothrow_move_assignable<nlohmann::json>::value
17198  )
17199 {
17200  j1.swap(j2);
17201 }
17202 
17204 template<>
17205 struct hash<nlohmann::json>
17206 {
17212  std::size_t operator()(const nlohmann::json& j) const
17213  {
17214  // a naive hashing via the string representation
17215  const auto& h = hash<nlohmann::json::string_t>();
17216  return h(j.dump());
17217  }
17218 };
17219 
17223 template<>
17225 {
17231  nlohmann::detail::value_t rhs) const noexcept
17232  {
17233  return nlohmann::detail::operator<(lhs, rhs);
17234  }
17235 };
17236 
17237 } // namespace std
17238 
17252 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
17253 {
17254  return nlohmann::json::parse(s, s + n);
17255 }
17256 
17270 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
17271 {
17273 }
17274 
17275 // #include <nlohmann/detail/macro_unscope.hpp>
17276 
17277 
17278 // restore GCC/clang diagnostic settings
17279 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
17280  #pragma GCC diagnostic pop
17281 #endif
17282 #if defined(__clang__)
17283  #pragma GCC diagnostic pop
17284 #endif
17285 
17286 // clean up
17287 #undef JSON_CATCH
17288 #undef JSON_THROW
17289 #undef JSON_TRY
17290 #undef JSON_LIKELY
17291 #undef JSON_UNLIKELY
17292 #undef JSON_DEPRECATED
17293 #undef JSON_HAS_CPP_14
17294 #undef JSON_HAS_CPP_17
17295 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
17296 #undef NLOHMANN_BASIC_JSON_TPL
17297 #undef NLOHMANN_JSON_HAS_HELPER
17298 
17299 
17300 #endif
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:10565
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: json.hpp:6918
d
Definition: setup.py:29
object_t * object
object (stored with pointer to save storage)
Definition: json.hpp:10469
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:14347
value_type const & operator*() const
Definition: json.hpp:8913
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:11227
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:10589
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:13492
reference value() const
return the value of an iterator
Definition: json.hpp:4702
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14867
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:11990
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:2961
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:13883
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
Definition: json.hpp:10717
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:1346
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4396
token_type
token types for the parser
Definition: json.hpp:1878
const int id
the id of the exception
Definition: json.hpp:546
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:11972
input_buffer_adapter(const char *b, const std::size_t l)
Definition: json.hpp:1700
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:635
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:1621
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:9787
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:12026
input_adapter(IteratorType first, IteratorType last)
input adapter for iterator range with contiguous storage
Definition: json.hpp:1782
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:14146
BasicJsonType get_msgpack_object(const NumberType len)
Definition: json.hpp:5913
static JSON_DEPRECATED iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:13874
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:15236
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13940
std::initializer_list< detail::json_ref< basic_json >> initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:9817
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8268
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:11434
#define JSON_CATCH(exception)
Definition: json.hpp:160
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:10415
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:7210
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4336
value_t
the JSON type enumeration
Definition: json.hpp:865
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:10886
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:3824
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:4374
ROSCPP_DECL void start()
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:7729
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:4695
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:12963
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:13948
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:3960
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:13197
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:4653
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:1292
~basic_json() noexcept
destructor
Definition: json.hpp:11504
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:10471
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:10849
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:10473
void unget_character() override
restore the last non-eof() character to input
Definition: json.hpp:1685
static bool accept(detail::input_adapter i)
Definition: json.hpp:15626
static void strtof(long double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:2506
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:271
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:1336
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:12393
void destroy(value_t t) noexcept
Definition: json.hpp:10594
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:3798
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:10559
f
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:13033
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:4629
a signed integer – use get_number_integer() for actual value
constexpr int kAlpha
Definition: json.hpp:7451
array (ordered collection of values)
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:16552
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:8977
json_ref(Args &&...args)
Definition: json.hpp:8895
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:3786
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:10347
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:11607
boolean_t boolean
boolean
Definition: json.hpp:10475
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15356
static other_error create(int id_, const std::string &what_arg)
Definition: json.hpp:813
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:4171
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:10492
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:10494
bool expect(token_type t)
Definition: json.hpp:3658
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.hpp:9492
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:10276
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:12762
a template for a reverse iterator class
Definition: json.hpp:4624
const char indent_char
the indentation character
Definition: json.hpp:8859
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:4000
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:11637
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:558
a class to store JSON values
Definition: json.hpp:85
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:16026
constexpr diyfp(uint64_t f_, int e_) noexcept
Definition: json.hpp:7204
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:16021
void init(const M_string &remappings)
constexpr int kGamma
Definition: json.hpp:7452
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:9869
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
Definition: json.hpp:1047
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:16509
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:14594
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:1872
bool is_root() const
return whether pointer points to the root document
Definition: json.hpp:9051
value_type moved_or_copied() const
Definition: json.hpp:8904
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:10758
default JSONSerializer template argument
Definition: json.hpp:73
bool call(const std::string &service_name, MReq &req, MRes &res)
std::shared_ptr< output_adapter_protocol< CharType >> output_adapter_t
a type to simplify interfaces
Definition: json.hpp:4737
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14774
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:4203
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:11978
typename lexer_t::token_type token_type
Definition: json.hpp:3161
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:12002
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:11664
static std::string escape(std::string s)
escape "~"" to "~0" and "/" to "~1"
Definition: json.hpp:9504
string_t get_msgpack_string()
reads a MessagePack string
Definition: json.hpp:5833
XmlRpcServer s
void unget_character() noexceptoverride
restore the last non-eof() character to input
Definition: json.hpp:1724
input_adapter(T(&array)[N])
input adapter for array
Definition: json.hpp:1814
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:15504
type_error(int id_, const char *what_arg)
Definition: json.hpp:738
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:9888
StringType string_t
a type for a string
Definition: json.hpp:10178
JSON_DEPRECATED friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:15714
lexer_t m_lexer
the lexer
Definition: json.hpp:3706
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:3200
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:7304
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:13637
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
Definition: json.hpp:10079
number value (signed integer)
std::char_traits< char >::int_type get_character() noexceptoverride
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:1714
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:1871
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:11162
Target reinterpret_bits(const Source source)
Definition: json.hpp:7187
std::pair< std::size_t, int > get_ubjson_size_type()
determine the type and size for a container
Definition: json.hpp:5981
bool operator!=(const iteration_proxy_internal &o) const noexcept
inequality operator (needed for range-based for)
Definition: json.hpp:4534
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:4407
BasicJsonType parse_msgpack_internal()
Definition: json.hpp:5280
void dump_integer(NumberType x)
dump an integer
Definition: json.hpp:8669
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:14918
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:13566
output_adapter(StringType &s)
Definition: json.hpp:4812
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:1272
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:16677
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:4665
bool operator==(const in6_addr a, const in6_addr b)
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:4683
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:9861
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
Definition: json.hpp:9512
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:14397
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:14673
input_adapter(CharT b, std::size_t l)
input adapter for buffer
Definition: json.hpp:1761
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:15205
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:9076
pointer m_object
associated JSON instance
Definition: json.hpp:4482
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:8307
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:15402
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4572
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:4365
void from_json(const BasicJsonType &j, std::tuple< Args... > &t)
Definition: json.hpp:1182
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13715
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:10479
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:4058
number_float_t number_float
number (floating-point)
Definition: json.hpp:10481
BasicJsonType parse_cbor_internal(const bool get_char=true)
Definition: json.hpp:4963
pointer operator->() const
dereference the iterator
Definition: json.hpp:4126
a template for a bidirectional iterator for the basic_json class
Definition: json.hpp:3915
void expect_eof() const
throw if end of input is not reached
Definition: json.hpp:6170
token_type get_token()
get next token from lexer
Definition: json.hpp:3650
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:15160
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:935
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:9803
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:3935
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:11845
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:4809
void write_character(CharType c) override
Definition: json.hpp:4788
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:7468
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:4634
BasicJsonType parse_ubjson(const bool strict)
create a JSON value from UBJSON input
Definition: json.hpp:4934
#define JSON_UNLIKELY(x)
Definition: json.hpp:183
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:9417
lexical analysis
Definition: json.hpp:1869
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:4671
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:1304
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4428
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:3759
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:4877
BasicJsonType get_cbor_object(const NumberType len)
Definition: json.hpp:5807
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:1980
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:9615
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:15413
syntax analysis
Definition: json.hpp:3154
void emplace_back(Args &&...args)
add an object to an array
Definition: json.hpp:14474
serialization to CBOR and MessagePack values
Definition: json.hpp:6232
serializer(output_adapter_t< char > s, const char ichar)
Definition: json.hpp:8279
output adapter for byte vectors
Definition: json.hpp:4741
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:11996
const std::size_t byte
byte index of the parse error
Definition: json.hpp:632
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:4689
abstract input adapter interface
Definition: json.hpp:1611
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:4751
void unget()
unget current character (return it again on next get)
Definition: json.hpp:2932
string_t && move_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:2973
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:10488
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15448
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:3858
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:1418
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:9673
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:4327
static void strtof(double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:2501
NLOHMANN_JSON_HAS_HELPER(mapped_type)
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:11135
exception indicating access out of the defined range
Definition: json.hpp:773
bool next_byte_in_range(std::initializer_list< int > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:2028
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:11686
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:11823
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
Definition: json.hpp:3181
token_type scan()
Definition: json.hpp:3025
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:3811
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:9815
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:13475
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:12724
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:3753
void write_msgpack(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6492
void parse_internal(bool keep, BasicJsonType &result)
the actual parser
Definition: json.hpp:3257
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:7287
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:12483
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:10782
primitive_iterator_t const operator++(int) noexcept
Definition: json.hpp:3804
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4867
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:13389
void add(int c)
add a character to token_buffer
Definition: json.hpp:2944
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:15310
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:11351
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:4318
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:4160
const_reference back() const
access the last element
Definition: json.hpp:13140
const_reference front() const
access the first element
Definition: json.hpp:13094
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:1384
void clear() noexcept
clears the contents
Definition: json.hpp:14216
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:14623
void throw_exception() const
Definition: json.hpp:3677
static T * create(Args &&...args)
helper for exception-safe object creation
Definition: json.hpp:10423
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:14446
BasicJsonType get_ubjson_array()
Definition: json.hpp:6072
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:2955
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:11738
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:13526
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:16975
exception indicating a parse error
Definition: json.hpp:604
reference operator[](T *key)
access specified object element
Definition: json.hpp:12851
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:11955
#define JSON_THROW(exception)
Definition: json.hpp:158
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:2967
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:4638
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:12632
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:16314
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:16126
const char * what() const noexceptoverride
returns the explanatory string
Definition: json.hpp:540
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 >{})))
Definition: json.hpp:1213
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:16438
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:16616
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:4641
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:1328
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:12581
std::vector< CharType > & v
Definition: json.hpp:4757
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:4631
an unsigned integer – use get_number_unsigned() for actual value
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:2903
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:3862
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:12811
abstract output adapter interface
Definition: json.hpp:4728
void write_character(CharType c) override
Definition: json.hpp:4746
#define JSON_DEPRECATED
Definition: json.hpp:149
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:15929
general exception of the basic_json class
Definition: json.hpp:536
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:17212
basic_json(const detail::json_ref< basic_json > &ref)
Definition: json.hpp:11322
IteratorType::reference container
the container to iterate
Definition: json.hpp:4568
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:14076
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:16111
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:7329
out_of_range(int id_, const char *what_arg)
Definition: json.hpp:783
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:12331
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:9156
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:15917
value_type const * operator->() const
Definition: json.hpp:8918
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:8066
std::string pop_back()
remove and return last reference pointer
Definition: json.hpp:9038
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:3158
auto call(const BasicJsonType &j, T &val, priority_tag< 1 >) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
Definition: json.hpp:1191
reference back()
access the last element
Definition: json.hpp:13130
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:1316
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:3860
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
Definition: json.hpp:1526
string_t get_ubjson_string(const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:5944
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:3949
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:15149
string_t get_string(const NumberType len)
create a string by reading characters from the input
Definition: json.hpp:5697
output_adapter(std::vector< CharType > &vec)
Definition: json.hpp:4806
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:15786
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:4484
void write_number(const NumberType n)
Definition: json.hpp:6899
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:16325
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:9232
void dump_float(number_float_t x, std::false_type)
Definition: json.hpp:8739
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13576
input_adapter(CharT b)
input adapter for string literal
Definition: json.hpp:1773
exception indicating errors with iterators
Definition: json.hpp:676
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:13744
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:11708
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:888
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:1176
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:7969
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:12014
namespace for Niels Lohmann
Definition: json.hpp:63
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:8890
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:13302
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:12008
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:11889
constexpr difference_type get_value() const noexcept
Definition: json.hpp:3747
input adapter for buffer input
Definition: json.hpp:1697
an floating point number – use get_number_float() for actual value
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8269
object (unordered set of name/value pairs)
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:12061
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4525
void dump_float(number_float_t x, std::true_type)
Definition: json.hpp:8731
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:12380
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:3156
std::string key() const
return key of the iterator
Definition: json.hpp:4540
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:268
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:3944
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:205
string_t get_cbor_string()
reads a CBOR string
Definition: json.hpp:5721
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:9621
exception indicating executing a member function with a wrong type
Definition: json.hpp:728
value_t m_type
the type of the current element
Definition: json.hpp:15816
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:10490
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15367
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:34
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:9525
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:3765
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:12303
void assert_invariant() const noexcept
checks the class invariants
Definition: json.hpp:10639
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:2496
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:15744
#define JSON_LIKELY(x)
Definition: json.hpp:182
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:15078
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:1392
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:16579
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer.
Definition: json.hpp:9813
typename parser::parse_event_t parse_event_t
parser event types
Definition: json.hpp:10666
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:14323
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:14428
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:4772
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:3184
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:15687
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
Definition: json.hpp:17151
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:16236
constexpr diyfp() noexcept
Definition: json.hpp:7203
static invalid_iterator create(int id_, const std::string &what_arg)
Definition: json.hpp:679
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:17194
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
Definition: json.hpp:10125
const char * cursor
pointer to the current character
Definition: json.hpp:1734
static int array_index(const std::string &s)
Definition: json.hpp:9019
#define JSON_TRY
Definition: json.hpp:159
const char * limit
pointer past the last character
Definition: json.hpp:1736
typename BasicJsonType::string_t string_t
Definition: json.hpp:3159
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:4459
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:11916
output adapter for basic_string
Definition: json.hpp:4783
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:14816
input_stream_adapter(std::istream &i)
Definition: json.hpp:1642
BasicJsonType get_ubjson_object()
Definition: json.hpp:6117
input_adapter(std::istream &&i)
input adapter for input stream
Definition: json.hpp:1751
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:10204
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:15391
constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:3016
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:6240
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:3236
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:9588
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:8116
output adapter for output streams
Definition: json.hpp:4762
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:4089
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:15605
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4868
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:33
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:14313
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 >{})))
Definition: json.hpp:1557
typename BasicJsonType::object_t object_t
Definition: json.hpp:3922
void dump_float(number_float_t x)
dump a floating-point number
Definition: json.hpp:8710
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:4282
output_vector_adapter(std::vector< CharType > &vec)
Definition: json.hpp:4744
json_ref(value_type &&value)
Definition: json.hpp:8882
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:11767
exception indicating other library errors
Definition: json.hpp:810
invalid_iterator(int id_, const char *what_arg)
Definition: json.hpp:686
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:551
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:3771
typename BasicJsonType::string_t string_t
Definition: json.hpp:8267
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:13606
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15459
void swap(array_t &other)
exchanges the values
Definition: json.hpp:14950
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:11966
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:9871
deserialization of CBOR and MessagePack values
Definition: json.hpp:4865
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:9356
const char * start
pointer to the first character
Definition: json.hpp:1738
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:1520
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:3938
static uint8_t decode(uint8_t &state, uint32_t &codep, const uint8_t byte) noexcept
check whether a string is UTF-8 encoded
Definition: json.hpp:8809
std::char_traits< char >::int_type get_character() override
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:1680
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:3776
std::basic_ostream< CharType > & stream
Definition: json.hpp:4778
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:17230
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:11795
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:11984
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:16120
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:1356
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4576
static constexpr std::size_t size() noexcept
Definition: json.hpp:280
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:10577
void write_character(CharType c) override
Definition: json.hpp:4767
number_integer_t number_integer
number (integer)
Definition: json.hpp:10477
BasicJsonType value_type
Definition: json.hpp:8880
void swap(string_t &other)
exchanges the values
Definition: json.hpp:15016
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:4009
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:3157
exception(int id_, const char *what_arg)
Definition: json.hpp:549
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:10583
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4561
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:13056
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:4214
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:14570
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:11867
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:1370
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13647
std::less< StringType > object_comparator_t
Definition: json.hpp:9989
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:13781
typename BasicJsonType::string_t string_t
Definition: json.hpp:1874
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:4519
BasicJsonType get_msgpack_array(const NumberType len)
Definition: json.hpp:5902
BasicJsonType parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:5610
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:1401
static out_of_range create(int id_, const std::string &what_arg)
Definition: json.hpp:776
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:14731
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8270
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:1900
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:10486
void dump_escaped(const string_t &s, const bool ensure_ascii)
dump escaped string
Definition: json.hpp:8514
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:3940
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:16225
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:8996
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:2883
primitive_iterator_t const operator--(int) noexcept
Definition: json.hpp:3817
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:12678
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:16466
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:12530
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:14287
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:6734
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:15321
reference front()
access the first element
Definition: json.hpp:13086
JSON Pointer.
Definition: json.hpp:99
typename BasicJsonType::string_t string_t
Definition: json.hpp:4869
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:13707
token_type scan_number()
scan a number literal
Definition: json.hpp:2551
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:4309
BasicJsonType parse_msgpack(const bool strict)
create a JSON value from MessagePack input
Definition: json.hpp:4913
number value (unsigned integer)
char ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.hpp:7044
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:9863
typename BasicJsonType::array_t array_t
Definition: json.hpp:3923
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:13810
void call(BasicJsonType &, T &&, priority_tag< 0 >) const noexcept
Definition: json.hpp:1542
static bool accept(IteratorType first, IteratorType last)
Definition: json.hpp:15700
static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict=true)
Definition: json.hpp:16391
basic_json<> json
default JSON class
Definition: json.hpp:109
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:9297
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:15194
BasicJsonType parse_cbor(const bool strict)
create a JSON value from CBOR input
Definition: json.hpp:4892
std::istream & is
the associated input stream
Definition: json.hpp:1692
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:3793
input_adapter(std::istream &i)
input adapter for input stream
Definition: json.hpp:1747
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:4273
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:4677
void swap(object_t &other)
exchanges the values
Definition: json.hpp:14983
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:10571
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:16014
static char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:1954
constexpr std::size_t get_position() const noexcept
return position of last read token
Definition: json.hpp:2983
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:8028
string_t dump(const int indent=-1, const char indent_char= ' ', const bool ensure_ascii=false) const
serialization
Definition: json.hpp:11557
void call(const BasicJsonType &, T &, priority_tag< 0 >) const noexcept
Definition: json.hpp:1199
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
Definition: json.hpp:961
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:13677
proxy class for the items() function
Definition: json.hpp:3892
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:12038
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:4659
reference value() const
return the value of an iterator
Definition: json.hpp:4475
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:4246
output_stream_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:4765
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:11471
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:14373
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:4793
string_t indent_string
the indentation string
Definition: json.hpp:8861
other_error(int id_, const char *what_arg)
Definition: json.hpp:820
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:12032
BasicJsonType get_ubjson_value(const int prefix)
Definition: json.hpp:6011
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:11003
JSON_DEPRECATED friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:15528
bool accept_internal()
the actual acceptor
Definition: json.hpp:3546
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:3781
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:11092
auto call(BasicJsonType &j, T &&val, priority_tag< 1 >) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:1535
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:15345
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:13424
token_type scan_string()
scan a string literal
Definition: json.hpp:2065
def is_string(t)
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:15437
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4582
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:9628
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:15183
void write_cbor(const BasicJsonType &j)
[in] j JSON value to serialize
Definition: json.hpp:6248
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:1873
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:615
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:1260
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
Definition: json.hpp:14522
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:12044
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:1280
static bool accept(detail::input_adapter &i)
Definition: json.hpp:15631
static type_error create(int id_, const std::string &what_arg)
Definition: json.hpp:731
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:197
void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta, uint64_t rest, uint64_t ten_k)
Definition: json.hpp:7688
std::string get_token_string() const
Definition: json.hpp:2991
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:9866
json_ref(const value_type &value)
Definition: json.hpp:8886
input_adapter(const ContiguousContainer &c)
input adapter for contiguous container
Definition: json.hpp:1822
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:4647
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:3830
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:16383
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:15924
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:4952
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
Definition: json.hpp:7632
json_value m_value
the value of the current element
Definition: json.hpp:15819
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:15617
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:12901
json_pointer top() const
Definition: json.hpp:9056
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:4385
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:8199
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:13752
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:32
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:12985
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:14004
BasicJsonType get_cbor_array(const NumberType len)
Definition: json.hpp:5796
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:4021
static basic_json meta()
returns version information on the library
Definition: json.hpp:9919
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:7222
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:12020
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:9657
lexer(detail::input_adapter_t adapter)
Definition: json.hpp:1941


json_transport
Author(s): Paul Bovbel
autogenerated on Thu Jun 13 2019 19:12:24