Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
json.hpp
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.4.0
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef NLOHMANN_JSON_HPP
31 #define NLOHMANN_JSON_HPP
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 4
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <ciso646> // and, not, or
40 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
41 #include <functional> // hash, less
42 #include <initializer_list> // initializer_list
43 #include <iosfwd> // istream, ostream
44 #include <iterator> // iterator_traits, random_access_iterator_tag
45 #include <numeric> // accumulate
46 #include <string> // string, stoi, to_string
47 #include <utility> // declval, forward, move, pair, swap
48 
49 // #include <nlohmann/json_fwd.hpp>
50 #ifndef NLOHMANN_JSON_FWD_HPP
51 #define NLOHMANN_JSON_FWD_HPP
52 
53 #include <cstdint> // int64_t, uint64_t
54 #include <map> // map
55 #include <memory> // allocator
56 #include <string> // string
57 #include <vector> // vector
58 
64 namespace nlohmann
65 {
73 template<typename T = void, typename SFINAE = void>
75 
76 template<template<typename U, typename V, typename... Args> class ObjectType =
77  std::map,
78  template<typename U, typename... Args> class ArrayType = std::vector,
79  class StringType = std::string, class BooleanType = bool,
80  class NumberIntegerType = std::int64_t,
81  class NumberUnsignedType = std::uint64_t,
82  class NumberFloatType = double,
83  template<typename U> class AllocatorType = std::allocator,
84  template<typename T, typename SFINAE = void> class JSONSerializer =
86 class basic_json;
87 
99 template<typename BasicJsonType>
101 
111 } // namespace nlohmann
112 
113 #endif
114 
115 // #include <nlohmann/detail/macro_scope.hpp>
116 
117 
118 // This file contains all internal macro definitions
119 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
120 
121 // exclude unsupported compilers
122 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
123  #if defined(__clang__)
124  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
125  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
126  #endif
127  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
128  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
129  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
130  #endif
131  #endif
132 #endif
133 
134 // disable float-equal warnings on GCC/clang
135 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
136  #pragma GCC diagnostic push
137  #pragma GCC diagnostic ignored "-Wfloat-equal"
138 #endif
139 
140 // disable documentation warnings on clang
141 #if defined(__clang__)
142  #pragma GCC diagnostic push
143  #pragma GCC diagnostic ignored "-Wdocumentation"
144 #endif
145 
146 // allow for portable deprecation warnings
147 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
148  #define JSON_DEPRECATED __attribute__((deprecated))
149 #elif defined(_MSC_VER)
150  #define JSON_DEPRECATED __declspec(deprecated)
151 #else
152  #define JSON_DEPRECATED
153 #endif
154 
155 // allow to disable exceptions
156 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
157  #define JSON_THROW(exception) throw exception
158  #define JSON_TRY try
159  #define JSON_CATCH(exception) catch(exception)
160  #define JSON_INTERNAL_CATCH(exception) catch(exception)
161 #else
162  #define JSON_THROW(exception) std::abort()
163  #define JSON_TRY if(true)
164  #define JSON_CATCH(exception) if(false)
165  #define JSON_INTERNAL_CATCH(exception) if(false)
166 #endif
167 
168 // override exception macros
169 #if defined(JSON_THROW_USER)
170  #undef JSON_THROW
171  #define JSON_THROW JSON_THROW_USER
172 #endif
173 #if defined(JSON_TRY_USER)
174  #undef JSON_TRY
175  #define JSON_TRY JSON_TRY_USER
176 #endif
177 #if defined(JSON_CATCH_USER)
178  #undef JSON_CATCH
179  #define JSON_CATCH JSON_CATCH_USER
180  #undef JSON_INTERNAL_CATCH
181  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
182 #endif
183 #if defined(JSON_INTERNAL_CATCH_USER)
184  #undef JSON_INTERNAL_CATCH
185  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
186 #endif
187 
188 // manual branch prediction
189 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
190  #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
191  #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
192 #else
193  #define JSON_LIKELY(x) x
194  #define JSON_UNLIKELY(x) x
195 #endif
196 
197 // C++ language standard detection
198 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
199  #define JSON_HAS_CPP_17
200  #define JSON_HAS_CPP_14
201 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
202  #define JSON_HAS_CPP_14
203 #endif
204 
210 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
211  template<typename BasicJsonType> \
212  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
213  { \
214  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
215  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
216  auto it = std::find_if(std::begin(m), std::end(m), \
217  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
218  { \
219  return ej_pair.first == e; \
220  }); \
221  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
222  } \
223  template<typename BasicJsonType> \
224  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
225  { \
226  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
227  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
228  auto it = std::find_if(std::begin(m), std::end(m), \
229  [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
230  { \
231  return ej_pair.second == j; \
232  }); \
233  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
234  }
235 
236 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
237 // may be removed in the future once the class is split.
238 
239 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
240  template<template<typename, typename, typename...> class ObjectType, \
241  template<typename, typename...> class ArrayType, \
242  class StringType, class BooleanType, class NumberIntegerType, \
243  class NumberUnsignedType, class NumberFloatType, \
244  template<typename> class AllocatorType, \
245  template<typename, typename = void> class JSONSerializer>
246 
247 #define NLOHMANN_BASIC_JSON_TPL \
248  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
249  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
250  AllocatorType, JSONSerializer>
251 
252 // #include <nlohmann/detail/meta/cpp_future.hpp>
253 
254 
255 #include <ciso646> // not
256 #include <cstddef> // size_t
257 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
258 
259 namespace nlohmann
260 {
261 namespace detail
262 {
263 // alias templates to reduce boilerplate
264 template<bool B, typename T = void>
265 using enable_if_t = typename std::enable_if<B, T>::type;
266 
267 template<typename T>
268 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
269 
270 // implementation of C++14 index_sequence and affiliates
271 // source: https://stackoverflow.com/a/32223343
272 template<std::size_t... Ints>
274 {
276  using value_type = std::size_t;
277  static constexpr std::size_t size() noexcept
278  {
279  return sizeof...(Ints);
280  }
281 };
282 
283 template<class Sequence1, class Sequence2>
285 
286 template<std::size_t... I1, std::size_t... I2>
288  : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
289 
290 template<std::size_t N>
292  : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
293  typename make_index_sequence < N - N / 2 >::type > {};
294 
295 template<> struct make_index_sequence<0> : index_sequence<> {};
296 template<> struct make_index_sequence<1> : index_sequence<0> {};
297 
298 template<typename... Ts>
300 
301 // dispatch utility (taken from ranges-v3)
302 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
303 template<> struct priority_tag<0> {};
304 
305 // taken from ranges-v3
306 template<typename T>
308 {
309  static constexpr T value{};
310 };
311 
312 template<typename T>
313 constexpr T static_const<T>::value;
314 } // namespace detail
315 } // namespace nlohmann
316 
317 // #include <nlohmann/detail/meta/type_traits.hpp>
318 
319 
320 #include <ciso646> // not
321 #include <limits> // numeric_limits
322 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
323 #include <utility> // declval
324 
325 // #include <nlohmann/json_fwd.hpp>
326 
327 // #include <nlohmann/detail/meta/cpp_future.hpp>
328 
329 // #include <nlohmann/detail/meta/detected.hpp>
330 
331 
332 #include <type_traits>
333 
334 // #include <nlohmann/detail/meta/void_t.hpp>
335 
336 
337 namespace nlohmann
338 {
339 namespace detail
340 {
341 template <typename ...Ts> struct make_void
342 {
343  using type = void;
344 };
345 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
346 } // namespace detail
347 } // namespace nlohmann
348 
349 
350 // http://en.cppreference.com/w/cpp/experimental/is_detected
351 namespace nlohmann
352 {
353 namespace detail
354 {
355 struct nonesuch
356 {
357  nonesuch() = delete;
358  ~nonesuch() = delete;
359  nonesuch(nonesuch const&) = delete;
360  void operator=(nonesuch const&) = delete;
361 };
362 
363 template <class Default,
364  class AlwaysVoid,
365  template <class...> class Op,
366  class... Args>
367 struct detector
368 {
369  using value_t = std::false_type;
370  using type = Default;
371 };
372 
373 template <class Default, template <class...> class Op, class... Args>
374 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
375 {
376  using value_t = std::true_type;
377  using type = Op<Args...>;
378 };
379 
380 template <template <class...> class Op, class... Args>
381 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
382 
383 template <template <class...> class Op, class... Args>
384 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
385 
386 template <class Default, template <class...> class Op, class... Args>
387 using detected_or = detector<Default, void, Op, Args...>;
388 
389 template <class Default, template <class...> class Op, class... Args>
390 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
391 
392 template <class Expected, template <class...> class Op, class... Args>
393 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
394 
395 template <class To, template <class...> class Op, class... Args>
397  std::is_convertible<detected_t<Op, Args...>, To>;
398 } // namespace detail
399 } // namespace nlohmann
400 
401 // #include <nlohmann/detail/macro_scope.hpp>
402 
403 
404 namespace nlohmann
405 {
414 namespace detail
415 {
417 // helpers //
419 
420 // Note to maintainers:
421 //
422 // Every trait in this file expects a non CV-qualified type.
423 // The only exceptions are in the 'aliases for detected' section
424 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
425 //
426 // In this case, T has to be properly CV-qualified to constraint the function arguments
427 // (e.g. to_json(BasicJsonType&, const T&))
428 
429 template<typename> struct is_basic_json : std::false_type {};
430 
432 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
433 
435 // aliases for detected //
437 
438 template <typename T>
439 using mapped_type_t = typename T::mapped_type;
440 
441 template <typename T>
442 using key_type_t = typename T::key_type;
443 
444 template <typename T>
445 using value_type_t = typename T::value_type;
446 
447 template <typename T>
448 using difference_type_t = typename T::difference_type;
449 
450 template <typename T>
451 using pointer_t = typename T::pointer;
452 
453 template <typename T>
454 using reference_t = typename T::reference;
455 
456 template <typename T>
457 using iterator_category_t = typename T::iterator_category;
458 
459 template <typename T>
460 using iterator_t = typename T::iterator;
461 
462 template <typename T, typename... Args>
463 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
464 
465 template <typename T, typename... Args>
466 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
467 
468 template <typename T, typename U>
469 using get_template_function = decltype(std::declval<T>().template get<U>());
470 
471 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
472 template <typename BasicJsonType, typename T, typename = void>
473 struct has_from_json : std::false_type {};
474 
475 template <typename BasicJsonType, typename T>
476 struct has_from_json<BasicJsonType, T,
478 {
479  using serializer = typename BasicJsonType::template json_serializer<T, void>;
480 
481  static constexpr bool value =
483  const BasicJsonType&, T&>::value;
484 };
485 
486 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
487 // this overload is used for non-default-constructible user-defined-types
488 template <typename BasicJsonType, typename T, typename = void>
489 struct has_non_default_from_json : std::false_type {};
490 
491 template<typename BasicJsonType, typename T>
493 {
494  using serializer = typename BasicJsonType::template json_serializer<T, void>;
495 
496  static constexpr bool value =
498  const BasicJsonType&>::value;
499 };
500 
501 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
502 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
503 template <typename BasicJsonType, typename T, typename = void>
504 struct has_to_json : std::false_type {};
505 
506 template <typename BasicJsonType, typename T>
507 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
508 {
509  using serializer = typename BasicJsonType::template json_serializer<T, void>;
510 
511  static constexpr bool value =
513  T>::value;
514 };
515 
516 
518 // is_ functions //
520 
521 template <typename T, typename = void>
522 struct is_iterator_traits : std::false_type {};
523 
524 template <typename T>
525 struct is_iterator_traits<std::iterator_traits<T>>
526 {
527  private:
528  using traits = std::iterator_traits<T>;
529 
530  public:
531  static constexpr auto value =
537 };
538 
539 // source: https://stackoverflow.com/a/37193089/4116453
540 
541 template <typename T, typename = void>
542 struct is_complete_type : std::false_type {};
543 
544 template <typename T>
545 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
546 
547 template <typename BasicJsonType, typename CompatibleObjectType,
548  typename = void>
549 struct is_compatible_object_type_impl : std::false_type {};
550 
551 template <typename BasicJsonType, typename CompatibleObjectType>
553  BasicJsonType, CompatibleObjectType,
554  enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
555  is_detected<key_type_t, CompatibleObjectType>::value >>
556 {
557 
558  using object_t = typename BasicJsonType::object_t;
559 
560  // macOS's is_constructible does not play well with nonesuch...
561  static constexpr bool value =
562  std::is_constructible<typename object_t::key_type,
563  typename CompatibleObjectType::key_type>::value and
564  std::is_constructible<typename object_t::mapped_type,
565  typename CompatibleObjectType::mapped_type>::value;
566 };
567 
568 template <typename BasicJsonType, typename CompatibleObjectType>
570  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
571 
572 template <typename BasicJsonType, typename ConstructibleObjectType,
573  typename = void>
574 struct is_constructible_object_type_impl : std::false_type {};
575 
576 template <typename BasicJsonType, typename ConstructibleObjectType>
578  BasicJsonType, ConstructibleObjectType,
579  enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
580  is_detected<key_type_t, ConstructibleObjectType>::value >>
581 {
582  using object_t = typename BasicJsonType::object_t;
583 
584  static constexpr bool value =
589 };
590 
591 template <typename BasicJsonType, typename ConstructibleObjectType>
593  : is_constructible_object_type_impl<BasicJsonType,
594  ConstructibleObjectType> {};
595 
596 template <typename BasicJsonType, typename CompatibleStringType,
597  typename = void>
598 struct is_compatible_string_type_impl : std::false_type {};
599 
600 template <typename BasicJsonType, typename CompatibleStringType>
602  BasicJsonType, CompatibleStringType,
603  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
604  value_type_t, CompatibleStringType>::value >>
605 {
606  static constexpr auto value =
608 };
609 
610 template <typename BasicJsonType, typename ConstructibleStringType>
612  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
613 
614 template <typename BasicJsonType, typename ConstructibleStringType,
615  typename = void>
616 struct is_constructible_string_type_impl : std::false_type {};
617 
618 template <typename BasicJsonType, typename ConstructibleStringType>
620  BasicJsonType, ConstructibleStringType,
621  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
622  value_type_t, ConstructibleStringType>::value >>
623 {
624  static constexpr auto value =
625  std::is_constructible<ConstructibleStringType,
626  typename BasicJsonType::string_t>::value;
627 };
628 
629 template <typename BasicJsonType, typename ConstructibleStringType>
631  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
632 
633 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
634 struct is_compatible_array_type_impl : std::false_type {};
635 
636 template <typename BasicJsonType, typename CompatibleArrayType>
638  BasicJsonType, CompatibleArrayType,
639  enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
640  is_detected<iterator_t, CompatibleArrayType>::value and
641 // This is needed because json_reverse_iterator has a ::iterator type...
642 // Therefore it is detected as a CompatibleArrayType.
643 // The real fix would be to have an Iterable concept.
644  not is_iterator_traits<
645  std::iterator_traits<CompatibleArrayType>>::value >>
646 {
647  static constexpr bool value =
648  std::is_constructible<BasicJsonType,
649  typename CompatibleArrayType::value_type>::value;
650 };
651 
652 template <typename BasicJsonType, typename CompatibleArrayType>
654  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
655 
656 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
657 struct is_constructible_array_type_impl : std::false_type {};
658 
659 template <typename BasicJsonType, typename ConstructibleArrayType>
661  BasicJsonType, ConstructibleArrayType,
662  enable_if_t<std::is_same<ConstructibleArrayType,
663  typename BasicJsonType::value_type>::value >>
664  : std::true_type {};
665 
666 template <typename BasicJsonType, typename ConstructibleArrayType>
668  BasicJsonType, ConstructibleArrayType,
669  enable_if_t<not std::is_same<ConstructibleArrayType,
670  typename BasicJsonType::value_type>::value and
671  is_detected<value_type_t, ConstructibleArrayType>::value and
672  is_detected<iterator_t, ConstructibleArrayType>::value and
674  detected_t<value_type_t, ConstructibleArrayType>>::value >>
675 {
676  static constexpr bool value =
677  // This is needed because json_reverse_iterator has a ::iterator type,
678  // furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
679  // Therefore it is detected as a ConstructibleArrayType.
680  // The real fix would be to have an Iterable concept.
681  not is_iterator_traits <
682  std::iterator_traits<ConstructibleArrayType >>::value and
683 
685  has_from_json<BasicJsonType,
686  typename ConstructibleArrayType::value_type>::value or
688  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
689 };
690 
691 template <typename BasicJsonType, typename ConstructibleArrayType>
693  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
694 
695 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
696  typename = void>
697 struct is_compatible_integer_type_impl : std::false_type {};
698 
699 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
701  RealIntegerType, CompatibleNumberIntegerType,
702  enable_if_t<std::is_integral<RealIntegerType>::value and
703  std::is_integral<CompatibleNumberIntegerType>::value and
704  not std::is_same<bool, CompatibleNumberIntegerType>::value >>
705 {
706  // is there an assert somewhere on overflows?
707  using RealLimits = std::numeric_limits<RealIntegerType>;
708  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
709 
710  static constexpr auto value =
711  std::is_constructible<RealIntegerType,
712  CompatibleNumberIntegerType>::value and
713  CompatibleLimits::is_integer and
714  RealLimits::is_signed == CompatibleLimits::is_signed;
715 };
716 
717 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
719  : is_compatible_integer_type_impl<RealIntegerType,
720  CompatibleNumberIntegerType> {};
721 
722 template <typename BasicJsonType, typename CompatibleType, typename = void>
723 struct is_compatible_type_impl: std::false_type {};
724 
725 template <typename BasicJsonType, typename CompatibleType>
727  BasicJsonType, CompatibleType,
728  enable_if_t<is_complete_type<CompatibleType>::value >>
729 {
730  static constexpr bool value =
732 };
733 
734 template <typename BasicJsonType, typename CompatibleType>
736  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
737 } // namespace detail
738 } // namespace nlohmann
739 
740 // #include <nlohmann/detail/exceptions.hpp>
741 
742 
743 #include <exception> // exception
744 #include <stdexcept> // runtime_error
745 #include <string> // to_string
746 
747 // #include <nlohmann/detail/input/position_t.hpp>
748 
749 
750 #include <cstddef> // size_t
751 
752 namespace nlohmann
753 {
754 namespace detail
755 {
758 {
760  std::size_t chars_read_total = 0;
762  std::size_t chars_read_current_line = 0;
764  std::size_t lines_read = 0;
765 
767  constexpr operator size_t() const
768  {
769  return chars_read_total;
770  }
771 };
772 
773 }
774 }
775 
776 
777 namespace nlohmann
778 {
779 namespace detail
780 {
782 // exceptions //
784 
813 class exception : public std::exception
814 {
815  public:
817  const char* what() const noexcept override
818  {
819  return m.what();
820  }
821 
823  const int id;
824 
825  protected:
826  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
827 
828  static std::string name(const std::string& ename, int id_)
829  {
830  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
831  }
832 
833  private:
835  std::runtime_error m;
836 };
837 
882 class parse_error : public exception
883 {
884  public:
894  static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
895  {
896  std::string w = exception::name("parse_error", id_) + "parse error" +
897  position_string(pos) + ": " + what_arg;
898  return parse_error(id_, pos.chars_read_total, w.c_str());
899  }
900 
901  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
902  {
903  std::string w = exception::name("parse_error", id_) + "parse error" +
904  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
905  ": " + what_arg;
906  return parse_error(id_, byte_, w.c_str());
907  }
908 
918  const std::size_t byte;
919 
920  private:
921  parse_error(int id_, std::size_t byte_, const char* what_arg)
922  : exception(id_, what_arg), byte(byte_) {}
923 
925  {
926  return " at line " + std::to_string(pos.lines_read + 1) +
927  ", column " + std::to_string(pos.chars_read_current_line);
928  }
929 };
930 
969 {
970  public:
971  static invalid_iterator create(int id_, const std::string& what_arg)
972  {
973  std::string w = exception::name("invalid_iterator", id_) + what_arg;
974  return invalid_iterator(id_, w.c_str());
975  }
976 
977  private:
978  invalid_iterator(int id_, const char* what_arg)
979  : exception(id_, what_arg) {}
980 };
981 
1021 class type_error : public exception
1022 {
1023  public:
1024  static type_error create(int id_, const std::string& what_arg)
1025  {
1026  std::string w = exception::name("type_error", id_) + what_arg;
1027  return type_error(id_, w.c_str());
1028  }
1029 
1030  private:
1031  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
1032 };
1033 
1067 class out_of_range : public exception
1068 {
1069  public:
1070  static out_of_range create(int id_, const std::string& what_arg)
1071  {
1072  std::string w = exception::name("out_of_range", id_) + what_arg;
1073  return out_of_range(id_, w.c_str());
1074  }
1075 
1076  private:
1077  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
1078 };
1079 
1104 class other_error : public exception
1105 {
1106  public:
1107  static other_error create(int id_, const std::string& what_arg)
1108  {
1109  std::string w = exception::name("other_error", id_) + what_arg;
1110  return other_error(id_, w.c_str());
1111  }
1112 
1113  private:
1114  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
1115 };
1116 } // namespace detail
1117 } // namespace nlohmann
1118 
1119 // #include <nlohmann/detail/value_t.hpp>
1120 
1121 
1122 #include <array> // array
1123 #include <ciso646> // and
1124 #include <cstddef> // size_t
1125 #include <cstdint> // uint8_t
1126 
1127 namespace nlohmann
1128 {
1129 namespace detail
1130 {
1132 // JSON type enumeration //
1134 
1159 enum class value_t : std::uint8_t
1160 {
1161  null,
1162  object,
1163  array,
1164  string,
1165  boolean,
1166  number_integer,
1167  number_unsigned,
1168  number_float,
1169  discarded
1170 };
1171 
1182 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1183 {
1184  static constexpr std::array<std::uint8_t, 8> order = {{
1185  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1186  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1187  }
1188  };
1189 
1190  const auto l_index = static_cast<std::size_t>(lhs);
1191  const auto r_index = static_cast<std::size_t>(rhs);
1192  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1193 }
1194 } // namespace detail
1195 } // namespace nlohmann
1196 
1197 // #include <nlohmann/detail/conversions/from_json.hpp>
1198 
1199 
1200 #include <algorithm> // transform
1201 #include <array> // array
1202 #include <ciso646> // and, not
1203 #include <forward_list> // forward_list
1204 #include <iterator> // inserter, front_inserter, end
1205 #include <map> // map
1206 #include <string> // string
1207 #include <tuple> // tuple, make_tuple
1208 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
1209 #include <unordered_map> // unordered_map
1210 #include <utility> // pair, declval
1211 #include <valarray> // valarray
1212 
1213 // #include <nlohmann/detail/exceptions.hpp>
1214 
1215 // #include <nlohmann/detail/macro_scope.hpp>
1216 
1217 // #include <nlohmann/detail/meta/cpp_future.hpp>
1218 
1219 // #include <nlohmann/detail/meta/type_traits.hpp>
1220 
1221 // #include <nlohmann/detail/value_t.hpp>
1222 
1223 
1224 namespace nlohmann
1225 {
1226 namespace detail
1227 {
1228 template<typename BasicJsonType>
1229 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1230 {
1231  if (JSON_UNLIKELY(not j.is_null()))
1232  {
1233  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1234  }
1235  n = nullptr;
1236 }
1237 
1238 // overloads for basic_json template parameters
1239 template<typename BasicJsonType, typename ArithmeticType,
1242  int> = 0>
1243 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1244 {
1245  switch (static_cast<value_t>(j))
1246  {
1248  {
1249  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1250  break;
1251  }
1253  {
1254  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1255  break;
1256  }
1257  case value_t::number_float:
1258  {
1259  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1260  break;
1261  }
1262 
1263  default:
1264  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1265  }
1266 }
1267 
1268 template<typename BasicJsonType>
1269 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1270 {
1271  if (JSON_UNLIKELY(not j.is_boolean()))
1272  {
1273  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1274  }
1275  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1276 }
1277 
1278 template<typename BasicJsonType>
1279 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1280 {
1281  if (JSON_UNLIKELY(not j.is_string()))
1282  {
1283  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1284  }
1285  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1286 }
1287 
1288 template <
1289  typename BasicJsonType, typename ConstructibleStringType,
1290  enable_if_t <
1292  not std::is_same<typename BasicJsonType::string_t,
1293  ConstructibleStringType>::value,
1294  int > = 0 >
1295 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
1296 {
1297  if (JSON_UNLIKELY(not j.is_string()))
1298  {
1299  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1300  }
1301 
1302  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1303 }
1304 
1305 template<typename BasicJsonType>
1306 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1307 {
1308  get_arithmetic_value(j, val);
1309 }
1310 
1311 template<typename BasicJsonType>
1312 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1313 {
1314  get_arithmetic_value(j, val);
1315 }
1316 
1317 template<typename BasicJsonType>
1318 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1319 {
1320  get_arithmetic_value(j, val);
1321 }
1322 
1323 template<typename BasicJsonType, typename EnumType,
1325 void from_json(const BasicJsonType& j, EnumType& e)
1326 {
1327  typename std::underlying_type<EnumType>::type val;
1328  get_arithmetic_value(j, val);
1329  e = static_cast<EnumType>(val);
1330 }
1331 
1332 // forward_list doesn't have an insert method
1333 template<typename BasicJsonType, typename T, typename Allocator,
1335 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1336 {
1337  if (JSON_UNLIKELY(not j.is_array()))
1338  {
1339  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1340  }
1341  std::transform(j.rbegin(), j.rend(),
1342  std::front_inserter(l), [](const BasicJsonType & i)
1343  {
1344  return i.template get<T>();
1345  });
1346 }
1347 
1348 // valarray doesn't have an insert method
1349 template<typename BasicJsonType, typename T,
1350  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
1351 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1352 {
1353  if (JSON_UNLIKELY(not j.is_array()))
1354  {
1355  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1356  }
1357  l.resize(j.size());
1358  std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1359 }
1360 
1361 template<typename BasicJsonType>
1362 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1363 {
1364  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1365 }
1366 
1367 template <typename BasicJsonType, typename T, std::size_t N>
1368 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1369  priority_tag<2> /*unused*/)
1370 -> decltype(j.template get<T>(), void())
1371 {
1372  for (std::size_t i = 0; i < N; ++i)
1373  {
1374  arr[i] = j.at(i).template get<T>();
1375  }
1376 }
1377 
1378 template<typename BasicJsonType, typename ConstructibleArrayType>
1379 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
1380 -> decltype(
1381  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1382  j.template get<typename ConstructibleArrayType::value_type>(),
1383  void())
1384 {
1385  using std::end;
1386 
1387  arr.reserve(j.size());
1388  std::transform(j.begin(), j.end(),
1389  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1390  {
1391  // get<BasicJsonType>() returns *this, this won't call a from_json
1392  // method when value_type is BasicJsonType
1393  return i.template get<typename ConstructibleArrayType::value_type>();
1394  });
1395 }
1396 
1397 template <typename BasicJsonType, typename ConstructibleArrayType>
1398 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
1399  priority_tag<0> /*unused*/)
1400 {
1401  using std::end;
1402 
1403  std::transform(
1404  j.begin(), j.end(), std::inserter(arr, end(arr)),
1405  [](const BasicJsonType & i)
1406  {
1407  // get<BasicJsonType>() returns *this, this won't call a from_json
1408  // method when value_type is BasicJsonType
1409  return i.template get<typename ConstructibleArrayType::value_type>();
1410  });
1411 }
1412 
1413 template <typename BasicJsonType, typename ConstructibleArrayType,
1414  enable_if_t <
1419  int > = 0 >
1420 
1421 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
1422 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1423 j.template get<typename ConstructibleArrayType::value_type>(),
1424 void())
1425 {
1426  if (JSON_UNLIKELY(not j.is_array()))
1427  {
1428  JSON_THROW(type_error::create(302, "type must be array, but is " +
1429  std::string(j.type_name())));
1430  }
1431 
1433 }
1434 
1435 template<typename BasicJsonType, typename ConstructibleObjectType,
1437 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
1438 {
1439  if (JSON_UNLIKELY(not j.is_object()))
1440  {
1441  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1442  }
1443 
1444  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1445  using value_type = typename ConstructibleObjectType::value_type;
1446  std::transform(
1447  inner_object->begin(), inner_object->end(),
1448  std::inserter(obj, obj.begin()),
1449  [](typename BasicJsonType::object_t::value_type const & p)
1450  {
1451  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1452  });
1453 }
1454 
1455 // overload for arithmetic types, not chosen for basic_json template arguments
1456 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1457 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1458 // an arithmetic type?
1459 template<typename BasicJsonType, typename ArithmeticType,
1460  enable_if_t <
1465  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1466  int> = 0>
1467 void from_json(const BasicJsonType& j, ArithmeticType& val)
1468 {
1469  switch (static_cast<value_t>(j))
1470  {
1472  {
1473  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1474  break;
1475  }
1477  {
1478  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1479  break;
1480  }
1481  case value_t::number_float:
1482  {
1483  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1484  break;
1485  }
1486  case value_t::boolean:
1487  {
1488  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1489  break;
1490  }
1491 
1492  default:
1493  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1494  }
1495 }
1496 
1497 template<typename BasicJsonType, typename A1, typename A2>
1498 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1499 {
1500  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1501 }
1502 
1503 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1504 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
1505 {
1506  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1507 }
1508 
1509 template<typename BasicJsonType, typename... Args>
1510 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1511 {
1513 }
1514 
1515 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1516  typename = enable_if_t<not std::is_constructible<
1517  typename BasicJsonType::string_t, Key>::value>>
1518 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1519 {
1520  if (JSON_UNLIKELY(not j.is_array()))
1521  {
1522  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1523  }
1524  for (const auto& p : j)
1525  {
1526  if (JSON_UNLIKELY(not p.is_array()))
1527  {
1528  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1529  }
1530  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1531  }
1532 }
1533 
1534 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1535  typename = enable_if_t<not std::is_constructible<
1536  typename BasicJsonType::string_t, Key>::value>>
1537 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1538 {
1539  if (JSON_UNLIKELY(not j.is_array()))
1540  {
1541  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1542  }
1543  for (const auto& p : j)
1544  {
1545  if (JSON_UNLIKELY(not p.is_array()))
1546  {
1547  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1548  }
1549  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1550  }
1551 }
1552 
1554 {
1555  template<typename BasicJsonType, typename T>
1556  auto operator()(const BasicJsonType& j, T& val) const
1557  noexcept(noexcept(from_json(j, val)))
1558  -> decltype(from_json(j, val), void())
1559  {
1560  return from_json(j, val);
1561  }
1562 };
1563 } // namespace detail
1564 
1568 namespace
1569 {
1571 } // namespace
1572 } // namespace nlohmann
1573 
1574 // #include <nlohmann/detail/conversions/to_json.hpp>
1575 
1576 
1577 #include <ciso646> // or, and, not
1578 #include <iterator> // begin, end
1579 #include <tuple> // tuple, get
1580 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1581 #include <utility> // move, forward, declval, pair
1582 #include <valarray> // valarray
1583 #include <vector> // vector
1584 
1585 // #include <nlohmann/detail/meta/cpp_future.hpp>
1586 
1587 // #include <nlohmann/detail/meta/type_traits.hpp>
1588 
1589 // #include <nlohmann/detail/value_t.hpp>
1590 
1591 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1592 
1593 
1594 #include <cstddef> // size_t
1595 #include <string> // string, to_string
1596 #include <iterator> // input_iterator_tag
1597 
1598 // #include <nlohmann/detail/value_t.hpp>
1599 
1600 
1601 namespace nlohmann
1602 {
1603 namespace detail
1604 {
1606 template<typename IteratorType> class iteration_proxy
1607 {
1608  private:
1611  {
1612  public:
1613  using difference_type = std::ptrdiff_t;
1617  using iterator_category = std::input_iterator_tag;
1618 
1619  private:
1621  IteratorType anchor;
1623  std::size_t array_index = 0;
1625  mutable std::size_t array_index_last = 0;
1627  mutable std::string array_index_str = "0";
1629  const std::string empty_str = "";
1630 
1631  public:
1632  explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
1633 
1636  {
1637  return *this;
1638  }
1639 
1642  {
1643  ++anchor;
1644  ++array_index;
1645 
1646  return *this;
1647  }
1648 
1650  bool operator==(const iteration_proxy_internal& o) const noexcept
1651  {
1652  return anchor == o.anchor;
1653  }
1654 
1656  bool operator!=(const iteration_proxy_internal& o) const noexcept
1657  {
1658  return anchor != o.anchor;
1659  }
1660 
1662  const std::string& key() const
1663  {
1664  assert(anchor.m_object != nullptr);
1665 
1666  switch (anchor.m_object->type())
1667  {
1668  // use integer array index as key
1669  case value_t::array:
1670  {
1671  if (array_index != array_index_last)
1672  {
1673  array_index_str = std::to_string(array_index);
1674  array_index_last = array_index;
1675  }
1676  return array_index_str;
1677  }
1678 
1679  // use key from the object
1680  case value_t::object:
1681  return anchor.key();
1682 
1683  // use an empty key for all primitive types
1684  default:
1685  return empty_str;
1686  }
1687  }
1688 
1690  typename IteratorType::reference value() const
1691  {
1692  return anchor.value();
1693  }
1694  };
1695 
1697  typename IteratorType::reference container;
1698 
1699  public:
1701  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1702  : container(cont) {}
1703 
1706  {
1707  return iteration_proxy_internal(container.begin());
1708  }
1709 
1712  {
1713  return iteration_proxy_internal(container.end());
1714  }
1715 };
1716 } // namespace detail
1717 } // namespace nlohmann
1718 
1719 
1720 namespace nlohmann
1721 {
1722 namespace detail
1723 {
1725 // constructors //
1727 
1728 template<value_t> struct external_constructor;
1729 
1730 template<>
1732 {
1733  template<typename BasicJsonType>
1734  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1735  {
1736  j.m_type = value_t::boolean;
1737  j.m_value = b;
1738  j.assert_invariant();
1739  }
1740 };
1741 
1742 template<>
1744 {
1745  template<typename BasicJsonType>
1746  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1747  {
1748  j.m_type = value_t::string;
1749  j.m_value = s;
1750  j.assert_invariant();
1751  }
1752 
1753  template<typename BasicJsonType>
1754  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1755  {
1756  j.m_type = value_t::string;
1757  j.m_value = std::move(s);
1758  j.assert_invariant();
1759  }
1760 
1761  template<typename BasicJsonType, typename CompatibleStringType,
1763  int> = 0>
1764  static void construct(BasicJsonType& j, const CompatibleStringType& str)
1765  {
1766  j.m_type = value_t::string;
1767  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1768  j.assert_invariant();
1769  }
1770 };
1771 
1772 template<>
1774 {
1775  template<typename BasicJsonType>
1776  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1777  {
1778  j.m_type = value_t::number_float;
1779  j.m_value = val;
1780  j.assert_invariant();
1781  }
1782 };
1783 
1784 template<>
1786 {
1787  template<typename BasicJsonType>
1788  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1789  {
1790  j.m_type = value_t::number_unsigned;
1791  j.m_value = val;
1792  j.assert_invariant();
1793  }
1794 };
1795 
1796 template<>
1798 {
1799  template<typename BasicJsonType>
1800  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1801  {
1802  j.m_type = value_t::number_integer;
1803  j.m_value = val;
1804  j.assert_invariant();
1805  }
1806 };
1807 
1808 template<>
1810 {
1811  template<typename BasicJsonType>
1812  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1813  {
1814  j.m_type = value_t::array;
1815  j.m_value = arr;
1816  j.assert_invariant();
1817  }
1818 
1819  template<typename BasicJsonType>
1820  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1821  {
1822  j.m_type = value_t::array;
1823  j.m_value = std::move(arr);
1824  j.assert_invariant();
1825  }
1826 
1827  template<typename BasicJsonType, typename CompatibleArrayType,
1829  int> = 0>
1830  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1831  {
1832  using std::begin;
1833  using std::end;
1834  j.m_type = value_t::array;
1835  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1836  j.assert_invariant();
1837  }
1838 
1839  template<typename BasicJsonType>
1840  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1841  {
1842  j.m_type = value_t::array;
1843  j.m_value = value_t::array;
1844  j.m_value.array->reserve(arr.size());
1845  for (const bool x : arr)
1846  {
1847  j.m_value.array->push_back(x);
1848  }
1849  j.assert_invariant();
1850  }
1851 
1852  template<typename BasicJsonType, typename T,
1854  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1855  {
1856  j.m_type = value_t::array;
1857  j.m_value = value_t::array;
1858  j.m_value.array->resize(arr.size());
1859  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1860  j.assert_invariant();
1861  }
1862 };
1863 
1864 template<>
1866 {
1867  template<typename BasicJsonType>
1868  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1869  {
1870  j.m_type = value_t::object;
1871  j.m_value = obj;
1872  j.assert_invariant();
1873  }
1874 
1875  template<typename BasicJsonType>
1876  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1877  {
1878  j.m_type = value_t::object;
1879  j.m_value = std::move(obj);
1880  j.assert_invariant();
1881  }
1882 
1883  template<typename BasicJsonType, typename CompatibleObjectType,
1885  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1886  {
1887  using std::begin;
1888  using std::end;
1889 
1890  j.m_type = value_t::object;
1891  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
1892  j.assert_invariant();
1893  }
1894 };
1895 
1897 // to_json //
1899 
1900 template<typename BasicJsonType, typename T,
1902 void to_json(BasicJsonType& j, T b) noexcept
1903 {
1905 }
1906 
1907 template<typename BasicJsonType, typename CompatibleString,
1909 void to_json(BasicJsonType& j, const CompatibleString& s)
1910 {
1912 }
1913 
1914 template<typename BasicJsonType>
1915 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1916 {
1918 }
1919 
1920 template<typename BasicJsonType, typename FloatType,
1922 void to_json(BasicJsonType& j, FloatType val) noexcept
1923 {
1924  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
1925 }
1926 
1927 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1929 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1930 {
1931  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
1932 }
1933 
1934 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1936 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1937 {
1938  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1939 }
1940 
1941 template<typename BasicJsonType, typename EnumType,
1942  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
1943 void to_json(BasicJsonType& j, EnumType e) noexcept
1944 {
1945  using underlying_type = typename std::underlying_type<EnumType>::type;
1946  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1947 }
1948 
1949 template<typename BasicJsonType>
1950 void to_json(BasicJsonType& j, const std::vector<bool>& e)
1951 {
1953 }
1954 
1955 template <typename BasicJsonType, typename CompatibleArrayType,
1956  enable_if_t<is_compatible_array_type<BasicJsonType,
1957  CompatibleArrayType>::value and
1959  BasicJsonType, CompatibleArrayType>::value and
1962  int> = 0>
1963 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1964 {
1966 }
1967 
1968 template<typename BasicJsonType, typename T,
1970 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
1971 {
1973 }
1974 
1975 template<typename BasicJsonType>
1976 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1977 {
1979 }
1980 
1981 template<typename BasicJsonType, typename CompatibleObjectType,
1983 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1984 {
1986 }
1987 
1988 template<typename BasicJsonType>
1989 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1990 {
1992 }
1993 
1994 template <
1995  typename BasicJsonType, typename T, std::size_t N,
1996  enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
1997  const T (&)[N]>::value,
1998  int> = 0 >
1999 void to_json(BasicJsonType& j, const T (&arr)[N])
2000 {
2002 }
2003 
2004 template<typename BasicJsonType, typename... Args>
2005 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
2006 {
2007  j = {p.first, p.second};
2008 }
2009 
2010 // for https://github.com/nlohmann/json/pull/1134
2011 template<typename BasicJsonType, typename T,
2013 void to_json(BasicJsonType& j, const T& b)
2014 {
2015  j = {{b.key(), b.value()}};
2016 }
2017 
2018 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
2019 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
2020 {
2021  j = {std::get<Idx>(t)...};
2022 }
2023 
2024 template<typename BasicJsonType, typename... Args>
2025 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
2026 {
2028 }
2029 
2031 {
2032  template<typename BasicJsonType, typename T>
2033  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
2034  -> decltype(to_json(j, std::forward<T>(val)), void())
2035  {
2036  return to_json(j, std::forward<T>(val));
2037  }
2038 };
2039 } // namespace detail
2040 
2042 namespace
2043 {
2045 } // namespace
2046 } // namespace nlohmann
2047 
2048 // #include <nlohmann/detail/input/input_adapters.hpp>
2049 
2050 
2051 #include <cassert> // assert
2052 #include <cstddef> // size_t
2053 #include <cstring> // strlen
2054 #include <istream> // istream
2055 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
2056 #include <memory> // shared_ptr, make_shared, addressof
2057 #include <numeric> // accumulate
2058 #include <string> // string, char_traits
2059 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
2060 #include <utility> // pair, declval
2061 
2062 // #include <nlohmann/detail/macro_scope.hpp>
2063 
2064 
2065 namespace nlohmann
2066 {
2067 namespace detail
2068 {
2071 
2073 // input adapters //
2075 
2088 {
2090  virtual std::char_traits<char>::int_type get_character() = 0;
2091  virtual ~input_adapter_protocol() = default;
2092 };
2093 
2095 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2096 
2107 {
2108  public:
2110  {
2111  // clear stream flags; we use underlying streambuf I/O, do not
2112  // maintain ifstream flags
2113  is.clear();
2114  }
2115 
2116  explicit input_stream_adapter(std::istream& i)
2117  : is(i), sb(*i.rdbuf())
2118  {}
2119 
2120  // delete because of pointer members
2121  input_stream_adapter(const input_stream_adapter&) = delete;
2122  input_stream_adapter& operator=(input_stream_adapter&) = delete;
2124  input_stream_adapter& operator=(input_stream_adapter&&) = delete;
2125 
2126  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
2127  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
2128  // end up as the same value, eg. 0xFFFFFFFF.
2129  std::char_traits<char>::int_type get_character() override
2130  {
2131  return sb.sbumpc();
2132  }
2133 
2134  private:
2136  std::istream& is;
2137  std::streambuf& sb;
2138 };
2139 
2142 {
2143  public:
2144  input_buffer_adapter(const char* b, const std::size_t l) noexcept
2145  : cursor(b), limit(b + l)
2146  {}
2147 
2148  // delete because of pointer members
2149  input_buffer_adapter(const input_buffer_adapter&) = delete;
2150  input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
2152  input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
2153  ~input_buffer_adapter() override = default;
2154 
2155  std::char_traits<char>::int_type get_character() noexcept override
2156  {
2157  if (JSON_LIKELY(cursor < limit))
2158  {
2159  return std::char_traits<char>::to_int_type(*(cursor++));
2160  }
2161 
2162  return std::char_traits<char>::eof();
2163  }
2164 
2165  private:
2167  const char* cursor;
2169  const char* const limit;
2170 };
2171 
2172 template<typename WideStringType, size_t T>
2174 {
2175  // UTF-32
2176  static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
2177  {
2178  utf8_bytes_index = 0;
2179 
2180  if (current_wchar == str.size())
2181  {
2182  utf8_bytes[0] = std::char_traits<char>::eof();
2183  utf8_bytes_filled = 1;
2184  }
2185  else
2186  {
2187  // get the current character
2188  const auto wc = static_cast<int>(str[current_wchar++]);
2189 
2190  // UTF-32 to UTF-8 encoding
2191  if (wc < 0x80)
2192  {
2193  utf8_bytes[0] = wc;
2194  utf8_bytes_filled = 1;
2195  }
2196  else if (wc <= 0x7FF)
2197  {
2198  utf8_bytes[0] = 0xC0 | ((wc >> 6) & 0x1F);
2199  utf8_bytes[1] = 0x80 | (wc & 0x3F);
2200  utf8_bytes_filled = 2;
2201  }
2202  else if (wc <= 0xFFFF)
2203  {
2204  utf8_bytes[0] = 0xE0 | ((wc >> 12) & 0x0F);
2205  utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2206  utf8_bytes[2] = 0x80 | (wc & 0x3F);
2207  utf8_bytes_filled = 3;
2208  }
2209  else if (wc <= 0x10FFFF)
2210  {
2211  utf8_bytes[0] = 0xF0 | ((wc >> 18) & 0x07);
2212  utf8_bytes[1] = 0x80 | ((wc >> 12) & 0x3F);
2213  utf8_bytes[2] = 0x80 | ((wc >> 6) & 0x3F);
2214  utf8_bytes[3] = 0x80 | (wc & 0x3F);
2215  utf8_bytes_filled = 4;
2216  }
2217  else
2218  {
2219  // unknown character
2220  utf8_bytes[0] = wc;
2221  utf8_bytes_filled = 1;
2222  }
2223  }
2224  }
2225 };
2226 
2227 template<typename WideStringType>
2228 struct wide_string_input_helper<WideStringType, 2>
2229 {
2230  // UTF-16
2231  static void fill_buffer(const WideStringType& str, size_t& current_wchar, std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, size_t& utf8_bytes_index, size_t& utf8_bytes_filled)
2232  {
2233  utf8_bytes_index = 0;
2234 
2235  if (current_wchar == str.size())
2236  {
2237  utf8_bytes[0] = std::char_traits<char>::eof();
2238  utf8_bytes_filled = 1;
2239  }
2240  else
2241  {
2242  // get the current character
2243  const auto wc = static_cast<int>(str[current_wchar++]);
2244 
2245  // UTF-16 to UTF-8 encoding
2246  if (wc < 0x80)
2247  {
2248  utf8_bytes[0] = wc;
2249  utf8_bytes_filled = 1;
2250  }
2251  else if (wc <= 0x7FF)
2252  {
2253  utf8_bytes[0] = 0xC0 | ((wc >> 6));
2254  utf8_bytes[1] = 0x80 | (wc & 0x3F);
2255  utf8_bytes_filled = 2;
2256  }
2257  else if (0xD800 > wc or wc >= 0xE000)
2258  {
2259  utf8_bytes[0] = 0xE0 | ((wc >> 12));
2260  utf8_bytes[1] = 0x80 | ((wc >> 6) & 0x3F);
2261  utf8_bytes[2] = 0x80 | (wc & 0x3F);
2262  utf8_bytes_filled = 3;
2263  }
2264  else
2265  {
2266  if (current_wchar < str.size())
2267  {
2268  const auto wc2 = static_cast<int>(str[current_wchar++]);
2269  const int charcode = 0x10000 + (((wc & 0x3FF) << 10) | (wc2 & 0x3FF));
2270  utf8_bytes[0] = 0xf0 | (charcode >> 18);
2271  utf8_bytes[1] = 0x80 | ((charcode >> 12) & 0x3F);
2272  utf8_bytes[2] = 0x80 | ((charcode >> 6) & 0x3F);
2273  utf8_bytes[3] = 0x80 | (charcode & 0x3F);
2274  utf8_bytes_filled = 4;
2275  }
2276  else
2277  {
2278  // unknown character
2279  ++current_wchar;
2280  utf8_bytes[0] = wc;
2281  utf8_bytes_filled = 1;
2282  }
2283  }
2284  }
2285  }
2286 };
2287 
2288 template<typename WideStringType>
2290 {
2291  public:
2292  explicit wide_string_input_adapter(const WideStringType& w) noexcept
2293  : str(w)
2294  {}
2295 
2296  std::char_traits<char>::int_type get_character() noexcept override
2297  {
2298  // check if buffer needs to be filled
2299  if (utf8_bytes_index == utf8_bytes_filled)
2300  {
2301  fill_buffer<sizeof(typename WideStringType::value_type)>();
2302 
2303  assert(utf8_bytes_filled > 0);
2304  assert(utf8_bytes_index == 0);
2305  }
2306 
2307  // use buffer
2308  assert(utf8_bytes_filled > 0);
2309  assert(utf8_bytes_index < utf8_bytes_filled);
2310  return utf8_bytes[utf8_bytes_index++];
2311  }
2312 
2313  private:
2314  template<size_t T>
2316  {
2317  wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2318  }
2319 
2321  const WideStringType& str;
2322 
2324  std::size_t current_wchar = 0;
2325 
2327  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2328 
2330  std::size_t utf8_bytes_index = 0;
2332  std::size_t utf8_bytes_filled = 0;
2333 };
2334 
2336 {
2337  public:
2338  // native support
2339 
2341  input_adapter(std::istream& i)
2342  : ia(std::make_shared<input_stream_adapter>(i)) {}
2343 
2345  input_adapter(std::istream&& i)
2346  : ia(std::make_shared<input_stream_adapter>(i)) {}
2347 
2348  input_adapter(const std::wstring& ws)
2349  : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2350 
2351  input_adapter(const std::u16string& ws)
2352  : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2353 
2354  input_adapter(const std::u32string& ws)
2355  : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2356 
2358  template<typename CharT,
2359  typename std::enable_if<
2361  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2362  sizeof(typename std::remove_pointer<CharT>::type) == 1,
2363  int>::type = 0>
2364  input_adapter(CharT b, std::size_t l)
2365  : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2366 
2367  // derived support
2368 
2370  template<typename CharT,
2371  typename std::enable_if<
2373  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2374  sizeof(typename std::remove_pointer<CharT>::type) == 1,
2375  int>::type = 0>
2376  input_adapter(CharT b)
2377  : input_adapter(reinterpret_cast<const char*>(b),
2378  std::strlen(reinterpret_cast<const char*>(b))) {}
2379 
2381  template<class IteratorType,
2382  typename std::enable_if<
2383  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2384  int>::type = 0>
2385  input_adapter(IteratorType first, IteratorType last)
2386  {
2387 #ifndef NDEBUG
2388  // assertion to check that the iterator range is indeed contiguous,
2389  // see http://stackoverflow.com/a/35008842/266378 for more discussion
2390  const auto is_contiguous = std::accumulate(
2391  first, last, std::pair<bool, int>(true, 0),
2392  [&first](std::pair<bool, int> res, decltype(*first) val)
2393  {
2394  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2395  return res;
2396  }).first;
2397  assert(is_contiguous);
2398 #endif
2399 
2400  // assertion to check that each element is 1 byte long
2401  static_assert(
2402  sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
2403  "each element in the iterator range must have the size of 1 byte");
2404 
2405  const auto len = static_cast<size_t>(std::distance(first, last));
2406  if (JSON_LIKELY(len > 0))
2407  {
2408  // there is at least one element: use the address of first
2409  ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2410  }
2411  else
2412  {
2413  // the address of first cannot be used: use nullptr
2414  ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2415  }
2416  }
2417 
2419  template<class T, std::size_t N>
2421  : input_adapter(std::begin(array), std::end(array)) {}
2422 
2424  template<class ContiguousContainer, typename
2426  std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2427  int>::type = 0>
2428  input_adapter(const ContiguousContainer& c)
2429  : input_adapter(std::begin(c), std::end(c)) {}
2430 
2431  operator input_adapter_t()
2432  {
2433  return ia;
2434  }
2435 
2436  private:
2438  input_adapter_t ia = nullptr;
2439 };
2440 } // namespace detail
2441 } // namespace nlohmann
2442 
2443 // #include <nlohmann/detail/input/lexer.hpp>
2444 
2445 
2446 #include <clocale> // localeconv
2447 #include <cstddef> // size_t
2448 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
2449 #include <cstdio> // snprintf
2450 #include <initializer_list> // initializer_list
2451 #include <string> // char_traits, string
2452 #include <vector> // vector
2453 
2454 // #include <nlohmann/detail/macro_scope.hpp>
2455 
2456 // #include <nlohmann/detail/input/input_adapters.hpp>
2457 
2458 // #include <nlohmann/detail/input/position_t.hpp>
2459 
2460 
2461 namespace nlohmann
2462 {
2463 namespace detail
2464 {
2466 // lexer //
2468 
2474 template<typename BasicJsonType>
2475 class lexer
2476 {
2477  using number_integer_t = typename BasicJsonType::number_integer_t;
2478  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2479  using number_float_t = typename BasicJsonType::number_float_t;
2480  using string_t = typename BasicJsonType::string_t;
2481 
2482  public:
2484  enum class token_type
2485  {
2486  uninitialized,
2487  literal_true,
2488  literal_false,
2489  literal_null,
2490  value_string,
2491  value_unsigned,
2492  value_integer,
2493  value_float,
2494  begin_array,
2495  begin_object,
2496  end_array,
2497  end_object,
2498  name_separator,
2499  value_separator,
2500  parse_error,
2501  end_of_input,
2502  literal_or_value
2503  };
2504 
2506  static const char* token_type_name(const token_type t) noexcept
2507  {
2508  switch (t)
2509  {
2510  case token_type::uninitialized:
2511  return "<uninitialized>";
2512  case token_type::literal_true:
2513  return "true literal";
2514  case token_type::literal_false:
2515  return "false literal";
2516  case token_type::literal_null:
2517  return "null literal";
2518  case token_type::value_string:
2519  return "string literal";
2523  return "number literal";
2524  case token_type::begin_array:
2525  return "'['";
2526  case token_type::begin_object:
2527  return "'{'";
2528  case token_type::end_array:
2529  return "']'";
2530  case token_type::end_object:
2531  return "'}'";
2532  case token_type::name_separator:
2533  return "':'";
2534  case token_type::value_separator:
2535  return "','";
2536  case token_type::parse_error:
2537  return "<parse error>";
2538  case token_type::end_of_input:
2539  return "end of input";
2540  case token_type::literal_or_value:
2541  return "'[', '{', or a literal";
2542  // LCOV_EXCL_START
2543  default: // catch non-enum values
2544  return "unknown token";
2545  // LCOV_EXCL_STOP
2546  }
2547  }
2548 
2549  explicit lexer(detail::input_adapter_t&& adapter)
2550  : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
2551 
2552  // delete because of pointer members
2553  lexer(const lexer&) = delete;
2554  lexer(lexer&&) = delete;
2555  lexer& operator=(lexer&) = delete;
2556  lexer& operator=(lexer&&) = delete;
2557  ~lexer() = default;
2558 
2559  private:
2561  // locales
2563 
2565  static char get_decimal_point() noexcept
2566  {
2567  const auto loc = localeconv();
2568  assert(loc != nullptr);
2569  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
2570  }
2571 
2573  // scan functions
2575 
2592  {
2593  // this function only makes sense after reading `\u`
2594  assert(current == 'u');
2595  int codepoint = 0;
2596 
2597  const auto factors = { 12, 8, 4, 0 };
2598  for (const auto factor : factors)
2599  {
2600  get();
2601 
2602  if (current >= '0' and current <= '9')
2603  {
2604  codepoint += ((current - 0x30) << factor);
2605  }
2606  else if (current >= 'A' and current <= 'F')
2607  {
2608  codepoint += ((current - 0x37) << factor);
2609  }
2610  else if (current >= 'a' and current <= 'f')
2611  {
2612  codepoint += ((current - 0x57) << factor);
2613  }
2614  else
2615  {
2616  return -1;
2617  }
2618  }
2619 
2620  assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
2621  return codepoint;
2622  }
2623 
2639  bool next_byte_in_range(std::initializer_list<int> ranges)
2640  {
2641  assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
2642  add(current);
2643 
2644  for (auto range = ranges.begin(); range != ranges.end(); ++range)
2645  {
2646  get();
2647  if (JSON_LIKELY(*range <= current and current <= *(++range)))
2648  {
2649  add(current);
2650  }
2651  else
2652  {
2653  error_message = "invalid string: ill-formed UTF-8 byte";
2654  return false;
2655  }
2656  }
2657 
2658  return true;
2659  }
2660 
2677  {
2678  // reset token_buffer (ignore opening quote)
2679  reset();
2680 
2681  // we entered the function by reading an open quote
2682  assert(current == '\"');
2683 
2684  while (true)
2685  {
2686  // get next character
2687  switch (get())
2688  {
2689  // end of file while parsing string
2690  case std::char_traits<char>::eof():
2691  {
2692  error_message = "invalid string: missing closing quote";
2693  return token_type::parse_error;
2694  }
2695 
2696  // closing quote
2697  case '\"':
2698  {
2699  return token_type::value_string;
2700  }
2701 
2702  // escapes
2703  case '\\':
2704  {
2705  switch (get())
2706  {
2707  // quotation mark
2708  case '\"':
2709  add('\"');
2710  break;
2711  // reverse solidus
2712  case '\\':
2713  add('\\');
2714  break;
2715  // solidus
2716  case '/':
2717  add('/');
2718  break;
2719  // backspace
2720  case 'b':
2721  add('\b');
2722  break;
2723  // form feed
2724  case 'f':
2725  add('\f');
2726  break;
2727  // line feed
2728  case 'n':
2729  add('\n');
2730  break;
2731  // carriage return
2732  case 'r':
2733  add('\r');
2734  break;
2735  // tab
2736  case 't':
2737  add('\t');
2738  break;
2739 
2740  // unicode escapes
2741  case 'u':
2742  {
2743  const int codepoint1 = get_codepoint();
2744  int codepoint = codepoint1; // start with codepoint1
2745 
2746  if (JSON_UNLIKELY(codepoint1 == -1))
2747  {
2748  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2749  return token_type::parse_error;
2750  }
2751 
2752  // check if code point is a high surrogate
2753  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
2754  {
2755  // expect next \uxxxx entry
2756  if (JSON_LIKELY(get() == '\\' and get() == 'u'))
2757  {
2758  const int codepoint2 = get_codepoint();
2759 
2760  if (JSON_UNLIKELY(codepoint2 == -1))
2761  {
2762  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
2763  return token_type::parse_error;
2764  }
2765 
2766  // check if codepoint2 is a low surrogate
2767  if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
2768  {
2769  // overwrite codepoint
2770  codepoint =
2771  // high surrogate occupies the most significant 22 bits
2772  (codepoint1 << 10)
2773  // low surrogate occupies the least significant 15 bits
2774  + codepoint2
2775  // there is still the 0xD800, 0xDC00 and 0x10000 noise
2776  // in the result so we have to subtract with:
2777  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
2778  - 0x35FDC00;
2779  }
2780  else
2781  {
2782  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2783  return token_type::parse_error;
2784  }
2785  }
2786  else
2787  {
2788  error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
2789  return token_type::parse_error;
2790  }
2791  }
2792  else
2793  {
2794  if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
2795  {
2796  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
2797  return token_type::parse_error;
2798  }
2799  }
2800 
2801  // result of the above calculation yields a proper codepoint
2802  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
2803 
2804  // translate codepoint into bytes
2805  if (codepoint < 0x80)
2806  {
2807  // 1-byte characters: 0xxxxxxx (ASCII)
2808  add(codepoint);
2809  }
2810  else if (codepoint <= 0x7FF)
2811  {
2812  // 2-byte characters: 110xxxxx 10xxxxxx
2813  add(0xC0 | (codepoint >> 6));
2814  add(0x80 | (codepoint & 0x3F));
2815  }
2816  else if (codepoint <= 0xFFFF)
2817  {
2818  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
2819  add(0xE0 | (codepoint >> 12));
2820  add(0x80 | ((codepoint >> 6) & 0x3F));
2821  add(0x80 | (codepoint & 0x3F));
2822  }
2823  else
2824  {
2825  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2826  add(0xF0 | (codepoint >> 18));
2827  add(0x80 | ((codepoint >> 12) & 0x3F));
2828  add(0x80 | ((codepoint >> 6) & 0x3F));
2829  add(0x80 | (codepoint & 0x3F));
2830  }
2831 
2832  break;
2833  }
2834 
2835  // other characters after escape
2836  default:
2837  error_message = "invalid string: forbidden character after backslash";
2838  return token_type::parse_error;
2839  }
2840 
2841  break;
2842  }
2843 
2844  // invalid control characters
2845  case 0x00:
2846  {
2847  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
2848  return token_type::parse_error;
2849  }
2850 
2851  case 0x01:
2852  {
2853  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
2854  return token_type::parse_error;
2855  }
2856 
2857  case 0x02:
2858  {
2859  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
2860  return token_type::parse_error;
2861  }
2862 
2863  case 0x03:
2864  {
2865  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
2866  return token_type::parse_error;
2867  }
2868 
2869  case 0x04:
2870  {
2871  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
2872  return token_type::parse_error;
2873  }
2874 
2875  case 0x05:
2876  {
2877  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
2878  return token_type::parse_error;
2879  }
2880 
2881  case 0x06:
2882  {
2883  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
2884  return token_type::parse_error;
2885  }
2886 
2887  case 0x07:
2888  {
2889  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
2890  return token_type::parse_error;
2891  }
2892 
2893  case 0x08:
2894  {
2895  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
2896  return token_type::parse_error;
2897  }
2898 
2899  case 0x09:
2900  {
2901  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
2902  return token_type::parse_error;
2903  }
2904 
2905  case 0x0A:
2906  {
2907  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
2908  return token_type::parse_error;
2909  }
2910 
2911  case 0x0B:
2912  {
2913  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
2914  return token_type::parse_error;
2915  }
2916 
2917  case 0x0C:
2918  {
2919  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
2920  return token_type::parse_error;
2921  }
2922 
2923  case 0x0D:
2924  {
2925  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
2926  return token_type::parse_error;
2927  }
2928 
2929  case 0x0E:
2930  {
2931  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
2932  return token_type::parse_error;
2933  }
2934 
2935  case 0x0F:
2936  {
2937  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
2938  return token_type::parse_error;
2939  }
2940 
2941  case 0x10:
2942  {
2943  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
2944  return token_type::parse_error;
2945  }
2946 
2947  case 0x11:
2948  {
2949  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
2950  return token_type::parse_error;
2951  }
2952 
2953  case 0x12:
2954  {
2955  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
2956  return token_type::parse_error;
2957  }
2958 
2959  case 0x13:
2960  {
2961  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
2962  return token_type::parse_error;
2963  }
2964 
2965  case 0x14:
2966  {
2967  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
2968  return token_type::parse_error;
2969  }
2970 
2971  case 0x15:
2972  {
2973  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
2974  return token_type::parse_error;
2975  }
2976 
2977  case 0x16:
2978  {
2979  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
2980  return token_type::parse_error;
2981  }
2982 
2983  case 0x17:
2984  {
2985  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
2986  return token_type::parse_error;
2987  }
2988 
2989  case 0x18:
2990  {
2991  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
2992  return token_type::parse_error;
2993  }
2994 
2995  case 0x19:
2996  {
2997  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
2998  return token_type::parse_error;
2999  }
3000 
3001  case 0x1A:
3002  {
3003  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
3004  return token_type::parse_error;
3005  }
3006 
3007  case 0x1B:
3008  {
3009  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
3010  return token_type::parse_error;
3011  }
3012 
3013  case 0x1C:
3014  {
3015  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
3016  return token_type::parse_error;
3017  }
3018 
3019  case 0x1D:
3020  {
3021  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
3022  return token_type::parse_error;
3023  }
3024 
3025  case 0x1E:
3026  {
3027  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
3028  return token_type::parse_error;
3029  }
3030 
3031  case 0x1F:
3032  {
3033  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
3034  return token_type::parse_error;
3035  }
3036 
3037  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
3038  case 0x20:
3039  case 0x21:
3040  case 0x23:
3041  case 0x24:
3042  case 0x25:
3043  case 0x26:
3044  case 0x27:
3045  case 0x28:
3046  case 0x29:
3047  case 0x2A:
3048  case 0x2B:
3049  case 0x2C:
3050  case 0x2D:
3051  case 0x2E:
3052  case 0x2F:
3053  case 0x30:
3054  case 0x31:
3055  case 0x32:
3056  case 0x33:
3057  case 0x34:
3058  case 0x35:
3059  case 0x36:
3060  case 0x37:
3061  case 0x38:
3062  case 0x39:
3063  case 0x3A:
3064  case 0x3B:
3065  case 0x3C:
3066  case 0x3D:
3067  case 0x3E:
3068  case 0x3F:
3069  case 0x40:
3070  case 0x41:
3071  case 0x42:
3072  case 0x43:
3073  case 0x44:
3074  case 0x45:
3075  case 0x46:
3076  case 0x47:
3077  case 0x48:
3078  case 0x49:
3079  case 0x4A:
3080  case 0x4B:
3081  case 0x4C:
3082  case 0x4D:
3083  case 0x4E:
3084  case 0x4F:
3085  case 0x50:
3086  case 0x51:
3087  case 0x52:
3088  case 0x53:
3089  case 0x54:
3090  case 0x55:
3091  case 0x56:
3092  case 0x57:
3093  case 0x58:
3094  case 0x59:
3095  case 0x5A:
3096  case 0x5B:
3097  case 0x5D:
3098  case 0x5E:
3099  case 0x5F:
3100  case 0x60:
3101  case 0x61:
3102  case 0x62:
3103  case 0x63:
3104  case 0x64:
3105  case 0x65:
3106  case 0x66:
3107  case 0x67:
3108  case 0x68:
3109  case 0x69:
3110  case 0x6A:
3111  case 0x6B:
3112  case 0x6C:
3113  case 0x6D:
3114  case 0x6E:
3115  case 0x6F:
3116  case 0x70:
3117  case 0x71:
3118  case 0x72:
3119  case 0x73:
3120  case 0x74:
3121  case 0x75:
3122  case 0x76:
3123  case 0x77:
3124  case 0x78:
3125  case 0x79:
3126  case 0x7A:
3127  case 0x7B:
3128  case 0x7C:
3129  case 0x7D:
3130  case 0x7E:
3131  case 0x7F:
3132  {
3133  add(current);
3134  break;
3135  }
3136 
3137  // U+0080..U+07FF: bytes C2..DF 80..BF
3138  case 0xC2:
3139  case 0xC3:
3140  case 0xC4:
3141  case 0xC5:
3142  case 0xC6:
3143  case 0xC7:
3144  case 0xC8:
3145  case 0xC9:
3146  case 0xCA:
3147  case 0xCB:
3148  case 0xCC:
3149  case 0xCD:
3150  case 0xCE:
3151  case 0xCF:
3152  case 0xD0:
3153  case 0xD1:
3154  case 0xD2:
3155  case 0xD3:
3156  case 0xD4:
3157  case 0xD5:
3158  case 0xD6:
3159  case 0xD7:
3160  case 0xD8:
3161  case 0xD9:
3162  case 0xDA:
3163  case 0xDB:
3164  case 0xDC:
3165  case 0xDD:
3166  case 0xDE:
3167  case 0xDF:
3168  {
3169  if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
3170  {
3171  return token_type::parse_error;
3172  }
3173  break;
3174  }
3175 
3176  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
3177  case 0xE0:
3178  {
3179  if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
3180  {
3181  return token_type::parse_error;
3182  }
3183  break;
3184  }
3185 
3186  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
3187  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
3188  case 0xE1:
3189  case 0xE2:
3190  case 0xE3:
3191  case 0xE4:
3192  case 0xE5:
3193  case 0xE6:
3194  case 0xE7:
3195  case 0xE8:
3196  case 0xE9:
3197  case 0xEA:
3198  case 0xEB:
3199  case 0xEC:
3200  case 0xEE:
3201  case 0xEF:
3202  {
3203  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
3204  {
3205  return token_type::parse_error;
3206  }
3207  break;
3208  }
3209 
3210  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
3211  case 0xED:
3212  {
3213  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
3214  {
3215  return token_type::parse_error;
3216  }
3217  break;
3218  }
3219 
3220  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
3221  case 0xF0:
3222  {
3223  if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3224  {
3225  return token_type::parse_error;
3226  }
3227  break;
3228  }
3229 
3230  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
3231  case 0xF1:
3232  case 0xF2:
3233  case 0xF3:
3234  {
3235  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
3236  {
3237  return token_type::parse_error;
3238  }
3239  break;
3240  }
3241 
3242  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
3243  case 0xF4:
3244  {
3245  if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
3246  {
3247  return token_type::parse_error;
3248  }
3249  break;
3250  }
3251 
3252  // remaining bytes (80..C1 and F5..FF) are ill-formed
3253  default:
3254  {
3255  error_message = "invalid string: ill-formed UTF-8 byte";
3256  return token_type::parse_error;
3257  }
3258  }
3259  }
3260  }
3261 
3262  static void strtof(float& f, const char* str, char** endptr) noexcept
3263  {
3264  f = std::strtof(str, endptr);
3265  }
3266 
3267  static void strtof(double& f, const char* str, char** endptr) noexcept
3268  {
3269  f = std::strtod(str, endptr);
3270  }
3271 
3272  static void strtof(long double& f, const char* str, char** endptr) noexcept
3273  {
3274  f = std::strtold(str, endptr);
3275  }
3276 
3317  token_type scan_number() // lgtm [cpp/use-of-goto]
3318  {
3319  // reset token_buffer to store the number's bytes
3320  reset();
3321 
3322  // the type of the parsed number; initially set to unsigned; will be
3323  // changed if minus sign, decimal point or exponent is read
3324  token_type number_type = token_type::value_unsigned;
3325 
3326  // state (init): we just found out we need to scan a number
3327  switch (current)
3328  {
3329  case '-':
3330  {
3331  add(current);
3332  goto scan_number_minus;
3333  }
3334 
3335  case '0':
3336  {
3337  add(current);
3338  goto scan_number_zero;
3339  }
3340 
3341  case '1':
3342  case '2':
3343  case '3':
3344  case '4':
3345  case '5':
3346  case '6':
3347  case '7':
3348  case '8':
3349  case '9':
3350  {
3351  add(current);
3352  goto scan_number_any1;
3353  }
3354 
3355  // LCOV_EXCL_START
3356  default:
3357  {
3358  // all other characters are rejected outside scan_number()
3359  assert(false);
3360  }
3361  // LCOV_EXCL_STOP
3362  }
3363 
3364 scan_number_minus:
3365  // state: we just parsed a leading minus sign
3366  number_type = token_type::value_integer;
3367  switch (get())
3368  {
3369  case '0':
3370  {
3371  add(current);
3372  goto scan_number_zero;
3373  }
3374 
3375  case '1':
3376  case '2':
3377  case '3':
3378  case '4':
3379  case '5':
3380  case '6':
3381  case '7':
3382  case '8':
3383  case '9':
3384  {
3385  add(current);
3386  goto scan_number_any1;
3387  }
3388 
3389  default:
3390  {
3391  error_message = "invalid number; expected digit after '-'";
3392  return token_type::parse_error;
3393  }
3394  }
3395 
3396 scan_number_zero:
3397  // state: we just parse a zero (maybe with a leading minus sign)
3398  switch (get())
3399  {
3400  case '.':
3401  {
3402  add(decimal_point_char);
3403  goto scan_number_decimal1;
3404  }
3405 
3406  case 'e':
3407  case 'E':
3408  {
3409  add(current);
3410  goto scan_number_exponent;
3411  }
3412 
3413  default:
3414  goto scan_number_done;
3415  }
3416 
3417 scan_number_any1:
3418  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
3419  switch (get())
3420  {
3421  case '0':
3422  case '1':
3423  case '2':
3424  case '3':
3425  case '4':
3426  case '5':
3427  case '6':
3428  case '7':
3429  case '8':
3430  case '9':
3431  {
3432  add(current);
3433  goto scan_number_any1;
3434  }
3435 
3436  case '.':
3437  {
3438  add(decimal_point_char);
3439  goto scan_number_decimal1;
3440  }
3441 
3442  case 'e':
3443  case 'E':
3444  {
3445  add(current);
3446  goto scan_number_exponent;
3447  }
3448 
3449  default:
3450  goto scan_number_done;
3451  }
3452 
3453 scan_number_decimal1:
3454  // state: we just parsed a decimal point
3455  number_type = token_type::value_float;
3456  switch (get())
3457  {
3458  case '0':
3459  case '1':
3460  case '2':
3461  case '3':
3462  case '4':
3463  case '5':
3464  case '6':
3465  case '7':
3466  case '8':
3467  case '9':
3468  {
3469  add(current);
3470  goto scan_number_decimal2;
3471  }
3472 
3473  default:
3474  {
3475  error_message = "invalid number; expected digit after '.'";
3476  return token_type::parse_error;
3477  }
3478  }
3479 
3480 scan_number_decimal2:
3481  // we just parsed at least one number after a decimal point
3482  switch (get())
3483  {
3484  case '0':
3485  case '1':
3486  case '2':
3487  case '3':
3488  case '4':
3489  case '5':
3490  case '6':
3491  case '7':
3492  case '8':
3493  case '9':
3494  {
3495  add(current);
3496  goto scan_number_decimal2;
3497  }
3498 
3499  case 'e':
3500  case 'E':
3501  {
3502  add(current);
3503  goto scan_number_exponent;
3504  }
3505 
3506  default:
3507  goto scan_number_done;
3508  }
3509 
3510 scan_number_exponent:
3511  // we just parsed an exponent
3512  number_type = token_type::value_float;
3513  switch (get())
3514  {
3515  case '+':
3516  case '-':
3517  {
3518  add(current);
3519  goto scan_number_sign;
3520  }
3521 
3522  case '0':
3523  case '1':
3524  case '2':
3525  case '3':
3526  case '4':
3527  case '5':
3528  case '6':
3529  case '7':
3530  case '8':
3531  case '9':
3532  {
3533  add(current);
3534  goto scan_number_any2;
3535  }
3536 
3537  default:
3538  {
3539  error_message =
3540  "invalid number; expected '+', '-', or digit after exponent";
3541  return token_type::parse_error;
3542  }
3543  }
3544 
3545 scan_number_sign:
3546  // we just parsed an exponent sign
3547  switch (get())
3548  {
3549  case '0':
3550  case '1':
3551  case '2':
3552  case '3':
3553  case '4':
3554  case '5':
3555  case '6':
3556  case '7':
3557  case '8':
3558  case '9':
3559  {
3560  add(current);
3561  goto scan_number_any2;
3562  }
3563 
3564  default:
3565  {
3566  error_message = "invalid number; expected digit after exponent sign";
3567  return token_type::parse_error;
3568  }
3569  }
3570 
3571 scan_number_any2:
3572  // we just parsed a number after the exponent or exponent sign
3573  switch (get())
3574  {
3575  case '0':
3576  case '1':
3577  case '2':
3578  case '3':
3579  case '4':
3580  case '5':
3581  case '6':
3582  case '7':
3583  case '8':
3584  case '9':
3585  {
3586  add(current);
3587  goto scan_number_any2;
3588  }
3589 
3590  default:
3591  goto scan_number_done;
3592  }
3593 
3594 scan_number_done:
3595  // unget the character after the number (we only read it to know that
3596  // we are done scanning a number)
3597  unget();
3598 
3599  char* endptr = nullptr;
3600  errno = 0;
3601 
3602  // try to parse integers first and fall back to floats
3603  if (number_type == token_type::value_unsigned)
3604  {
3605  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
3606 
3607  // we checked the number format before
3608  assert(endptr == token_buffer.data() + token_buffer.size());
3609 
3610  if (errno == 0)
3611  {
3612  value_unsigned = static_cast<number_unsigned_t>(x);
3613  if (value_unsigned == x)
3614  {
3615  return token_type::value_unsigned;
3616  }
3617  }
3618  }
3619  else if (number_type == token_type::value_integer)
3620  {
3621  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
3622 
3623  // we checked the number format before
3624  assert(endptr == token_buffer.data() + token_buffer.size());
3625 
3626  if (errno == 0)
3627  {
3628  value_integer = static_cast<number_integer_t>(x);
3629  if (value_integer == x)
3630  {
3631  return token_type::value_integer;
3632  }
3633  }
3634  }
3635 
3636  // this code is reached if we parse a floating-point number or if an
3637  // integer conversion above failed
3638  strtof(value_float, token_buffer.data(), &endptr);
3639 
3640  // we checked the number format before
3641  assert(endptr == token_buffer.data() + token_buffer.size());
3642 
3643  return token_type::value_float;
3644  }
3645 
3651  token_type scan_literal(const char* literal_text, const std::size_t length,
3652  token_type return_type)
3653  {
3654  assert(current == literal_text[0]);
3655  for (std::size_t i = 1; i < length; ++i)
3656  {
3657  if (JSON_UNLIKELY(get() != literal_text[i]))
3658  {
3659  error_message = "invalid literal";
3660  return token_type::parse_error;
3661  }
3662  }
3663  return return_type;
3664  }
3665 
3667  // input management
3669 
3671  void reset() noexcept
3672  {
3673  token_buffer.clear();
3674  token_string.clear();
3675  token_string.push_back(std::char_traits<char>::to_char_type(current));
3676  }
3677 
3678  /*
3679  @brief get next character from the input
3680 
3681  This function provides the interface to the used input adapter. It does
3682  not throw in case the input reached EOF, but returns a
3683  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
3684  for use in error messages.
3685 
3686  @return character read from the input
3687  */
3688  std::char_traits<char>::int_type get()
3689  {
3690  ++position.chars_read_total;
3691  ++position.chars_read_current_line;
3692 
3693  if (next_unget)
3694  {
3695  // just reset the next_unget variable and work with current
3696  next_unget = false;
3697  }
3698  else
3699  {
3700  current = ia->get_character();
3701  }
3702 
3703  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3704  {
3705  token_string.push_back(std::char_traits<char>::to_char_type(current));
3706  }
3707 
3708  if (current == '\n')
3709  {
3710  ++position.lines_read;
3711  ++position.chars_read_current_line = 0;
3712  }
3713 
3714  return current;
3715  }
3716 
3725  void unget()
3726  {
3727  next_unget = true;
3728 
3729  --position.chars_read_total;
3730 
3731  // in case we "unget" a newline, we have to also decrement the lines_read
3732  if (position.chars_read_current_line == 0)
3733  {
3734  if (position.lines_read > 0)
3735  {
3736  --position.lines_read;
3737  }
3738  }
3739  else
3740  {
3741  --position.chars_read_current_line;
3742  }
3743 
3744  if (JSON_LIKELY(current != std::char_traits<char>::eof()))
3745  {
3746  assert(token_string.size() != 0);
3747  token_string.pop_back();
3748  }
3749  }
3750 
3752  void add(int c)
3753  {
3754  token_buffer.push_back(std::char_traits<char>::to_char_type(c));
3755  }
3756 
3757  public:
3759  // value getters
3761 
3763  constexpr number_integer_t get_number_integer() const noexcept
3764  {
3765  return value_integer;
3766  }
3767 
3769  constexpr number_unsigned_t get_number_unsigned() const noexcept
3770  {
3771  return value_unsigned;
3772  }
3773 
3775  constexpr number_float_t get_number_float() const noexcept
3776  {
3777  return value_float;
3778  }
3779 
3782  {
3783  return token_buffer;
3784  }
3785 
3787  // diagnostics
3789 
3791  constexpr position_t get_position() const noexcept
3792  {
3793  return position;
3794  }
3795 
3800  {
3801  // escape control characters
3802  std::string result;
3803  for (const auto c : token_string)
3804  {
3805  if ('\x00' <= c and c <= '\x1F')
3806  {
3807  // escape control characters
3808  char cs[9];
3809  snprintf(cs, 9, "<U+%.4X>", static_cast<unsigned char>(c));
3810  result += cs;
3811  }
3812  else
3813  {
3814  // add character as is
3815  result.push_back(c);
3816  }
3817  }
3818 
3819  return result;
3820  }
3821 
3823  constexpr const char* get_error_message() const noexcept
3824  {
3825  return error_message;
3826  }
3827 
3829  // actual scanner
3831 
3836  bool skip_bom()
3837  {
3838  if (get() == 0xEF)
3839  {
3840  // check if we completely parse the BOM
3841  return get() == 0xBB and get() == 0xBF;
3842  }
3843 
3844  // the first character is not the beginning of the BOM; unget it to
3845  // process is later
3846  unget();
3847  return true;
3848  }
3849 
3851  {
3852  // initially, skip the BOM
3853  if (position.chars_read_total == 0 and not skip_bom())
3854  {
3855  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
3856  return token_type::parse_error;
3857  }
3858 
3859  // read next character and ignore whitespace
3860  do
3861  {
3862  get();
3863  }
3864  while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
3865 
3866  switch (current)
3867  {
3868  // structural characters
3869  case '[':
3870  return token_type::begin_array;
3871  case ']':
3872  return token_type::end_array;
3873  case '{':
3874  return token_type::begin_object;
3875  case '}':
3876  return token_type::end_object;
3877  case ':':
3878  return token_type::name_separator;
3879  case ',':
3880  return token_type::value_separator;
3881 
3882  // literals
3883  case 't':
3884  return scan_literal("true", 4, token_type::literal_true);
3885  case 'f':
3886  return scan_literal("false", 5, token_type::literal_false);
3887  case 'n':
3888  return scan_literal("null", 4, token_type::literal_null);
3889 
3890  // string
3891  case '\"':
3892  return scan_string();
3893 
3894  // number
3895  case '-':
3896  case '0':
3897  case '1':
3898  case '2':
3899  case '3':
3900  case '4':
3901  case '5':
3902  case '6':
3903  case '7':
3904  case '8':
3905  case '9':
3906  return scan_number();
3907 
3908  // end of input (the null byte is needed when parsing from
3909  // string literals)
3910  case '\0':
3911  case std::char_traits<char>::eof():
3912  return token_type::end_of_input;
3913 
3914  // error
3915  default:
3916  error_message = "invalid literal";
3917  return token_type::parse_error;
3918  }
3919  }
3920 
3921  private:
3924 
3926  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
3927 
3929  bool next_unget = false;
3930 
3933 
3935  std::vector<char> token_string {};
3936 
3938  string_t token_buffer {};
3939 
3941  const char* error_message = "";
3942 
3943  // number values
3944  number_integer_t value_integer = 0;
3945  number_unsigned_t value_unsigned = 0;
3946  number_float_t value_float = 0;
3947 
3949  const char decimal_point_char = '.';
3950 };
3951 } // namespace detail
3952 } // namespace nlohmann
3953 
3954 // #include <nlohmann/detail/input/parser.hpp>
3955 
3956 
3957 #include <cassert> // assert
3958 #include <cmath> // isfinite
3959 #include <cstdint> // uint8_t
3960 #include <functional> // function
3961 #include <string> // string
3962 #include <utility> // move
3963 
3964 // #include <nlohmann/detail/exceptions.hpp>
3965 
3966 // #include <nlohmann/detail/macro_scope.hpp>
3967 
3968 // #include <nlohmann/detail/meta/is_sax.hpp>
3969 
3970 
3971 #include <cstdint> // size_t
3972 #include <utility> // declval
3973 
3974 // #include <nlohmann/detail/meta/detected.hpp>
3975 
3976 // #include <nlohmann/detail/meta/type_traits.hpp>
3977 
3978 
3979 namespace nlohmann
3980 {
3981 namespace detail
3982 {
3983 template <typename T>
3984 using null_function_t = decltype(std::declval<T&>().null());
3985 
3986 template <typename T>
3987 using boolean_function_t =
3988  decltype(std::declval<T&>().boolean(std::declval<bool>()));
3989 
3990 template <typename T, typename Integer>
3992  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3993 
3994 template <typename T, typename Unsigned>
3996  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3997 
3998 template <typename T, typename Float, typename String>
3999 using number_float_function_t = decltype(std::declval<T&>().number_float(
4000  std::declval<Float>(), std::declval<const String&>()));
4001 
4002 template <typename T, typename String>
4003 using string_function_t =
4004  decltype(std::declval<T&>().string(std::declval<String&>()));
4005 
4006 template <typename T>
4008  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
4009 
4010 template <typename T, typename String>
4011 using key_function_t =
4012  decltype(std::declval<T&>().key(std::declval<String&>()));
4013 
4014 template <typename T>
4015 using end_object_function_t = decltype(std::declval<T&>().end_object());
4016 
4017 template <typename T>
4018 using start_array_function_t =
4019  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
4020 
4021 template <typename T>
4022 using end_array_function_t = decltype(std::declval<T&>().end_array());
4023 
4024 template <typename T, typename Exception>
4025 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
4026  std::declval<std::size_t>(), std::declval<const std::string&>(),
4027  std::declval<const Exception&>()));
4028 
4029 template <typename SAX, typename BasicJsonType>
4030 struct is_sax
4031 {
4032  private:
4034  "BasicJsonType must be of type basic_json<...>");
4035 
4036  using number_integer_t = typename BasicJsonType::number_integer_t;
4037  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4038  using number_float_t = typename BasicJsonType::number_float_t;
4039  using string_t = typename BasicJsonType::string_t;
4040  using exception_t = typename BasicJsonType::exception;
4041 
4042  public:
4043  static constexpr bool value =
4047  number_integer_t>::value &&
4049  number_unsigned_t>::value &&
4051  string_t>::value &&
4059 };
4060 
4061 template <typename SAX, typename BasicJsonType>
4063 {
4064  private:
4066  "BasicJsonType must be of type basic_json<...>");
4067 
4068  using number_integer_t = typename BasicJsonType::number_integer_t;
4069  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4070  using number_float_t = typename BasicJsonType::number_float_t;
4071  using string_t = typename BasicJsonType::string_t;
4072  using exception_t = typename BasicJsonType::exception;
4073 
4074  public:
4076  "Missing/invalid function: bool null()");
4078  "Missing/invalid function: bool boolean(bool)");
4080  "Missing/invalid function: bool boolean(bool)");
4081  static_assert(
4084  "Missing/invalid function: bool number_integer(number_integer_t)");
4085  static_assert(
4086  is_detected_exact<bool, number_unsigned_function_t, SAX,
4088  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
4089  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
4091  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
4092  static_assert(
4094  "Missing/invalid function: bool string(string_t&)");
4096  "Missing/invalid function: bool start_object(std::size_t)");
4098  "Missing/invalid function: bool key(string_t&)");
4100  "Missing/invalid function: bool end_object()");
4102  "Missing/invalid function: bool start_array(std::size_t)");
4104  "Missing/invalid function: bool end_array()");
4105  static_assert(
4107  "Missing/invalid function: bool parse_error(std::size_t, const "
4108  "std::string&, const exception&)");
4109 };
4110 } // namespace detail
4111 } // namespace nlohmann
4112 
4113 // #include <nlohmann/detail/input/input_adapters.hpp>
4114 
4115 // #include <nlohmann/detail/input/json_sax.hpp>
4116 
4117 
4118 #include <cstddef>
4119 #include <string>
4120 #include <vector>
4121 
4122 // #include <nlohmann/detail/input/parser.hpp>
4123 
4124 // #include <nlohmann/detail/exceptions.hpp>
4125 
4126 
4127 namespace nlohmann
4128 {
4129 
4138 template<typename BasicJsonType>
4139 struct json_sax
4140 {
4142  using number_integer_t = typename BasicJsonType::number_integer_t;
4144  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4146  using number_float_t = typename BasicJsonType::number_float_t;
4148  using string_t = typename BasicJsonType::string_t;
4149 
4154  virtual bool null() = 0;
4155 
4161  virtual bool boolean(bool val) = 0;
4162 
4168  virtual bool number_integer(number_integer_t val) = 0;
4169 
4175  virtual bool number_unsigned(number_unsigned_t val) = 0;
4176 
4183  virtual bool number_float(number_float_t val, const string_t& s) = 0;
4184 
4191  virtual bool string(string_t& val) = 0;
4192 
4199  virtual bool start_object(std::size_t elements) = 0;
4200 
4207  virtual bool key(string_t& val) = 0;
4208 
4213  virtual bool end_object() = 0;
4214 
4221  virtual bool start_array(std::size_t elements) = 0;
4222 
4227  virtual bool end_array() = 0;
4228 
4236  virtual bool parse_error(std::size_t position,
4237  const std::string& last_token,
4238  const detail::exception& ex) = 0;
4239 
4240  virtual ~json_sax() = default;
4241 };
4242 
4243 
4244 namespace detail
4245 {
4259 template<typename BasicJsonType>
4261 {
4262  public:
4263  using number_integer_t = typename BasicJsonType::number_integer_t;
4264  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4265  using number_float_t = typename BasicJsonType::number_float_t;
4266  using string_t = typename BasicJsonType::string_t;
4267 
4273  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
4274  : root(r), allow_exceptions(allow_exceptions_)
4275  {}
4276 
4277  bool null()
4278  {
4279  handle_value(nullptr);
4280  return true;
4281  }
4282 
4283  bool boolean(bool val)
4284  {
4285  handle_value(val);
4286  return true;
4287  }
4288 
4290  {
4291  handle_value(val);
4292  return true;
4293  }
4294 
4296  {
4297  handle_value(val);
4298  return true;
4299  }
4300 
4301  bool number_float(number_float_t val, const string_t& /*unused*/)
4302  {
4303  handle_value(val);
4304  return true;
4305  }
4306 
4307  bool string(string_t& val)
4308  {
4309  handle_value(val);
4310  return true;
4311  }
4312 
4313  bool start_object(std::size_t len)
4314  {
4315  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4316 
4317  if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4318  {
4320  "excessive object size: " + std::to_string(len)));
4321  }
4322 
4323  return true;
4324  }
4325 
4326  bool key(string_t& val)
4327  {
4328  // add null at given key and store the reference for later
4329  object_element = &(ref_stack.back()->m_value.object->operator[](val));
4330  return true;
4331  }
4332 
4333  bool end_object()
4334  {
4335  ref_stack.pop_back();
4336  return true;
4337  }
4338 
4339  bool start_array(std::size_t len)
4340  {
4341  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4342 
4343  if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4344  {
4346  "excessive array size: " + std::to_string(len)));
4347  }
4348 
4349  return true;
4350  }
4351 
4352  bool end_array()
4353  {
4354  ref_stack.pop_back();
4355  return true;
4356  }
4357 
4358  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4359  const detail::exception& ex)
4360  {
4361  errored = true;
4362  if (allow_exceptions)
4363  {
4364  // determine the proper exception type from the id
4365  switch ((ex.id / 100) % 100)
4366  {
4367  case 1:
4368  JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4369  case 4:
4370  JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4371  // LCOV_EXCL_START
4372  case 2:
4373  JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4374  case 3:
4375  JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4376  case 5:
4377  JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4378  default:
4379  assert(false);
4380  // LCOV_EXCL_STOP
4381  }
4382  }
4383  return false;
4384  }
4385 
4386  constexpr bool is_errored() const
4387  {
4388  return errored;
4389  }
4390 
4391  private:
4398  template<typename Value>
4399  BasicJsonType* handle_value(Value&& v)
4400  {
4401  if (ref_stack.empty())
4402  {
4403  root = BasicJsonType(std::forward<Value>(v));
4404  return &root;
4405  }
4406 
4407  assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4408 
4409  if (ref_stack.back()->is_array())
4410  {
4411  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4412  return &(ref_stack.back()->m_value.array->back());
4413  }
4414  else
4415  {
4416  assert(object_element);
4417  *object_element = BasicJsonType(std::forward<Value>(v));
4418  return object_element;
4419  }
4420  }
4421 
4423  BasicJsonType& root;
4425  std::vector<BasicJsonType*> ref_stack;
4427  BasicJsonType* object_element = nullptr;
4429  bool errored = false;
4431  const bool allow_exceptions = true;
4432 };
4433 
4434 template<typename BasicJsonType>
4436 {
4437  public:
4438  using number_integer_t = typename BasicJsonType::number_integer_t;
4439  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4440  using number_float_t = typename BasicJsonType::number_float_t;
4441  using string_t = typename BasicJsonType::string_t;
4442  using parser_callback_t = typename BasicJsonType::parser_callback_t;
4443  using parse_event_t = typename BasicJsonType::parse_event_t;
4444 
4446  const parser_callback_t cb,
4447  const bool allow_exceptions_ = true)
4448  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4449  {
4450  keep_stack.push_back(true);
4451  }
4452 
4453  bool null()
4454  {
4455  handle_value(nullptr);
4456  return true;
4457  }
4458 
4459  bool boolean(bool val)
4460  {
4461  handle_value(val);
4462  return true;
4463  }
4464 
4466  {
4467  handle_value(val);
4468  return true;
4469  }
4470 
4472  {
4473  handle_value(val);
4474  return true;
4475  }
4476 
4477  bool number_float(number_float_t val, const string_t& /*unused*/)
4478  {
4479  handle_value(val);
4480  return true;
4481  }
4482 
4483  bool string(string_t& val)
4484  {
4485  handle_value(val);
4486  return true;
4487  }
4488 
4489  bool start_object(std::size_t len)
4490  {
4491  // check callback for object start
4492  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4493  keep_stack.push_back(keep);
4494 
4495  auto val = handle_value(BasicJsonType::value_t::object, true);
4496  ref_stack.push_back(val.second);
4497 
4498  // check object limit
4499  if (ref_stack.back())
4500  {
4501  if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4502  {
4504  "excessive object size: " + std::to_string(len)));
4505  }
4506  }
4507 
4508  return true;
4509  }
4510 
4511  bool key(string_t& val)
4512  {
4513  BasicJsonType k = BasicJsonType(val);
4514 
4515  // check callback for key
4516  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4517  key_keep_stack.push_back(keep);
4518 
4519  // add discarded value at given key and store the reference for later
4520  if (keep and ref_stack.back())
4521  {
4522  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4523  }
4524 
4525  return true;
4526  }
4527 
4528  bool end_object()
4529  {
4530  if (ref_stack.back())
4531  {
4532  if (not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4533  {
4534  // discard object
4535  *ref_stack.back() = discarded;
4536  }
4537  }
4538 
4539  assert(not ref_stack.empty());
4540  assert(not keep_stack.empty());
4541  ref_stack.pop_back();
4542  keep_stack.pop_back();
4543 
4544  if (not ref_stack.empty() and ref_stack.back())
4545  {
4546  // remove discarded value
4547  if (ref_stack.back()->is_object())
4548  {
4549  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4550  {
4551  if (it->is_discarded())
4552  {
4553  ref_stack.back()->erase(it);
4554  break;
4555  }
4556  }
4557  }
4558  }
4559 
4560  return true;
4561  }
4562 
4563  bool start_array(std::size_t len)
4564  {
4565  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4566  keep_stack.push_back(keep);
4567 
4568  auto val = handle_value(BasicJsonType::value_t::array, true);
4569  ref_stack.push_back(val.second);
4570 
4571  // check array limit
4572  if (ref_stack.back())
4573  {
4574  if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4575  {
4577  "excessive array size: " + std::to_string(len)));
4578  }
4579  }
4580 
4581  return true;
4582  }
4583 
4584  bool end_array()
4585  {
4586  bool keep = true;
4587 
4588  if (ref_stack.back())
4589  {
4590  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4591  if (not keep)
4592  {
4593  // discard array
4594  *ref_stack.back() = discarded;
4595  }
4596  }
4597 
4598  assert(not ref_stack.empty());
4599  assert(not keep_stack.empty());
4600  ref_stack.pop_back();
4601  keep_stack.pop_back();
4602 
4603  // remove discarded value
4604  if (not keep and not ref_stack.empty())
4605  {
4606  if (ref_stack.back()->is_array())
4607  {
4608  ref_stack.back()->m_value.array->pop_back();
4609  }
4610  }
4611 
4612  return true;
4613  }
4614 
4615  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4616  const detail::exception& ex)
4617  {
4618  errored = true;
4619  if (allow_exceptions)
4620  {
4621  // determine the proper exception type from the id
4622  switch ((ex.id / 100) % 100)
4623  {
4624  case 1:
4625  JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex));
4626  case 4:
4627  JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex));
4628  // LCOV_EXCL_START
4629  case 2:
4630  JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));
4631  case 3:
4632  JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));
4633  case 5:
4634  JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));
4635  default:
4636  assert(false);
4637  // LCOV_EXCL_STOP
4638  }
4639  }
4640  return false;
4641  }
4642 
4643  constexpr bool is_errored() const
4644  {
4645  return errored;
4646  }
4647 
4648  private:
4664  template<typename Value>
4665  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4666  {
4667  assert(not keep_stack.empty());
4668 
4669  // do not handle this value if we know it would be added to a discarded
4670  // container
4671  if (not keep_stack.back())
4672  {
4673  return {false, nullptr};
4674  }
4675 
4676  // create value
4677  auto value = BasicJsonType(std::forward<Value>(v));
4678 
4679  // check callback
4680  const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4681 
4682  // do not handle this value if we just learnt it shall be discarded
4683  if (not keep)
4684  {
4685  return {false, nullptr};
4686  }
4687 
4688  if (ref_stack.empty())
4689  {
4690  root = std::move(value);
4691  return {true, &root};
4692  }
4693 
4694  // skip this value if we already decided to skip the parent
4695  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4696  if (not ref_stack.back())
4697  {
4698  return {false, nullptr};
4699  }
4700 
4701  // we now only expect arrays and objects
4702  assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4703 
4704  if (ref_stack.back()->is_array())
4705  {
4706  ref_stack.back()->m_value.array->push_back(std::move(value));
4707  return {true, &(ref_stack.back()->m_value.array->back())};
4708  }
4709  else
4710  {
4711  // check if we should store an element for the current key
4712  assert(not key_keep_stack.empty());
4713  const bool store_element = key_keep_stack.back();
4714  key_keep_stack.pop_back();
4715 
4716  if (not store_element)
4717  {
4718  return {false, nullptr};
4719  }
4720 
4721  assert(object_element);
4722  *object_element = std::move(value);
4723  return {true, object_element};
4724  }
4725  }
4726 
4728  BasicJsonType& root;
4730  std::vector<BasicJsonType*> ref_stack;
4732  std::vector<bool> keep_stack;
4734  std::vector<bool> key_keep_stack;
4736  BasicJsonType* object_element = nullptr;
4738  bool errored = false;
4740  const parser_callback_t callback = nullptr;
4742  const bool allow_exceptions = true;
4744  BasicJsonType discarded = BasicJsonType::value_t::discarded;
4745 };
4746 
4747 template<typename BasicJsonType>
4749 {
4750  public:
4751  using number_integer_t = typename BasicJsonType::number_integer_t;
4752  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4753  using number_float_t = typename BasicJsonType::number_float_t;
4754  using string_t = typename BasicJsonType::string_t;
4755 
4756  bool null()
4757  {
4758  return true;
4759  }
4760 
4761  bool boolean(bool /*unused*/)
4762  {
4763  return true;
4764  }
4765 
4767  {
4768  return true;
4769  }
4770 
4772  {
4773  return true;
4774  }
4775 
4776  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
4777  {
4778  return true;
4779  }
4780 
4781  bool string(string_t& /*unused*/)
4782  {
4783  return true;
4784  }
4785 
4786  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
4787  {
4788  return true;
4789  }
4790 
4791  bool key(string_t& /*unused*/)
4792  {
4793  return true;
4794  }
4795 
4796  bool end_object()
4797  {
4798  return true;
4799  }
4800 
4801  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
4802  {
4803  return true;
4804  }
4805 
4806  bool end_array()
4807  {
4808  return true;
4809  }
4810 
4811  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
4812  {
4813  return false;
4814  }
4815 };
4816 } // namespace detail
4817 
4818 } // namespace nlohmann
4819 
4820 // #include <nlohmann/detail/input/lexer.hpp>
4821 
4822 // #include <nlohmann/detail/value_t.hpp>
4823 
4824 
4825 namespace nlohmann
4826 {
4827 namespace detail
4828 {
4830 // parser //
4832 
4838 template<typename BasicJsonType>
4839 class parser
4840 {
4841  using number_integer_t = typename BasicJsonType::number_integer_t;
4842  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4843  using number_float_t = typename BasicJsonType::number_float_t;
4844  using string_t = typename BasicJsonType::string_t;
4847 
4848  public:
4849  enum class parse_event_t : uint8_t
4850  {
4852  object_start,
4854  object_end,
4856  array_start,
4858  array_end,
4860  key,
4862  value
4863  };
4864 
4865  using parser_callback_t =
4866  std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
4867 
4869  explicit parser(detail::input_adapter_t&& adapter,
4870  const parser_callback_t cb = nullptr,
4871  const bool allow_exceptions_ = true)
4872  : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
4873  {
4874  // read first token
4875  get_token();
4876  }
4877 
4888  void parse(const bool strict, BasicJsonType& result)
4889  {
4890  if (callback)
4891  {
4892  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
4893  sax_parse_internal(&sdp);
4894  result.assert_invariant();
4895 
4896  // in strict mode, input must be completely read
4897  if (strict and (get_token() != token_type::end_of_input))
4898  {
4899  sdp.parse_error(m_lexer.get_position(),
4900  m_lexer.get_token_string(),
4901  parse_error::create(101, m_lexer.get_position(),
4902  exception_message(token_type::end_of_input, "value")));
4903  }
4904 
4905  // in case of an error, return discarded value
4906  if (sdp.is_errored())
4907  {
4908  result = value_t::discarded;
4909  return;
4910  }
4911 
4912  // set top-level value to null if it was discarded by the callback
4913  // function
4914  if (result.is_discarded())
4915  {
4916  result = nullptr;
4917  }
4918  }
4919  else
4920  {
4921  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
4922  sax_parse_internal(&sdp);
4923  result.assert_invariant();
4924 
4925  // in strict mode, input must be completely read
4926  if (strict and (get_token() != token_type::end_of_input))
4927  {
4928  sdp.parse_error(m_lexer.get_position(),
4929  m_lexer.get_token_string(),
4930  parse_error::create(101, m_lexer.get_position(),
4931  exception_message(token_type::end_of_input, "value")));
4932  }
4933 
4934  // in case of an error, return discarded value
4935  if (sdp.is_errored())
4936  {
4937  result = value_t::discarded;
4938  return;
4939  }
4940  }
4941  }
4942 
4949  bool accept(const bool strict = true)
4950  {
4951  json_sax_acceptor<BasicJsonType> sax_acceptor;
4952  return sax_parse(&sax_acceptor, strict);
4953  }
4954 
4955  template <typename SAX>
4956  bool sax_parse(SAX* sax, const bool strict = true)
4957  {
4959  const bool result = sax_parse_internal(sax);
4960 
4961  // strict mode: next byte must be EOF
4962  if (result and strict and (get_token() != token_type::end_of_input))
4963  {
4964  return sax->parse_error(m_lexer.get_position(),
4965  m_lexer.get_token_string(),
4966  parse_error::create(101, m_lexer.get_position(),
4967  exception_message(token_type::end_of_input, "value")));
4968  }
4969 
4970  return result;
4971  }
4972 
4973  private:
4974  template <typename SAX>
4975  bool sax_parse_internal(SAX* sax)
4976  {
4977  // stack to remember the hierarchy of structured values we are parsing
4978  // true = array; false = object
4979  std::vector<bool> states;
4980  // value to avoid a goto (see comment where set to true)
4981  bool skip_to_state_evaluation = false;
4982 
4983  while (true)
4984  {
4985  if (not skip_to_state_evaluation)
4986  {
4987  // invariant: get_token() was called before each iteration
4988  switch (last_token)
4989  {
4990  case token_type::begin_object:
4991  {
4992  if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
4993  {
4994  return false;
4995  }
4996 
4997  // closing } -> we are done
4998  if (get_token() == token_type::end_object)
4999  {
5000  if (JSON_UNLIKELY(not sax->end_object()))
5001  {
5002  return false;
5003  }
5004  break;
5005  }
5006 
5007  // parse key
5008  if (JSON_UNLIKELY(last_token != token_type::value_string))
5009  {
5010  return sax->parse_error(m_lexer.get_position(),
5011  m_lexer.get_token_string(),
5012  parse_error::create(101, m_lexer.get_position(),
5013  exception_message(token_type::value_string, "object key")));
5014  }
5015  if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
5016  {
5017  return false;
5018  }
5019 
5020  // parse separator (:)
5021  if (JSON_UNLIKELY(get_token() != token_type::name_separator))
5022  {
5023  return sax->parse_error(m_lexer.get_position(),
5024  m_lexer.get_token_string(),
5025  parse_error::create(101, m_lexer.get_position(),
5026  exception_message(token_type::name_separator, "object separator")));
5027  }
5028 
5029  // remember we are now inside an object
5030  states.push_back(false);
5031 
5032  // parse values
5033  get_token();
5034  continue;
5035  }
5036 
5037  case token_type::begin_array:
5038  {
5039  if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
5040  {
5041  return false;
5042  }
5043 
5044  // closing ] -> we are done
5045  if (get_token() == token_type::end_array)
5046  {
5047  if (JSON_UNLIKELY(not sax->end_array()))
5048  {
5049  return false;
5050  }
5051  break;
5052  }
5053 
5054  // remember we are now inside an array
5055  states.push_back(true);
5056 
5057  // parse values (no need to call get_token)
5058  continue;
5059  }
5060 
5061  case token_type::value_float:
5062  {
5063  const auto res = m_lexer.get_number_float();
5064 
5065  if (JSON_UNLIKELY(not std::isfinite(res)))
5066  {
5067  return sax->parse_error(m_lexer.get_position(),
5068  m_lexer.get_token_string(),
5069  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
5070  }
5071  else
5072  {
5073  if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
5074  {
5075  return false;
5076  }
5077  break;
5078  }
5079  }
5080 
5081  case token_type::literal_false:
5082  {
5083  if (JSON_UNLIKELY(not sax->boolean(false)))
5084  {
5085  return false;
5086  }
5087  break;
5088  }
5089 
5090  case token_type::literal_null:
5091  {
5092  if (JSON_UNLIKELY(not sax->null()))
5093  {
5094  return false;
5095  }
5096  break;
5097  }
5098 
5099  case token_type::literal_true:
5100  {
5101  if (JSON_UNLIKELY(not sax->boolean(true)))
5102  {
5103  return false;
5104  }
5105  break;
5106  }
5107 
5108  case token_type::value_integer:
5109  {
5110  if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
5111  {
5112  return false;
5113  }
5114  break;
5115  }
5116 
5117  case token_type::value_string:
5118  {
5119  if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
5120  {
5121  return false;
5122  }
5123  break;
5124  }
5125 
5126  case token_type::value_unsigned:
5127  {
5128  if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
5129  {
5130  return false;
5131  }
5132  break;
5133  }
5134 
5135  case token_type::parse_error:
5136  {
5137  // using "uninitialized" to avoid "expected" message
5138  return sax->parse_error(m_lexer.get_position(),
5139  m_lexer.get_token_string(),
5140  parse_error::create(101, m_lexer.get_position(),
5141  exception_message(token_type::uninitialized, "value")));
5142  }
5143 
5144  default: // the last token was unexpected
5145  {
5146  return sax->parse_error(m_lexer.get_position(),
5147  m_lexer.get_token_string(),
5148  parse_error::create(101, m_lexer.get_position(),
5149  exception_message(token_type::literal_or_value, "value")));
5150  }
5151  }
5152  }
5153  else
5154  {
5155  skip_to_state_evaluation = false;
5156  }
5157 
5158  // we reached this line after we successfully parsed a value
5159  if (states.empty())
5160  {
5161  // empty stack: we reached the end of the hierarchy: done
5162  return true;
5163  }
5164  else
5165  {
5166  if (states.back()) // array
5167  {
5168  // comma -> next value
5169  if (get_token() == token_type::value_separator)
5170  {
5171  // parse a new value
5172  get_token();
5173  continue;
5174  }
5175 
5176  // closing ]
5177  if (JSON_LIKELY(last_token == token_type::end_array))
5178  {
5179  if (JSON_UNLIKELY(not sax->end_array()))
5180  {
5181  return false;
5182  }
5183 
5184  // We are done with this array. Before we can parse a
5185  // new value, we need to evaluate the new state first.
5186  // By setting skip_to_state_evaluation to false, we
5187  // are effectively jumping to the beginning of this if.
5188  assert(not states.empty());
5189  states.pop_back();
5190  skip_to_state_evaluation = true;
5191  continue;
5192  }
5193  else
5194  {
5195  return sax->parse_error(m_lexer.get_position(),
5196  m_lexer.get_token_string(),
5197  parse_error::create(101, m_lexer.get_position(),
5198  exception_message(token_type::end_array, "array")));
5199  }
5200  }
5201  else // object
5202  {
5203  // comma -> next value
5204  if (get_token() == token_type::value_separator)
5205  {
5206  // parse key
5207  if (JSON_UNLIKELY(get_token() != token_type::value_string))
5208  {
5209  return sax->parse_error(m_lexer.get_position(),
5210  m_lexer.get_token_string(),
5211  parse_error::create(101, m_lexer.get_position(),
5212  exception_message(token_type::value_string, "object key")));
5213  }
5214  else
5215  {
5216  if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
5217  {
5218  return false;
5219  }
5220  }
5221 
5222  // parse separator (:)
5223  if (JSON_UNLIKELY(get_token() != token_type::name_separator))
5224  {
5225  return sax->parse_error(m_lexer.get_position(),
5226  m_lexer.get_token_string(),
5227  parse_error::create(101, m_lexer.get_position(),
5228  exception_message(token_type::name_separator, "object separator")));
5229  }
5230 
5231  // parse values
5232  get_token();
5233  continue;
5234  }
5235 
5236  // closing }
5237  if (JSON_LIKELY(last_token == token_type::end_object))
5238  {
5239  if (JSON_UNLIKELY(not sax->end_object()))
5240  {
5241  return false;
5242  }
5243 
5244  // We are done with this object. Before we can parse a
5245  // new value, we need to evaluate the new state first.
5246  // By setting skip_to_state_evaluation to false, we
5247  // are effectively jumping to the beginning of this if.
5248  assert(not states.empty());
5249  states.pop_back();
5250  skip_to_state_evaluation = true;
5251  continue;
5252  }
5253  else
5254  {
5255  return sax->parse_error(m_lexer.get_position(),
5256  m_lexer.get_token_string(),
5257  parse_error::create(101, m_lexer.get_position(),
5258  exception_message(token_type::end_object, "object")));
5259  }
5260  }
5261  }
5262  }
5263  }
5264 
5267  {
5268  return (last_token = m_lexer.scan());
5269  }
5270 
5271  std::string exception_message(const token_type expected, const std::string& context)
5272  {
5273  std::string error_msg = "syntax error ";
5274 
5275  if (not context.empty())
5276  {
5277  error_msg += "while parsing " + context + " ";
5278  }
5279 
5280  error_msg += "- ";
5281 
5282  if (last_token == token_type::parse_error)
5283  {
5284  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
5285  m_lexer.get_token_string() + "'";
5286  }
5287  else
5288  {
5289  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
5290  }
5291 
5292  if (expected != token_type::uninitialized)
5293  {
5294  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
5295  }
5296 
5297  return error_msg;
5298  }
5299 
5300  private:
5302  const parser_callback_t callback = nullptr;
5304  token_type last_token = token_type::uninitialized;
5308  const bool allow_exceptions = true;
5309 };
5310 } // namespace detail
5311 } // namespace nlohmann
5312 
5313 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5314 
5315 
5316 #include <cstddef> // ptrdiff_t
5317 #include <limits> // numeric_limits
5318 
5319 namespace nlohmann
5320 {
5321 namespace detail
5322 {
5323 /*
5324 @brief an iterator for primitive JSON types
5325 
5326 This class models an iterator for primitive JSON types (boolean, number,
5327 string). It's only purpose is to allow the iterator/const_iterator classes
5328 to "iterate" over primitive values. Internally, the iterator is modeled by
5329 a `difference_type` variable. Value begin_value (`0`) models the begin,
5330 end_value (`1`) models past the end.
5331 */
5333 {
5334  private:
5335  using difference_type = std::ptrdiff_t;
5336  static constexpr difference_type begin_value = 0;
5337  static constexpr difference_type end_value = begin_value + 1;
5338 
5341 
5342  public:
5343  constexpr difference_type get_value() const noexcept
5344  {
5345  return m_it;
5346  }
5347 
5349  void set_begin() noexcept
5350  {
5351  m_it = begin_value;
5352  }
5353 
5355  void set_end() noexcept
5356  {
5357  m_it = end_value;
5358  }
5359 
5361  constexpr bool is_begin() const noexcept
5362  {
5363  return m_it == begin_value;
5364  }
5365 
5367  constexpr bool is_end() const noexcept
5368  {
5369  return m_it == end_value;
5370  }
5371 
5372  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5373  {
5374  return lhs.m_it == rhs.m_it;
5375  }
5376 
5377  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
5378  {
5379  return lhs.m_it < rhs.m_it;
5380  }
5381 
5383  {
5384  auto result = *this;
5385  result += n;
5386  return result;
5387  }
5388 
5390  {
5391  return lhs.m_it - rhs.m_it;
5392  }
5393 
5395  {
5396  ++m_it;
5397  return *this;
5398  }
5399 
5400  primitive_iterator_t const operator++(int) noexcept
5401  {
5402  auto result = *this;
5403  ++m_it;
5404  return result;
5405  }
5406 
5408  {
5409  --m_it;
5410  return *this;
5411  }
5412 
5413  primitive_iterator_t const operator--(int) noexcept
5414  {
5415  auto result = *this;
5416  --m_it;
5417  return result;
5418  }
5419 
5421  {
5422  m_it += n;
5423  return *this;
5424  }
5425 
5427  {
5428  m_it -= n;
5429  return *this;
5430  }
5431 };
5432 } // namespace detail
5433 } // namespace nlohmann
5434 
5435 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5436 
5437 
5438 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5439 
5440 
5441 namespace nlohmann
5442 {
5443 namespace detail
5444 {
5451 template<typename BasicJsonType> struct internal_iterator
5452 {
5454  typename BasicJsonType::object_t::iterator object_iterator {};
5456  typename BasicJsonType::array_t::iterator array_iterator {};
5458  primitive_iterator_t primitive_iterator {};
5459 };
5460 } // namespace detail
5461 } // namespace nlohmann
5462 
5463 // #include <nlohmann/detail/iterators/iter_impl.hpp>
5464 
5465 
5466 #include <ciso646> // not
5467 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
5468 #include <type_traits> // conditional, is_const, remove_const
5469 
5470 // #include <nlohmann/detail/exceptions.hpp>
5471 
5472 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
5473 
5474 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
5475 
5476 // #include <nlohmann/detail/macro_scope.hpp>
5477 
5478 // #include <nlohmann/detail/meta/cpp_future.hpp>
5479 
5480 // #include <nlohmann/detail/value_t.hpp>
5481 
5482 
5483 namespace nlohmann
5484 {
5485 namespace detail
5486 {
5487 // forward declare, to be able to friend it later on
5488 template<typename IteratorType> class iteration_proxy;
5489 
5510 template<typename BasicJsonType>
5512 {
5514  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
5517 
5518  using object_t = typename BasicJsonType::object_t;
5519  using array_t = typename BasicJsonType::array_t;
5520  // make sure BasicJsonType is basic_json or const basic_json
5521  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
5522  "iter_impl only accepts (const) basic_json");
5523 
5524  public:
5525 
5531  using iterator_category = std::bidirectional_iterator_tag;
5532 
5534  using value_type = typename BasicJsonType::value_type;
5536  using difference_type = typename BasicJsonType::difference_type;
5539  typename BasicJsonType::const_pointer,
5540  typename BasicJsonType::pointer>::type;
5542  using reference =
5544  typename BasicJsonType::const_reference,
5545  typename BasicJsonType::reference>::type;
5546 
5548  iter_impl() = default;
5549 
5556  explicit iter_impl(pointer object) noexcept : m_object(object)
5557  {
5558  assert(m_object != nullptr);
5559 
5560  switch (m_object->m_type)
5561  {
5562  case value_t::object:
5563  {
5564  m_it.object_iterator = typename object_t::iterator();
5565  break;
5566  }
5567 
5568  case value_t::array:
5569  {
5570  m_it.array_iterator = typename array_t::iterator();
5571  break;
5572  }
5573 
5574  default:
5575  {
5576  m_it.primitive_iterator = primitive_iterator_t();
5577  break;
5578  }
5579  }
5580  }
5581 
5596  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5597  : m_object(other.m_object), m_it(other.m_it) {}
5598 
5605  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
5606  {
5607  m_object = other.m_object;
5608  m_it = other.m_it;
5609  return *this;
5610  }
5611 
5612  private:
5617  void set_begin() noexcept
5618  {
5619  assert(m_object != nullptr);
5620 
5621  switch (m_object->m_type)
5622  {
5623  case value_t::object:
5624  {
5625  m_it.object_iterator = m_object->m_value.object->begin();
5626  break;
5627  }
5628 
5629  case value_t::array:
5630  {
5631  m_it.array_iterator = m_object->m_value.array->begin();
5632  break;
5633  }
5634 
5635  case value_t::null:
5636  {
5637  // set to end so begin()==end() is true: null is empty
5638  m_it.primitive_iterator.set_end();
5639  break;
5640  }
5641 
5642  default:
5643  {
5644  m_it.primitive_iterator.set_begin();
5645  break;
5646  }
5647  }
5648  }
5649 
5654  void set_end() noexcept
5655  {
5656  assert(m_object != nullptr);
5657 
5658  switch (m_object->m_type)
5659  {
5660  case value_t::object:
5661  {
5662  m_it.object_iterator = m_object->m_value.object->end();
5663  break;
5664  }
5665 
5666  case value_t::array:
5667  {
5668  m_it.array_iterator = m_object->m_value.array->end();
5669  break;
5670  }
5671 
5672  default:
5673  {
5674  m_it.primitive_iterator.set_end();
5675  break;
5676  }
5677  }
5678  }
5679 
5680  public:
5686  {
5687  assert(m_object != nullptr);
5688 
5689  switch (m_object->m_type)
5690  {
5691  case value_t::object:
5692  {
5693  assert(m_it.object_iterator != m_object->m_value.object->end());
5694  return m_it.object_iterator->second;
5695  }
5696 
5697  case value_t::array:
5698  {
5699  assert(m_it.array_iterator != m_object->m_value.array->end());
5700  return *m_it.array_iterator;
5701  }
5702 
5703  case value_t::null:
5704  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5705 
5706  default:
5707  {
5708  if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5709  {
5710  return *m_object;
5711  }
5712 
5713  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5714  }
5715  }
5716  }
5717 
5723  {
5724  assert(m_object != nullptr);
5725 
5726  switch (m_object->m_type)
5727  {
5728  case value_t::object:
5729  {
5730  assert(m_it.object_iterator != m_object->m_value.object->end());
5731  return &(m_it.object_iterator->second);
5732  }
5733 
5734  case value_t::array:
5735  {
5736  assert(m_it.array_iterator != m_object->m_value.array->end());
5737  return &*m_it.array_iterator;
5738  }
5739 
5740  default:
5741  {
5742  if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
5743  {
5744  return m_object;
5745  }
5746 
5747  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
5748  }
5749  }
5750  }
5751 
5757  {
5758  auto result = *this;
5759  ++(*this);
5760  return result;
5761  }
5762 
5768  {
5769  assert(m_object != nullptr);
5770 
5771  switch (m_object->m_type)
5772  {
5773  case value_t::object:
5774  {
5775  std::advance(m_it.object_iterator, 1);
5776  break;
5777  }
5778 
5779  case value_t::array:
5780  {
5781  std::advance(m_it.array_iterator, 1);
5782  break;
5783  }
5784 
5785  default:
5786  {
5787  ++m_it.primitive_iterator;
5788  break;
5789  }
5790  }
5791 
5792  return *this;
5793  }
5794 
5800  {
5801  auto result = *this;
5802  --(*this);
5803  return result;
5804  }
5805 
5811  {
5812  assert(m_object != nullptr);
5813 
5814  switch (m_object->m_type)
5815  {
5816  case value_t::object:
5817  {
5818  std::advance(m_it.object_iterator, -1);
5819  break;
5820  }
5821 
5822  case value_t::array:
5823  {
5824  std::advance(m_it.array_iterator, -1);
5825  break;
5826  }
5827 
5828  default:
5829  {
5830  --m_it.primitive_iterator;
5831  break;
5832  }
5833  }
5834 
5835  return *this;
5836  }
5837 
5842  bool operator==(const iter_impl& other) const
5843  {
5844  // if objects are not the same, the comparison is undefined
5845  if (JSON_UNLIKELY(m_object != other.m_object))
5846  {
5847  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5848  }
5849 
5850  assert(m_object != nullptr);
5851 
5852  switch (m_object->m_type)
5853  {
5854  case value_t::object:
5855  return (m_it.object_iterator == other.m_it.object_iterator);
5856 
5857  case value_t::array:
5858  return (m_it.array_iterator == other.m_it.array_iterator);
5859 
5860  default:
5861  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
5862  }
5863  }
5864 
5869  bool operator!=(const iter_impl& other) const
5870  {
5871  return not operator==(other);
5872  }
5873 
5878  bool operator<(const iter_impl& other) const
5879  {
5880  // if objects are not the same, the comparison is undefined
5881  if (JSON_UNLIKELY(m_object != other.m_object))
5882  {
5883  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
5884  }
5885 
5886  assert(m_object != nullptr);
5887 
5888  switch (m_object->m_type)
5889  {
5890  case value_t::object:
5891  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
5892 
5893  case value_t::array:
5894  return (m_it.array_iterator < other.m_it.array_iterator);
5895 
5896  default:
5897  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
5898  }
5899  }
5900 
5905  bool operator<=(const iter_impl& other) const
5906  {
5907  return not other.operator < (*this);
5908  }
5909 
5914  bool operator>(const iter_impl& other) const
5915  {
5916  return not operator<=(other);
5917  }
5918 
5923  bool operator>=(const iter_impl& other) const
5924  {
5925  return not operator<(other);
5926  }
5927 
5933  {
5934  assert(m_object != nullptr);
5935 
5936  switch (m_object->m_type)
5937  {
5938  case value_t::object:
5939  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
5940 
5941  case value_t::array:
5942  {
5943  std::advance(m_it.array_iterator, i);
5944  break;
5945  }
5946 
5947  default:
5948  {
5949  m_it.primitive_iterator += i;
5950  break;
5951  }
5952  }
5953 
5954  return *this;
5955  }
5956 
5962  {
5963  return operator+=(-i);
5964  }
5965 
5971  {
5972  auto result = *this;
5973  result += i;
5974  return result;
5975  }
5976 
5982  {
5983  auto result = it;
5984  result += i;
5985  return result;
5986  }
5987 
5993  {
5994  auto result = *this;
5995  result -= i;
5996  return result;
5997  }
5998 
6004  {
6005  assert(m_object != nullptr);
6006 
6007  switch (m_object->m_type)
6008  {
6009  case value_t::object:
6010  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
6011 
6012  case value_t::array:
6013  return m_it.array_iterator - other.m_it.array_iterator;
6014 
6015  default:
6016  return m_it.primitive_iterator - other.m_it.primitive_iterator;
6017  }
6018  }
6019 
6025  {
6026  assert(m_object != nullptr);
6027 
6028  switch (m_object->m_type)
6029  {
6030  case value_t::object:
6031  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
6032 
6033  case value_t::array:
6034  return *std::next(m_it.array_iterator, n);
6035 
6036  case value_t::null:
6037  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
6038 
6039  default:
6040  {
6041  if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
6042  {
6043  return *m_object;
6044  }
6045 
6046  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
6047  }
6048  }
6049  }
6050 
6055  const typename object_t::key_type& key() const
6056  {
6057  assert(m_object != nullptr);
6058 
6059  if (JSON_LIKELY(m_object->is_object()))
6060  {
6061  return m_it.object_iterator->first;
6062  }
6063 
6064  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
6065  }
6066 
6072  {
6073  return operator*();
6074  }
6075 
6076  private:
6078  pointer m_object = nullptr;
6081 };
6082 } // namespace detail
6083 } // namespace nlohmann
6084 
6085 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
6086 
6087 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
6088 
6089 
6090 #include <cstddef> // ptrdiff_t
6091 #include <iterator> // reverse_iterator
6092 #include <utility> // declval
6093 
6094 namespace nlohmann
6095 {
6096 namespace detail
6097 {
6099 // reverse_iterator //
6101 
6120 template<typename Base>
6121 class json_reverse_iterator : public std::reverse_iterator<Base>
6122 {
6123  public:
6124  using difference_type = std::ptrdiff_t;
6126  using base_iterator = std::reverse_iterator<Base>;
6128  using reference = typename Base::reference;
6129 
6131  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
6132  : base_iterator(it) {}
6133 
6135  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
6136 
6139  {
6140  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
6141  }
6142 
6145  {
6146  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
6147  }
6148 
6151  {
6152  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
6153  }
6154 
6157  {
6158  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
6159  }
6160 
6163  {
6164  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
6165  }
6166 
6169  {
6170  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
6171  }
6172 
6175  {
6176  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
6177  }
6178 
6181  {
6182  return base_iterator(*this) - base_iterator(other);
6183  }
6184 
6187  {
6188  return *(this->operator+(n));
6189  }
6190 
6192  auto key() const -> decltype(std::declval<Base>().key())
6193  {
6194  auto it = --this->base();
6195  return it.key();
6196  }
6197 
6200  {
6201  auto it = --this->base();
6202  return it.operator * ();
6203  }
6204 };
6205 } // namespace detail
6206 } // namespace nlohmann
6207 
6208 // #include <nlohmann/detail/output/output_adapters.hpp>
6209 
6210 
6211 #include <algorithm> // copy
6212 #include <cstddef> // size_t
6213 #include <ios> // streamsize
6214 #include <iterator> // back_inserter
6215 #include <memory> // shared_ptr, make_shared
6216 #include <ostream> // basic_ostream
6217 #include <string> // basic_string
6218 #include <vector> // vector
6219 
6220 namespace nlohmann
6221 {
6222 namespace detail
6223 {
6225 template<typename CharType> struct output_adapter_protocol
6226 {
6227  virtual void write_character(CharType c) = 0;
6228  virtual void write_characters(const CharType* s, std::size_t length) = 0;
6229  virtual ~output_adapter_protocol() = default;
6230 };
6231 
6233 template<typename CharType>
6234 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
6235 
6237 template<typename CharType>
6239 {
6240  public:
6241  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
6242  : v(vec)
6243  {}
6244 
6245  void write_character(CharType c) override
6246  {
6247  v.push_back(c);
6248  }
6249 
6250  void write_characters(const CharType* s, std::size_t length) override
6251  {
6252  std::copy(s, s + length, std::back_inserter(v));
6253  }
6254 
6255  private:
6256  std::vector<CharType>& v;
6257 };
6258 
6260 template<typename CharType>
6262 {
6263  public:
6264  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
6265  : stream(s)
6266  {}
6267 
6268  void write_character(CharType c) override
6269  {
6270  stream.put(c);
6271  }
6272 
6273  void write_characters(const CharType* s, std::size_t length) override
6274  {
6275  stream.write(s, static_cast<std::streamsize>(length));
6276  }
6277 
6278  private:
6279  std::basic_ostream<CharType>& stream;
6280 };
6281 
6283 template<typename CharType, typename StringType = std::basic_string<CharType>>
6285 {
6286  public:
6287  explicit output_string_adapter(StringType& s) noexcept
6288  : str(s)
6289  {}
6290 
6291  void write_character(CharType c) override
6292  {
6293  str.push_back(c);
6294  }
6295 
6296  void write_characters(const CharType* s, std::size_t length) override
6297  {
6298  str.append(s, length);
6299  }
6300 
6301  private:
6302  StringType& str;
6303 };
6304 
6305 template<typename CharType, typename StringType = std::basic_string<CharType>>
6307 {
6308  public:
6309  output_adapter(std::vector<CharType>& vec)
6310  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
6311 
6312  output_adapter(std::basic_ostream<CharType>& s)
6313  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
6314 
6315  output_adapter(StringType& s)
6316  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
6317 
6319  {
6320  return oa;
6321  }
6322 
6323  private:
6325 };
6326 } // namespace detail
6327 } // namespace nlohmann
6328 
6329 // #include <nlohmann/detail/input/binary_reader.hpp>
6330 
6331 
6332 #include <algorithm> // generate_n
6333 #include <array> // array
6334 #include <cassert> // assert
6335 #include <cmath> // ldexp
6336 #include <cstddef> // size_t
6337 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6338 #include <cstdio> // snprintf
6339 #include <cstring> // memcpy
6340 #include <iterator> // back_inserter
6341 #include <limits> // numeric_limits
6342 #include <string> // char_traits, string
6343 #include <utility> // make_pair, move
6344 
6345 // #include <nlohmann/detail/input/input_adapters.hpp>
6346 
6347 // #include <nlohmann/detail/input/json_sax.hpp>
6348 
6349 // #include <nlohmann/detail/exceptions.hpp>
6350 
6351 // #include <nlohmann/detail/macro_scope.hpp>
6352 
6353 // #include <nlohmann/detail/meta/is_sax.hpp>
6354 
6355 // #include <nlohmann/detail/value_t.hpp>
6356 
6357 
6358 namespace nlohmann
6359 {
6360 namespace detail
6361 {
6363 // binary reader //
6365 
6369 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
6371 {
6372  using number_integer_t = typename BasicJsonType::number_integer_t;
6373  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6374  using number_float_t = typename BasicJsonType::number_float_t;
6375  using string_t = typename BasicJsonType::string_t;
6376  using json_sax_t = SAX;
6377 
6378  public:
6384  explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
6385  {
6387  assert(ia);
6388  }
6389 
6397  bool sax_parse(const input_format_t format,
6398  json_sax_t* sax_,
6399  const bool strict = true)
6400  {
6401  sax = sax_;
6402  bool result = false;
6403 
6404  switch (format)
6405  {
6406  case input_format_t::bson:
6407  result = parse_bson_internal();
6408  break;
6409 
6410  case input_format_t::cbor:
6411  result = parse_cbor_internal();
6412  break;
6413 
6415  result = parse_msgpack_internal();
6416  break;
6417 
6419  result = parse_ubjson_internal();
6420  break;
6421 
6422  // LCOV_EXCL_START
6423  default:
6424  assert(false);
6425  // LCOV_EXCL_STOP
6426  }
6427 
6428  // strict mode: next byte must be EOF
6429  if (result and strict)
6430  {
6431  if (format == input_format_t::ubjson)
6432  {
6433  get_ignore_noop();
6434  }
6435  else
6436  {
6437  get();
6438  }
6439 
6440  if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
6441  {
6442  return sax->parse_error(chars_read, get_token_string(),
6443  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
6444  }
6445  }
6446 
6447  return result;
6448  }
6449 
6457  static constexpr bool little_endianess(int num = 1) noexcept
6458  {
6459  return (*reinterpret_cast<char*>(&num) == 1);
6460  }
6461 
6462  private:
6464  // BSON //
6466 
6472  {
6473  std::int32_t document_size;
6474  get_number<std::int32_t, true>(input_format_t::bson, document_size);
6475 
6476  if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
6477  {
6478  return false;
6479  }
6480 
6481  if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
6482  {
6483  return false;
6484  }
6485 
6486  return sax->end_object();
6487  }
6488 
6496  bool get_bson_cstr(string_t& result)
6497  {
6498  auto out = std::back_inserter(result);
6499  while (true)
6500  {
6501  get();
6502  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
6503  {
6504  return false;
6505  }
6506  if (current == 0x00)
6507  {
6508  return true;
6509  }
6510  *out++ = static_cast<char>(current);
6511  }
6512 
6513  return true;
6514  }
6515 
6527  template<typename NumberType>
6528  bool get_bson_string(const NumberType len, string_t& result)
6529  {
6530  if (JSON_UNLIKELY(len < 1))
6531  {
6532  auto last_token = get_token_string();
6533  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
6534  }
6535 
6536  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
6537  }
6538 
6549  bool parse_bson_element_internal(const int element_type,
6550  const std::size_t element_type_parse_position)
6551  {
6552  switch (element_type)
6553  {
6554  case 0x01: // double
6555  {
6556  double number;
6557  return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6558  }
6559 
6560  case 0x02: // string
6561  {
6562  std::int32_t len;
6563  string_t value;
6564  return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6565  }
6566 
6567  case 0x03: // object
6568  {
6569  return parse_bson_internal();
6570  }
6571 
6572  case 0x04: // array
6573  {
6574  return parse_bson_array();
6575  }
6576 
6577  case 0x08: // boolean
6578  {
6579  return sax->boolean(static_cast<bool>(get()));
6580  }
6581 
6582  case 0x0A: // null
6583  {
6584  return sax->null();
6585  }
6586 
6587  case 0x10: // int32
6588  {
6589  std::int32_t value;
6590  return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6591  }
6592 
6593  case 0x12: // int64
6594  {
6595  std::int64_t value;
6596  return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6597  }
6598 
6599  default: // anything else not supported (yet)
6600  {
6601  char cr[3];
6602  snprintf(cr, sizeof(cr), "%.2hhX", static_cast<unsigned char>(element_type));
6603  return sax->parse_error(element_type_parse_position, std::string(cr), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr)));
6604  }
6605  }
6606  }
6607 
6620  bool parse_bson_element_list(const bool is_array)
6621  {
6622  string_t key;
6623  while (int element_type = get())
6624  {
6625  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
6626  {
6627  return false;
6628  }
6629 
6630  const std::size_t element_type_parse_position = chars_read;
6631  if (JSON_UNLIKELY(not get_bson_cstr(key)))
6632  {
6633  return false;
6634  }
6635 
6636  if (not is_array)
6637  {
6638  sax->key(key);
6639  }
6640 
6641  if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6642  {
6643  return false;
6644  }
6645 
6646  // get_bson_cstr only appends
6647  key.clear();
6648  }
6649 
6650  return true;
6651  }
6652 
6658  {
6659  std::int32_t document_size;
6660  get_number<std::int32_t, true>(input_format_t::bson, document_size);
6661 
6662  if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
6663  {
6664  return false;
6665  }
6666 
6667  if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
6668  {
6669  return false;
6670  }
6671 
6672  return sax->end_array();
6673  }
6674 
6676  // CBOR //
6678 
6686  bool parse_cbor_internal(const bool get_char = true)
6687  {
6688  switch (get_char ? get() : current)
6689  {
6690  // EOF
6691  case std::char_traits<char>::eof():
6692  return unexpect_eof(input_format_t::cbor, "value");
6693 
6694  // Integer 0x00..0x17 (0..23)
6695  case 0x00:
6696  case 0x01:
6697  case 0x02:
6698  case 0x03:
6699  case 0x04:
6700  case 0x05:
6701  case 0x06:
6702  case 0x07:
6703  case 0x08:
6704  case 0x09:
6705  case 0x0A:
6706  case 0x0B:
6707  case 0x0C:
6708  case 0x0D:
6709  case 0x0E:
6710  case 0x0F:
6711  case 0x10:
6712  case 0x11:
6713  case 0x12:
6714  case 0x13:
6715  case 0x14:
6716  case 0x15:
6717  case 0x16:
6718  case 0x17:
6719  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6720 
6721  case 0x18: // Unsigned integer (one-byte uint8_t follows)
6722  {
6723  uint8_t number;
6724  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6725  }
6726 
6727  case 0x19: // Unsigned integer (two-byte uint16_t follows)
6728  {
6729  uint16_t number;
6730  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6731  }
6732 
6733  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6734  {
6735  uint32_t number;
6736  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6737  }
6738 
6739  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6740  {
6741  uint64_t number;
6742  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6743  }
6744 
6745  // Negative integer -1-0x00..-1-0x17 (-1..-24)
6746  case 0x20:
6747  case 0x21:
6748  case 0x22:
6749  case 0x23:
6750  case 0x24:
6751  case 0x25:
6752  case 0x26:
6753  case 0x27:
6754  case 0x28:
6755  case 0x29:
6756  case 0x2A:
6757  case 0x2B:
6758  case 0x2C:
6759  case 0x2D:
6760  case 0x2E:
6761  case 0x2F:
6762  case 0x30:
6763  case 0x31:
6764  case 0x32:
6765  case 0x33:
6766  case 0x34:
6767  case 0x35:
6768  case 0x36:
6769  case 0x37:
6770  return sax->number_integer(static_cast<int8_t>(0x20 - 1 - current));
6771 
6772  case 0x38: // Negative integer (one-byte uint8_t follows)
6773  {
6774  uint8_t number;
6775  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6776  }
6777 
6778  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6779  {
6780  uint16_t number;
6781  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6782  }
6783 
6784  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6785  {
6786  uint32_t number;
6787  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6788  }
6789 
6790  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6791  {
6792  uint64_t number;
6793  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6794  - static_cast<number_integer_t>(number));
6795  }
6796 
6797  // UTF-8 string (0x00..0x17 bytes follow)
6798  case 0x60:
6799  case 0x61:
6800  case 0x62:
6801  case 0x63:
6802  case 0x64:
6803  case 0x65:
6804  case 0x66:
6805  case 0x67:
6806  case 0x68:
6807  case 0x69:
6808  case 0x6A:
6809  case 0x6B:
6810  case 0x6C:
6811  case 0x6D:
6812  case 0x6E:
6813  case 0x6F:
6814  case 0x70:
6815  case 0x71:
6816  case 0x72:
6817  case 0x73:
6818  case 0x74:
6819  case 0x75:
6820  case 0x76:
6821  case 0x77:
6822  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6823  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6824  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6825  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6826  case 0x7F: // UTF-8 string (indefinite length)
6827  {
6828  string_t s;
6829  return get_cbor_string(s) and sax->string(s);
6830  }
6831 
6832  // array (0x00..0x17 data items follow)
6833  case 0x80:
6834  case 0x81:
6835  case 0x82:
6836  case 0x83:
6837  case 0x84:
6838  case 0x85:
6839  case 0x86:
6840  case 0x87:
6841  case 0x88:
6842  case 0x89:
6843  case 0x8A:
6844  case 0x8B:
6845  case 0x8C:
6846  case 0x8D:
6847  case 0x8E:
6848  case 0x8F:
6849  case 0x90:
6850  case 0x91:
6851  case 0x92:
6852  case 0x93:
6853  case 0x94:
6854  case 0x95:
6855  case 0x96:
6856  case 0x97:
6857  return get_cbor_array(static_cast<std::size_t>(current & 0x1F));
6858 
6859  case 0x98: // array (one-byte uint8_t for n follows)
6860  {
6861  uint8_t len;
6862  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6863  }
6864 
6865  case 0x99: // array (two-byte uint16_t for n follow)
6866  {
6867  uint16_t len;
6868  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6869  }
6870 
6871  case 0x9A: // array (four-byte uint32_t for n follow)
6872  {
6873  uint32_t len;
6874  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6875  }
6876 
6877  case 0x9B: // array (eight-byte uint64_t for n follow)
6878  {
6879  uint64_t len;
6880  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6881  }
6882 
6883  case 0x9F: // array (indefinite length)
6884  return get_cbor_array(std::size_t(-1));
6885 
6886  // map (0x00..0x17 pairs of data items follow)
6887  case 0xA0:
6888  case 0xA1:
6889  case 0xA2:
6890  case 0xA3:
6891  case 0xA4:
6892  case 0xA5:
6893  case 0xA6:
6894  case 0xA7:
6895  case 0xA8:
6896  case 0xA9:
6897  case 0xAA:
6898  case 0xAB:
6899  case 0xAC:
6900  case 0xAD:
6901  case 0xAE:
6902  case 0xAF:
6903  case 0xB0:
6904  case 0xB1:
6905  case 0xB2:
6906  case 0xB3:
6907  case 0xB4:
6908  case 0xB5:
6909  case 0xB6:
6910  case 0xB7:
6911  return get_cbor_object(static_cast<std::size_t>(current & 0x1F));
6912 
6913  case 0xB8: // map (one-byte uint8_t for n follows)
6914  {
6915  uint8_t len;
6916  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6917  }
6918 
6919  case 0xB9: // map (two-byte uint16_t for n follow)
6920  {
6921  uint16_t len;
6922  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6923  }
6924 
6925  case 0xBA: // map (four-byte uint32_t for n follow)
6926  {
6927  uint32_t len;
6928  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6929  }
6930 
6931  case 0xBB: // map (eight-byte uint64_t for n follow)
6932  {
6933  uint64_t len;
6934  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6935  }
6936 
6937  case 0xBF: // map (indefinite length)
6938  return get_cbor_object(std::size_t(-1));
6939 
6940  case 0xF4: // false
6941  return sax->boolean(false);
6942 
6943  case 0xF5: // true
6944  return sax->boolean(true);
6945 
6946  case 0xF6: // null
6947  return sax->null();
6948 
6949  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6950  {
6951  const int byte1_raw = get();
6952  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6953  {
6954  return false;
6955  }
6956  const int byte2_raw = get();
6957  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6958  {
6959  return false;
6960  }
6961 
6962  const auto byte1 = static_cast<unsigned char>(byte1_raw);
6963  const auto byte2 = static_cast<unsigned char>(byte2_raw);
6964 
6965  // code from RFC 7049, Appendix D, Figure 3:
6966  // As half-precision floating-point numbers were only added
6967  // to IEEE 754 in 2008, today's programming platforms often
6968  // still only have limited support for them. It is very
6969  // easy to include at least decoding support for them even
6970  // without such support. An example of a small decoder for
6971  // half-precision floating-point numbers in the C language
6972  // is shown in Fig. 3.
6973  const int half = (byte1 << 8) + byte2;
6974  const double val = [&half]
6975  {
6976  const int exp = (half >> 10) & 0x1F;
6977  const int mant = half & 0x3FF;
6978  assert(0 <= exp and exp <= 32);
6979  assert(0 <= mant and mant <= 1024);
6980  switch (exp)
6981  {
6982  case 0:
6983  return std::ldexp(mant, -24);
6984  case 31:
6985  return (mant == 0)
6986  ? std::numeric_limits<double>::infinity()
6987  : std::numeric_limits<double>::quiet_NaN();
6988  default:
6989  return std::ldexp(mant + 1024, exp - 25);
6990  }
6991  }();
6992  return sax->number_float((half & 0x8000) != 0
6993  ? static_cast<number_float_t>(-val)
6994  : static_cast<number_float_t>(val), "");
6995  }
6996 
6997  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6998  {
6999  float number;
7000  return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
7001  }
7002 
7003  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
7004  {
7005  double number;
7006  return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
7007  }
7008 
7009  default: // anything else (0xFF is handled inside the other types)
7010  {
7011  auto last_token = get_token_string();
7012  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
7013  }
7014  }
7015  }
7016 
7029  {
7030  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
7031  {
7032  return false;
7033  }
7034 
7035  switch (current)
7036  {
7037  // UTF-8 string (0x00..0x17 bytes follow)
7038  case 0x60:
7039  case 0x61:
7040  case 0x62:
7041  case 0x63:
7042  case 0x64:
7043  case 0x65:
7044  case 0x66:
7045  case 0x67:
7046  case 0x68:
7047  case 0x69:
7048  case 0x6A:
7049  case 0x6B:
7050  case 0x6C:
7051  case 0x6D:
7052  case 0x6E:
7053  case 0x6F:
7054  case 0x70:
7055  case 0x71:
7056  case 0x72:
7057  case 0x73:
7058  case 0x74:
7059  case 0x75:
7060  case 0x76:
7061  case 0x77:
7062  {
7063  return get_string(input_format_t::cbor, current & 0x1F, result);
7064  }
7065 
7066  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
7067  {
7068  uint8_t len;
7069  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7070  }
7071 
7072  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
7073  {
7074  uint16_t len;
7075  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7076  }
7077 
7078  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
7079  {
7080  uint32_t len;
7081  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7082  }
7083 
7084  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
7085  {
7086  uint64_t len;
7087  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
7088  }
7089 
7090  case 0x7F: // UTF-8 string (indefinite length)
7091  {
7092  while (get() != 0xFF)
7093  {
7094  string_t chunk;
7095  if (not get_cbor_string(chunk))
7096  {
7097  return false;
7098  }
7099  result.append(chunk);
7100  }
7101  return true;
7102  }
7103 
7104  default:
7105  {
7106  auto last_token = get_token_string();
7107  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
7108  }
7109  }
7110  }
7111 
7117  bool get_cbor_array(const std::size_t len)
7118  {
7119  if (JSON_UNLIKELY(not sax->start_array(len)))
7120  {
7121  return false;
7122  }
7123 
7124  if (len != std::size_t(-1))
7125  {
7126  for (std::size_t i = 0; i < len; ++i)
7127  {
7128  if (JSON_UNLIKELY(not parse_cbor_internal()))
7129  {
7130  return false;
7131  }
7132  }
7133  }
7134  else
7135  {
7136  while (get() != 0xFF)
7137  {
7138  if (JSON_UNLIKELY(not parse_cbor_internal(false)))
7139  {
7140  return false;
7141  }
7142  }
7143  }
7144 
7145  return sax->end_array();
7146  }
7147 
7153  bool get_cbor_object(const std::size_t len)
7154  {
7155  if (not JSON_UNLIKELY(sax->start_object(len)))
7156  {
7157  return false;
7158  }
7159 
7160  string_t key;
7161  if (len != std::size_t(-1))
7162  {
7163  for (std::size_t i = 0; i < len; ++i)
7164  {
7165  get();
7166  if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7167  {
7168  return false;
7169  }
7170 
7171  if (JSON_UNLIKELY(not parse_cbor_internal()))
7172  {
7173  return false;
7174  }
7175  key.clear();
7176  }
7177  }
7178  else
7179  {
7180  while (get() != 0xFF)
7181  {
7182  if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
7183  {
7184  return false;
7185  }
7186 
7187  if (JSON_UNLIKELY(not parse_cbor_internal()))
7188  {
7189  return false;
7190  }
7191  key.clear();
7192  }
7193  }
7194 
7195  return sax->end_object();
7196  }
7197 
7199  // MsgPack //
7201 
7206  {
7207  switch (get())
7208  {
7209  // EOF
7210  case std::char_traits<char>::eof():
7211  return unexpect_eof(input_format_t::msgpack, "value");
7212 
7213  // positive fixint
7214  case 0x00:
7215  case 0x01:
7216  case 0x02:
7217  case 0x03:
7218  case 0x04:
7219  case 0x05:
7220  case 0x06:
7221  case 0x07:
7222  case 0x08:
7223  case 0x09:
7224  case 0x0A:
7225  case 0x0B:
7226  case 0x0C:
7227  case 0x0D:
7228  case 0x0E:
7229  case 0x0F:
7230  case 0x10:
7231  case 0x11:
7232  case 0x12:
7233  case 0x13:
7234  case 0x14:
7235  case 0x15:
7236  case 0x16:
7237  case 0x17:
7238  case 0x18:
7239  case 0x19:
7240  case 0x1A:
7241  case 0x1B:
7242  case 0x1C:
7243  case 0x1D:
7244  case 0x1E:
7245  case 0x1F:
7246  case 0x20:
7247  case 0x21:
7248  case 0x22:
7249  case 0x23:
7250  case 0x24:
7251  case 0x25:
7252  case 0x26:
7253  case 0x27:
7254  case 0x28:
7255  case 0x29:
7256  case 0x2A:
7257  case 0x2B:
7258  case 0x2C:
7259  case 0x2D:
7260  case 0x2E:
7261  case 0x2F:
7262  case 0x30:
7263  case 0x31:
7264  case 0x32:
7265  case 0x33:
7266  case 0x34:
7267  case 0x35:
7268  case 0x36:
7269  case 0x37:
7270  case 0x38:
7271  case 0x39:
7272  case 0x3A:
7273  case 0x3B:
7274  case 0x3C:
7275  case 0x3D:
7276  case 0x3E:
7277  case 0x3F:
7278  case 0x40:
7279  case 0x41:
7280  case 0x42:
7281  case 0x43:
7282  case 0x44:
7283  case 0x45:
7284  case 0x46:
7285  case 0x47:
7286  case 0x48:
7287  case 0x49:
7288  case 0x4A:
7289  case 0x4B:
7290  case 0x4C:
7291  case 0x4D:
7292  case 0x4E:
7293  case 0x4F:
7294  case 0x50:
7295  case 0x51:
7296  case 0x52:
7297  case 0x53:
7298  case 0x54:
7299  case 0x55:
7300  case 0x56:
7301  case 0x57:
7302  case 0x58:
7303  case 0x59:
7304  case 0x5A:
7305  case 0x5B:
7306  case 0x5C:
7307  case 0x5D:
7308  case 0x5E:
7309  case 0x5F:
7310  case 0x60:
7311  case 0x61:
7312  case 0x62:
7313  case 0x63:
7314  case 0x64:
7315  case 0x65:
7316  case 0x66:
7317  case 0x67:
7318  case 0x68:
7319  case 0x69:
7320  case 0x6A:
7321  case 0x6B:
7322  case 0x6C:
7323  case 0x6D:
7324  case 0x6E:
7325  case 0x6F:
7326  case 0x70:
7327  case 0x71:
7328  case 0x72:
7329  case 0x73:
7330  case 0x74:
7331  case 0x75:
7332  case 0x76:
7333  case 0x77:
7334  case 0x78:
7335  case 0x79:
7336  case 0x7A:
7337  case 0x7B:
7338  case 0x7C:
7339  case 0x7D:
7340  case 0x7E:
7341  case 0x7F:
7342  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
7343 
7344  // fixmap
7345  case 0x80:
7346  case 0x81:
7347  case 0x82:
7348  case 0x83:
7349  case 0x84:
7350  case 0x85:
7351  case 0x86:
7352  case 0x87:
7353  case 0x88:
7354  case 0x89:
7355  case 0x8A:
7356  case 0x8B:
7357  case 0x8C:
7358  case 0x8D:
7359  case 0x8E:
7360  case 0x8F:
7361  return get_msgpack_object(static_cast<std::size_t>(current & 0x0F));
7362 
7363  // fixarray
7364  case 0x90:
7365  case 0x91:
7366  case 0x92:
7367  case 0x93:
7368  case 0x94:
7369  case 0x95:
7370  case 0x96:
7371  case 0x97:
7372  case 0x98:
7373  case 0x99:
7374  case 0x9A:
7375  case 0x9B:
7376  case 0x9C:
7377  case 0x9D:
7378  case 0x9E:
7379  case 0x9F:
7380  return get_msgpack_array(static_cast<std::size_t>(current & 0x0F));
7381 
7382  // fixstr
7383  case 0xA0:
7384  case 0xA1:
7385  case 0xA2:
7386  case 0xA3:
7387  case 0xA4:
7388  case 0xA5:
7389  case 0xA6:
7390  case 0xA7:
7391  case 0xA8:
7392  case 0xA9:
7393  case 0xAA:
7394  case 0xAB:
7395  case 0xAC:
7396  case 0xAD:
7397  case 0xAE:
7398  case 0xAF:
7399  case 0xB0:
7400  case 0xB1:
7401  case 0xB2:
7402  case 0xB3:
7403  case 0xB4:
7404  case 0xB5:
7405  case 0xB6:
7406  case 0xB7:
7407  case 0xB8:
7408  case 0xB9:
7409  case 0xBA:
7410  case 0xBB:
7411  case 0xBC:
7412  case 0xBD:
7413  case 0xBE:
7414  case 0xBF:
7415  {
7416  string_t s;
7417  return get_msgpack_string(s) and sax->string(s);
7418  }
7419 
7420  case 0xC0: // nil
7421  return sax->null();
7422 
7423  case 0xC2: // false
7424  return sax->boolean(false);
7425 
7426  case 0xC3: // true
7427  return sax->boolean(true);
7428 
7429  case 0xCA: // float 32
7430  {
7431  float number;
7432  return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7433  }
7434 
7435  case 0xCB: // float 64
7436  {
7437  double number;
7438  return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7439  }
7440 
7441  case 0xCC: // uint 8
7442  {
7443  uint8_t number;
7444  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7445  }
7446 
7447  case 0xCD: // uint 16
7448  {
7449  uint16_t number;
7450  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7451  }
7452 
7453  case 0xCE: // uint 32
7454  {
7455  uint32_t number;
7456  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7457  }
7458 
7459  case 0xCF: // uint 64
7460  {
7461  uint64_t number;
7462  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7463  }
7464 
7465  case 0xD0: // int 8
7466  {
7467  int8_t number;
7468  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7469  }
7470 
7471  case 0xD1: // int 16
7472  {
7473  int16_t number;
7474  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7475  }
7476 
7477  case 0xD2: // int 32
7478  {
7479  int32_t number;
7480  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7481  }
7482 
7483  case 0xD3: // int 64
7484  {
7485  int64_t number;
7486  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7487  }
7488 
7489  case 0xD9: // str 8
7490  case 0xDA: // str 16
7491  case 0xDB: // str 32
7492  {
7493  string_t s;
7494  return get_msgpack_string(s) and sax->string(s);
7495  }
7496 
7497  case 0xDC: // array 16
7498  {
7499  uint16_t len;
7500  return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7501  }
7502 
7503  case 0xDD: // array 32
7504  {
7505  uint32_t len;
7506  return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7507  }
7508 
7509  case 0xDE: // map 16
7510  {
7511  uint16_t len;
7512  return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7513  }
7514 
7515  case 0xDF: // map 32
7516  {
7517  uint32_t len;
7518  return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7519  }
7520 
7521  // negative fixint
7522  case 0xE0:
7523  case 0xE1:
7524  case 0xE2:
7525  case 0xE3:
7526  case 0xE4:
7527  case 0xE5:
7528  case 0xE6:
7529  case 0xE7:
7530  case 0xE8:
7531  case 0xE9:
7532  case 0xEA:
7533  case 0xEB:
7534  case 0xEC:
7535  case 0xED:
7536  case 0xEE:
7537  case 0xEF:
7538  case 0xF0:
7539  case 0xF1:
7540  case 0xF2:
7541  case 0xF3:
7542  case 0xF4:
7543  case 0xF5:
7544  case 0xF6:
7545  case 0xF7:
7546  case 0xF8:
7547  case 0xF9:
7548  case 0xFA:
7549  case 0xFB:
7550  case 0xFC:
7551  case 0xFD:
7552  case 0xFE:
7553  case 0xFF:
7554  return sax->number_integer(static_cast<int8_t>(current));
7555 
7556  default: // anything else
7557  {
7558  auto last_token = get_token_string();
7559  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
7560  }
7561  }
7562  }
7563 
7575  {
7576  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
7577  {
7578  return false;
7579  }
7580 
7581  switch (current)
7582  {
7583  // fixstr
7584  case 0xA0:
7585  case 0xA1:
7586  case 0xA2:
7587  case 0xA3:
7588  case 0xA4:
7589  case 0xA5:
7590  case 0xA6:
7591  case 0xA7:
7592  case 0xA8:
7593  case 0xA9:
7594  case 0xAA:
7595  case 0xAB:
7596  case 0xAC:
7597  case 0xAD:
7598  case 0xAE:
7599  case 0xAF:
7600  case 0xB0:
7601  case 0xB1:
7602  case 0xB2:
7603  case 0xB3:
7604  case 0xB4:
7605  case 0xB5:
7606  case 0xB6:
7607  case 0xB7:
7608  case 0xB8:
7609  case 0xB9:
7610  case 0xBA:
7611  case 0xBB:
7612  case 0xBC:
7613  case 0xBD:
7614  case 0xBE:
7615  case 0xBF:
7616  {
7617  return get_string(input_format_t::msgpack, current & 0x1F, result);
7618  }
7619 
7620  case 0xD9: // str 8
7621  {
7622  uint8_t len;
7623  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7624  }
7625 
7626  case 0xDA: // str 16
7627  {
7628  uint16_t len;
7629  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7630  }
7631 
7632  case 0xDB: // str 32
7633  {
7634  uint32_t len;
7635  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7636  }
7637 
7638  default:
7639  {
7640  auto last_token = get_token_string();
7641  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
7642  }
7643  }
7644  }
7645 
7650  bool get_msgpack_array(const std::size_t len)
7651  {
7652  if (JSON_UNLIKELY(not sax->start_array(len)))
7653  {
7654  return false;
7655  }
7656 
7657  for (std::size_t i = 0; i < len; ++i)
7658  {
7659  if (JSON_UNLIKELY(not parse_msgpack_internal()))
7660  {
7661  return false;
7662  }
7663  }
7664 
7665  return sax->end_array();
7666  }
7667 
7672  bool get_msgpack_object(const std::size_t len)
7673  {
7674  if (JSON_UNLIKELY(not sax->start_object(len)))
7675  {
7676  return false;
7677  }
7678 
7679  string_t key;
7680  for (std::size_t i = 0; i < len; ++i)
7681  {
7682  get();
7683  if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7684  {
7685  return false;
7686  }
7687 
7688  if (JSON_UNLIKELY(not parse_msgpack_internal()))
7689  {
7690  return false;
7691  }
7692  key.clear();
7693  }
7694 
7695  return sax->end_object();
7696  }
7697 
7699  // UBJSON //
7701 
7709  bool parse_ubjson_internal(const bool get_char = true)
7710  {
7711  return get_ubjson_value(get_char ? get_ignore_noop() : current);
7712  }
7713 
7728  bool get_ubjson_string(string_t& result, const bool get_char = true)
7729  {
7730  if (get_char)
7731  {
7732  get(); // TODO: may we ignore N here?
7733  }
7734 
7735  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7736  {
7737  return false;
7738  }
7739 
7740  switch (current)
7741  {
7742  case 'U':
7743  {
7744  uint8_t len;
7745  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7746  }
7747 
7748  case 'i':
7749  {
7750  int8_t len;
7751  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7752  }
7753 
7754  case 'I':
7755  {
7756  int16_t len;
7757  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7758  }
7759 
7760  case 'l':
7761  {
7762  int32_t len;
7763  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7764  }
7765 
7766  case 'L':
7767  {
7768  int64_t len;
7769  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7770  }
7771 
7772  default:
7773  auto last_token = get_token_string();
7774  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
7775  }
7776  }
7777 
7782  bool get_ubjson_size_value(std::size_t& result)
7783  {
7784  switch (get_ignore_noop())
7785  {
7786  case 'U':
7787  {
7788  uint8_t number;
7789  if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7790  {
7791  return false;
7792  }
7793  result = static_cast<std::size_t>(number);
7794  return true;
7795  }
7796 
7797  case 'i':
7798  {
7799  int8_t number;
7800  if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7801  {
7802  return false;
7803  }
7804  result = static_cast<std::size_t>(number);
7805  return true;
7806  }
7807 
7808  case 'I':
7809  {
7810  int16_t number;
7811  if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7812  {
7813  return false;
7814  }
7815  result = static_cast<std::size_t>(number);
7816  return true;
7817  }
7818 
7819  case 'l':
7820  {
7821  int32_t number;
7822  if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7823  {
7824  return false;
7825  }
7826  result = static_cast<std::size_t>(number);
7827  return true;
7828  }
7829 
7830  case 'L':
7831  {
7832  int64_t number;
7833  if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7834  {
7835  return false;
7836  }
7837  result = static_cast<std::size_t>(number);
7838  return true;
7839  }
7840 
7841  default:
7842  {
7843  auto last_token = get_token_string();
7844  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
7845  }
7846  }
7847  }
7848 
7859  bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7860  {
7861  result.first = string_t::npos; // size
7862  result.second = 0; // type
7863 
7864  get_ignore_noop();
7865 
7866  if (current == '$')
7867  {
7868  result.second = get(); // must not ignore 'N', because 'N' maybe the type
7869  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
7870  {
7871  return false;
7872  }
7873 
7874  get_ignore_noop();
7875  if (JSON_UNLIKELY(current != '#'))
7876  {
7877  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7878  {
7879  return false;
7880  }
7881  auto last_token = get_token_string();
7882  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
7883  }
7884 
7885  return get_ubjson_size_value(result.first);
7886  }
7887  else if (current == '#')
7888  {
7889  return get_ubjson_size_value(result.first);
7890  }
7891  return true;
7892  }
7893 
7898  bool get_ubjson_value(const int prefix)
7899  {
7900  switch (prefix)
7901  {
7902  case std::char_traits<char>::eof(): // EOF
7903  return unexpect_eof(input_format_t::ubjson, "value");
7904 
7905  case 'T': // true
7906  return sax->boolean(true);
7907  case 'F': // false
7908  return sax->boolean(false);
7909 
7910  case 'Z': // null
7911  return sax->null();
7912 
7913  case 'U':
7914  {
7915  uint8_t number;
7916  return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7917  }
7918 
7919  case 'i':
7920  {
7921  int8_t number;
7922  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7923  }
7924 
7925  case 'I':
7926  {
7927  int16_t number;
7928  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7929  }
7930 
7931  case 'l':
7932  {
7933  int32_t number;
7934  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7935  }
7936 
7937  case 'L':
7938  {
7939  int64_t number;
7940  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7941  }
7942 
7943  case 'd':
7944  {
7945  float number;
7946  return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7947  }
7948 
7949  case 'D':
7950  {
7951  double number;
7952  return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7953  }
7954 
7955  case 'C': // char
7956  {
7957  get();
7958  if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
7959  {
7960  return false;
7961  }
7962  if (JSON_UNLIKELY(current > 127))
7963  {
7964  auto last_token = get_token_string();
7965  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
7966  }
7967  string_t s(1, static_cast<char>(current));
7968  return sax->string(s);
7969  }
7970 
7971  case 'S': // string
7972  {
7973  string_t s;
7974  return get_ubjson_string(s) and sax->string(s);
7975  }
7976 
7977  case '[': // array
7978  return get_ubjson_array();
7979 
7980  case '{': // object
7981  return get_ubjson_object();
7982 
7983  default: // anything else
7984  {
7985  auto last_token = get_token_string();
7986  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
7987  }
7988  }
7989  }
7990 
7995  {
7996  std::pair<std::size_t, int> size_and_type;
7997  if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7998  {
7999  return false;
8000  }
8001 
8002  if (size_and_type.first != string_t::npos)
8003  {
8004  if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
8005  {
8006  return false;
8007  }
8008 
8009  if (size_and_type.second != 0)
8010  {
8011  if (size_and_type.second != 'N')
8012  {
8013  for (std::size_t i = 0; i < size_and_type.first; ++i)
8014  {
8015  if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8016  {
8017  return false;
8018  }
8019  }
8020  }
8021  }
8022  else
8023  {
8024  for (std::size_t i = 0; i < size_and_type.first; ++i)
8025  {
8026  if (JSON_UNLIKELY(not parse_ubjson_internal()))
8027  {
8028  return false;
8029  }
8030  }
8031  }
8032  }
8033  else
8034  {
8035  if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
8036  {
8037  return false;
8038  }
8039 
8040  while (current != ']')
8041  {
8042  if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
8043  {
8044  return false;
8045  }
8046  get_ignore_noop();
8047  }
8048  }
8049 
8050  return sax->end_array();
8051  }
8052 
8057  {
8058  std::pair<std::size_t, int> size_and_type;
8059  if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
8060  {
8061  return false;
8062  }
8063 
8064  string_t key;
8065  if (size_and_type.first != string_t::npos)
8066  {
8067  if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
8068  {
8069  return false;
8070  }
8071 
8072  if (size_and_type.second != 0)
8073  {
8074  for (std::size_t i = 0; i < size_and_type.first; ++i)
8075  {
8076  if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8077  {
8078  return false;
8079  }
8080  if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
8081  {
8082  return false;
8083  }
8084  key.clear();
8085  }
8086  }
8087  else
8088  {
8089  for (std::size_t i = 0; i < size_and_type.first; ++i)
8090  {
8091  if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
8092  {
8093  return false;
8094  }
8095  if (JSON_UNLIKELY(not parse_ubjson_internal()))
8096  {
8097  return false;
8098  }
8099  key.clear();
8100  }
8101  }
8102  }
8103  else
8104  {
8105  if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
8106  {
8107  return false;
8108  }
8109 
8110  while (current != '}')
8111  {
8112  if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
8113  {
8114  return false;
8115  }
8116  if (JSON_UNLIKELY(not parse_ubjson_internal()))
8117  {
8118  return false;
8119  }
8120  get_ignore_noop();
8121  key.clear();
8122  }
8123  }
8124 
8125  return sax->end_object();
8126  }
8127 
8129  // Utility functions //
8131 
8141  int get()
8142  {
8143  ++chars_read;
8144  return (current = ia->get_character());
8145  }
8146 
8151  {
8152  do
8153  {
8154  get();
8155  }
8156  while (current == 'N');
8157 
8158  return current;
8159  }
8160 
8161  /*
8162  @brief read a number from the input
8163 
8164  @tparam NumberType the type of the number
8165  @param[in] format the current format (for diagnostics)
8166  @param[out] result number of type @a NumberType
8167 
8168  @return whether conversion completed
8169 
8170  @note This function needs to respect the system's endianess, because
8171  bytes in CBOR, MessagePack, and UBJSON are stored in network order
8172  (big endian) and therefore need reordering on little endian systems.
8173  */
8174  template<typename NumberType, bool InputIsLittleEndian = false>
8175  bool get_number(const input_format_t format, NumberType& result)
8176  {
8177  // step 1: read input into array with system's byte order
8178  std::array<uint8_t, sizeof(NumberType)> vec;
8179  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
8180  {
8181  get();
8182  if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
8183  {
8184  return false;
8185  }
8186 
8187  // reverse byte order prior to conversion if necessary
8188  if (is_little_endian && !InputIsLittleEndian)
8189  {
8190  vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
8191  }
8192  else
8193  {
8194  vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
8195  }
8196  }
8197 
8198  // step 2: convert array into number of type T and return
8199  std::memcpy(&result, vec.data(), sizeof(NumberType));
8200  return true;
8201  }
8202 
8217  template<typename NumberType>
8218  bool get_string(const input_format_t format,
8219  const NumberType len,
8220  string_t& result)
8221  {
8222  bool success = true;
8223  std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
8224  {
8225  get();
8226  if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
8227  {
8228  success = false;
8229  }
8230  return static_cast<char>(current);
8231  });
8232  return success;
8233  }
8234 
8240  bool unexpect_eof(const input_format_t format, const char* context) const
8241  {
8242  if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
8243  {
8244  return sax->parse_error(chars_read, "<end of file>",
8245  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
8246  }
8247  return true;
8248  }
8249 
8254  {
8255  char cr[3];
8256  snprintf(cr, 3, "%.2hhX", static_cast<unsigned char>(current));
8257  return std::string{cr};
8258  }
8259 
8267  const std::string& detail,
8268  const std::string& context) const
8269  {
8270  std::string error_msg = "syntax error while parsing ";
8271 
8272  switch (format)
8273  {
8274  case input_format_t::cbor:
8275  error_msg += "CBOR";
8276  break;
8277 
8279  error_msg += "MessagePack";
8280  break;
8281 
8283  error_msg += "UBJSON";
8284  break;
8285 
8286  case input_format_t::bson:
8287  error_msg += "BSON";
8288  break;
8289 
8290  // LCOV_EXCL_START
8291  default:
8292  assert(false);
8293  // LCOV_EXCL_STOP
8294  }
8295 
8296  return error_msg + " " + context + ": " + detail;
8297  }
8298 
8299  private:
8301  input_adapter_t ia = nullptr;
8302 
8304  int current = std::char_traits<char>::eof();
8305 
8307  std::size_t chars_read = 0;
8308 
8310  const bool is_little_endian = little_endianess();
8311 
8313  json_sax_t* sax = nullptr;
8314 };
8315 } // namespace detail
8316 } // namespace nlohmann
8317 
8318 // #include <nlohmann/detail/output/binary_writer.hpp>
8319 
8320 
8321 #include <algorithm> // reverse
8322 #include <array> // array
8323 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
8324 #include <cstring> // memcpy
8325 #include <limits> // numeric_limits
8326 
8327 // #include <nlohmann/detail/input/binary_reader.hpp>
8328 
8329 // #include <nlohmann/detail/output/output_adapters.hpp>
8330 
8331 
8332 namespace nlohmann
8333 {
8334 namespace detail
8335 {
8337 // binary writer //
8339 
8343 template<typename BasicJsonType, typename CharType>
8345 {
8346  using string_t = typename BasicJsonType::string_t;
8347 
8348  public:
8354  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
8355  {
8356  assert(oa);
8357  }
8358 
8363  void write_bson(const BasicJsonType& j)
8364  {
8365  switch (j.type())
8366  {
8367  case value_t::object:
8368  {
8369  write_bson_object(*j.m_value.object);
8370  break;
8371  }
8372 
8373  default:
8374  {
8375  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
8376  }
8377  }
8378  }
8379 
8383  void write_cbor(const BasicJsonType& j)
8384  {
8385  switch (j.type())
8386  {
8387  case value_t::null:
8388  {
8389  oa->write_character(to_char_type(0xF6));
8390  break;
8391  }
8392 
8393  case value_t::boolean:
8394  {
8395  oa->write_character(j.m_value.boolean
8396  ? to_char_type(0xF5)
8397  : to_char_type(0xF4));
8398  break;
8399  }
8400 
8402  {
8403  if (j.m_value.number_integer >= 0)
8404  {
8405  // CBOR does not differentiate between positive signed
8406  // integers and unsigned integers. Therefore, we used the
8407  // code from the value_t::number_unsigned case here.
8408  if (j.m_value.number_integer <= 0x17)
8409  {
8410  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8411  }
8412  else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
8413  {
8414  oa->write_character(to_char_type(0x18));
8415  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8416  }
8417  else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
8418  {
8419  oa->write_character(to_char_type(0x19));
8420  write_number(static_cast<uint16_t>(j.m_value.number_integer));
8421  }
8422  else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
8423  {
8424  oa->write_character(to_char_type(0x1A));
8425  write_number(static_cast<uint32_t>(j.m_value.number_integer));
8426  }
8427  else
8428  {
8429  oa->write_character(to_char_type(0x1B));
8430  write_number(static_cast<uint64_t>(j.m_value.number_integer));
8431  }
8432  }
8433  else
8434  {
8435  // The conversions below encode the sign in the first
8436  // byte, and the value is converted to a positive number.
8437  const auto positive_number = -1 - j.m_value.number_integer;
8438  if (j.m_value.number_integer >= -24)
8439  {
8440  write_number(static_cast<uint8_t>(0x20 + positive_number));
8441  }
8442  else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
8443  {
8444  oa->write_character(to_char_type(0x38));
8445  write_number(static_cast<uint8_t>(positive_number));
8446  }
8447  else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
8448  {
8449  oa->write_character(to_char_type(0x39));
8450  write_number(static_cast<uint16_t>(positive_number));
8451  }
8452  else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
8453  {
8454  oa->write_character(to_char_type(0x3A));
8455  write_number(static_cast<uint32_t>(positive_number));
8456  }
8457  else
8458  {
8459  oa->write_character(to_char_type(0x3B));
8460  write_number(static_cast<uint64_t>(positive_number));
8461  }
8462  }
8463  break;
8464  }
8465 
8467  {
8468  if (j.m_value.number_unsigned <= 0x17)
8469  {
8470  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8471  }
8472  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8473  {
8474  oa->write_character(to_char_type(0x18));
8475  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
8476  }
8477  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8478  {
8479  oa->write_character(to_char_type(0x19));
8480  write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
8481  }
8482  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8483  {
8484  oa->write_character(to_char_type(0x1A));
8485  write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
8486  }
8487  else
8488  {
8489  oa->write_character(to_char_type(0x1B));
8490  write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
8491  }
8492  break;
8493  }
8494 
8495  case value_t::number_float:
8496  {
8497  oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
8498  write_number(j.m_value.number_float);
8499  break;
8500  }
8501 
8502  case value_t::string:
8503  {
8504  // step 1: write control byte and the string length
8505  const auto N = j.m_value.string->size();
8506  if (N <= 0x17)
8507  {
8508  write_number(static_cast<uint8_t>(0x60 + N));
8509  }
8510  else if (N <= (std::numeric_limits<uint8_t>::max)())
8511  {
8512  oa->write_character(to_char_type(0x78));
8513  write_number(static_cast<uint8_t>(N));
8514  }
8515  else if (N <= (std::numeric_limits<uint16_t>::max)())
8516  {
8517  oa->write_character(to_char_type(0x79));
8518  write_number(static_cast<uint16_t>(N));
8519  }
8520  else if (N <= (std::numeric_limits<uint32_t>::max)())
8521  {
8522  oa->write_character(to_char_type(0x7A));
8523  write_number(static_cast<uint32_t>(N));
8524  }
8525  // LCOV_EXCL_START
8526  else if (N <= (std::numeric_limits<uint64_t>::max)())
8527  {
8528  oa->write_character(to_char_type(0x7B));
8529  write_number(static_cast<uint64_t>(N));
8530  }
8531  // LCOV_EXCL_STOP
8532 
8533  // step 2: write the string
8534  oa->write_characters(
8535  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8536  j.m_value.string->size());
8537  break;
8538  }
8539 
8540  case value_t::array:
8541  {
8542  // step 1: write control byte and the array size
8543  const auto N = j.m_value.array->size();
8544  if (N <= 0x17)
8545  {
8546  write_number(static_cast<uint8_t>(0x80 + N));
8547  }
8548  else if (N <= (std::numeric_limits<uint8_t>::max)())
8549  {
8550  oa->write_character(to_char_type(0x98));
8551  write_number(static_cast<uint8_t>(N));
8552  }
8553  else if (N <= (std::numeric_limits<uint16_t>::max)())
8554  {
8555  oa->write_character(to_char_type(0x99));
8556  write_number(static_cast<uint16_t>(N));
8557  }
8558  else if (N <= (std::numeric_limits<uint32_t>::max)())
8559  {
8560  oa->write_character(to_char_type(0x9A));
8561  write_number(static_cast<uint32_t>(N));
8562  }
8563  // LCOV_EXCL_START
8564  else if (N <= (std::numeric_limits<uint64_t>::max)())
8565  {
8566  oa->write_character(to_char_type(0x9B));
8567  write_number(static_cast<uint64_t>(N));
8568  }
8569  // LCOV_EXCL_STOP
8570 
8571  // step 2: write each element
8572  for (const auto& el : *j.m_value.array)
8573  {
8574  write_cbor(el);
8575  }
8576  break;
8577  }
8578 
8579  case value_t::object:
8580  {
8581  // step 1: write control byte and the object size
8582  const auto N = j.m_value.object->size();
8583  if (N <= 0x17)
8584  {
8585  write_number(static_cast<uint8_t>(0xA0 + N));
8586  }
8587  else if (N <= (std::numeric_limits<uint8_t>::max)())
8588  {
8589  oa->write_character(to_char_type(0xB8));
8590  write_number(static_cast<uint8_t>(N));
8591  }
8592  else if (N <= (std::numeric_limits<uint16_t>::max)())
8593  {
8594  oa->write_character(to_char_type(0xB9));
8595  write_number(static_cast<uint16_t>(N));
8596  }
8597  else if (N <= (std::numeric_limits<uint32_t>::max)())
8598  {
8599  oa->write_character(to_char_type(0xBA));
8600  write_number(static_cast<uint32_t>(N));
8601  }
8602  // LCOV_EXCL_START
8603  else if (N <= (std::numeric_limits<uint64_t>::max)())
8604  {
8605  oa->write_character(to_char_type(0xBB));
8606  write_number(static_cast<uint64_t>(N));
8607  }
8608  // LCOV_EXCL_STOP
8609 
8610  // step 2: write each element
8611  for (const auto& el : *j.m_value.object)
8612  {
8613  write_cbor(el.first);
8614  write_cbor(el.second);
8615  }
8616  break;
8617  }
8618 
8619  default:
8620  break;
8621  }
8622  }
8623 
8627  void write_msgpack(const BasicJsonType& j)
8628  {
8629  switch (j.type())
8630  {
8631  case value_t::null: // nil
8632  {
8633  oa->write_character(to_char_type(0xC0));
8634  break;
8635  }
8636 
8637  case value_t::boolean: // true and false
8638  {
8639  oa->write_character(j.m_value.boolean
8640  ? to_char_type(0xC3)
8641  : to_char_type(0xC2));
8642  break;
8643  }
8644 
8646  {
8647  if (j.m_value.number_integer >= 0)
8648  {
8649  // MessagePack does not differentiate between positive
8650  // signed integers and unsigned integers. Therefore, we used
8651  // the code from the value_t::number_unsigned case here.
8652  if (j.m_value.number_unsigned < 128)
8653  {
8654  // positive fixnum
8655  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8656  }
8657  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8658  {
8659  // uint 8
8660  oa->write_character(to_char_type(0xCC));
8661  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8662  }
8663  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8664  {
8665  // uint 16
8666  oa->write_character(to_char_type(0xCD));
8667  write_number(static_cast<uint16_t>(j.m_value.number_integer));
8668  }
8669  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8670  {
8671  // uint 32
8672  oa->write_character(to_char_type(0xCE));
8673  write_number(static_cast<uint32_t>(j.m_value.number_integer));
8674  }
8675  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8676  {
8677  // uint 64
8678  oa->write_character(to_char_type(0xCF));
8679  write_number(static_cast<uint64_t>(j.m_value.number_integer));
8680  }
8681  }
8682  else
8683  {
8684  if (j.m_value.number_integer >= -32)
8685  {
8686  // negative fixnum
8687  write_number(static_cast<int8_t>(j.m_value.number_integer));
8688  }
8689  else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
8690  j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
8691  {
8692  // int 8
8693  oa->write_character(to_char_type(0xD0));
8694  write_number(static_cast<int8_t>(j.m_value.number_integer));
8695  }
8696  else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
8697  j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
8698  {
8699  // int 16
8700  oa->write_character(to_char_type(0xD1));
8701  write_number(static_cast<int16_t>(j.m_value.number_integer));
8702  }
8703  else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
8704  j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
8705  {
8706  // int 32
8707  oa->write_character(to_char_type(0xD2));
8708  write_number(static_cast<int32_t>(j.m_value.number_integer));
8709  }
8710  else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
8711  j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
8712  {
8713  // int 64
8714  oa->write_character(to_char_type(0xD3));
8715  write_number(static_cast<int64_t>(j.m_value.number_integer));
8716  }
8717  }
8718  break;
8719  }
8720 
8722  {
8723  if (j.m_value.number_unsigned < 128)
8724  {
8725  // positive fixnum
8726  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8727  }
8728  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
8729  {
8730  // uint 8
8731  oa->write_character(to_char_type(0xCC));
8732  write_number(static_cast<uint8_t>(j.m_value.number_integer));
8733  }
8734  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
8735  {
8736  // uint 16
8737  oa->write_character(to_char_type(0xCD));
8738  write_number(static_cast<uint16_t>(j.m_value.number_integer));
8739  }
8740  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
8741  {
8742  // uint 32
8743  oa->write_character(to_char_type(0xCE));
8744  write_number(static_cast<uint32_t>(j.m_value.number_integer));
8745  }
8746  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
8747  {
8748  // uint 64
8749  oa->write_character(to_char_type(0xCF));
8750  write_number(static_cast<uint64_t>(j.m_value.number_integer));
8751  }
8752  break;
8753  }
8754 
8755  case value_t::number_float:
8756  {
8757  oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
8758  write_number(j.m_value.number_float);
8759  break;
8760  }
8761 
8762  case value_t::string:
8763  {
8764  // step 1: write control byte and the string length
8765  const auto N = j.m_value.string->size();
8766  if (N <= 31)
8767  {
8768  // fixstr
8769  write_number(static_cast<uint8_t>(0xA0 | N));
8770  }
8771  else if (N <= (std::numeric_limits<uint8_t>::max)())
8772  {
8773  // str 8
8774  oa->write_character(to_char_type(0xD9));
8775  write_number(static_cast<uint8_t>(N));
8776  }
8777  else if (N <= (std::numeric_limits<uint16_t>::max)())
8778  {
8779  // str 16
8780  oa->write_character(to_char_type(0xDA));
8781  write_number(static_cast<uint16_t>(N));
8782  }
8783  else if (N <= (std::numeric_limits<uint32_t>::max)())
8784  {
8785  // str 32
8786  oa->write_character(to_char_type(0xDB));
8787  write_number(static_cast<uint32_t>(N));
8788  }
8789 
8790  // step 2: write the string
8791  oa->write_characters(
8792  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8793  j.m_value.string->size());
8794  break;
8795  }
8796 
8797  case value_t::array:
8798  {
8799  // step 1: write control byte and the array size
8800  const auto N = j.m_value.array->size();
8801  if (N <= 15)
8802  {
8803  // fixarray
8804  write_number(static_cast<uint8_t>(0x90 | N));
8805  }
8806  else if (N <= (std::numeric_limits<uint16_t>::max)())
8807  {
8808  // array 16
8809  oa->write_character(to_char_type(0xDC));
8810  write_number(static_cast<uint16_t>(N));
8811  }
8812  else if (N <= (std::numeric_limits<uint32_t>::max)())
8813  {
8814  // array 32
8815  oa->write_character(to_char_type(0xDD));
8816  write_number(static_cast<uint32_t>(N));
8817  }
8818 
8819  // step 2: write each element
8820  for (const auto& el : *j.m_value.array)
8821  {
8822  write_msgpack(el);
8823  }
8824  break;
8825  }
8826 
8827  case value_t::object:
8828  {
8829  // step 1: write control byte and the object size
8830  const auto N = j.m_value.object->size();
8831  if (N <= 15)
8832  {
8833  // fixmap
8834  write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
8835  }
8836  else if (N <= (std::numeric_limits<uint16_t>::max)())
8837  {
8838  // map 16
8839  oa->write_character(to_char_type(0xDE));
8840  write_number(static_cast<uint16_t>(N));
8841  }
8842  else if (N <= (std::numeric_limits<uint32_t>::max)())
8843  {
8844  // map 32
8845  oa->write_character(to_char_type(0xDF));
8846  write_number(static_cast<uint32_t>(N));
8847  }
8848 
8849  // step 2: write each element
8850  for (const auto& el : *j.m_value.object)
8851  {
8852  write_msgpack(el.first);
8853  write_msgpack(el.second);
8854  }
8855  break;
8856  }
8857 
8858  default:
8859  break;
8860  }
8861  }
8862 
8869  void write_ubjson(const BasicJsonType& j, const bool use_count,
8870  const bool use_type, const bool add_prefix = true)
8871  {
8872  switch (j.type())
8873  {
8874  case value_t::null:
8875  {
8876  if (add_prefix)
8877  {
8878  oa->write_character(to_char_type('Z'));
8879  }
8880  break;
8881  }
8882 
8883  case value_t::boolean:
8884  {
8885  if (add_prefix)
8886  {
8887  oa->write_character(j.m_value.boolean
8888  ? to_char_type('T')
8889  : to_char_type('F'));
8890  }
8891  break;
8892  }
8893 
8895  {
8896  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
8897  break;
8898  }
8899 
8901  {
8902  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
8903  break;
8904  }
8905 
8906  case value_t::number_float:
8907  {
8908  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
8909  break;
8910  }
8911 
8912  case value_t::string:
8913  {
8914  if (add_prefix)
8915  {
8916  oa->write_character(to_char_type('S'));
8917  }
8918  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
8919  oa->write_characters(
8920  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
8921  j.m_value.string->size());
8922  break;
8923  }
8924 
8925  case value_t::array:
8926  {
8927  if (add_prefix)
8928  {
8929  oa->write_character(to_char_type('['));
8930  }
8931 
8932  bool prefix_required = true;
8933  if (use_type and not j.m_value.array->empty())
8934  {
8935  assert(use_count);
8936  const CharType first_prefix = ubjson_prefix(j.front());
8937  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
8938  [this, first_prefix](const BasicJsonType & v)
8939  {
8940  return ubjson_prefix(v) == first_prefix;
8941  });
8942 
8943  if (same_prefix)
8944  {
8945  prefix_required = false;
8946  oa->write_character(to_char_type('$'));
8947  oa->write_character(first_prefix);
8948  }
8949  }
8950 
8951  if (use_count)
8952  {
8953  oa->write_character(to_char_type('#'));
8954  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
8955  }
8956 
8957  for (const auto& el : *j.m_value.array)
8958  {
8959  write_ubjson(el, use_count, use_type, prefix_required);
8960  }
8961 
8962  if (not use_count)
8963  {
8964  oa->write_character(to_char_type(']'));
8965  }
8966 
8967  break;
8968  }
8969 
8970  case value_t::object:
8971  {
8972  if (add_prefix)
8973  {
8974  oa->write_character(to_char_type('{'));
8975  }
8976 
8977  bool prefix_required = true;
8978  if (use_type and not j.m_value.object->empty())
8979  {
8980  assert(use_count);
8981  const CharType first_prefix = ubjson_prefix(j.front());
8982  const bool same_prefix = std::all_of(j.begin(), j.end(),
8983  [this, first_prefix](const BasicJsonType & v)
8984  {
8985  return ubjson_prefix(v) == first_prefix;
8986  });
8987 
8988  if (same_prefix)
8989  {
8990  prefix_required = false;
8991  oa->write_character(to_char_type('$'));
8992  oa->write_character(first_prefix);
8993  }
8994  }
8995 
8996  if (use_count)
8997  {
8998  oa->write_character(to_char_type('#'));
8999  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
9000  }
9001 
9002  for (const auto& el : *j.m_value.object)
9003  {
9004  write_number_with_ubjson_prefix(el.first.size(), true);
9005  oa->write_characters(
9006  reinterpret_cast<const CharType*>(el.first.c_str()),
9007  el.first.size());
9008  write_ubjson(el.second, use_count, use_type, prefix_required);
9009  }
9010 
9011  if (not use_count)
9012  {
9013  oa->write_character(to_char_type('}'));
9014  }
9015 
9016  break;
9017  }
9018 
9019  default:
9020  break;
9021  }
9022  }
9023 
9024  private:
9026  // BSON //
9028 
9033  static std::size_t calc_bson_entry_header_size(const string_t& name)
9034  {
9035  const auto it = name.find(static_cast<typename string_t::value_type>(0));
9036  if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
9037  {
9039  "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
9040  }
9041 
9042  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
9043  }
9044 
9049  const std::uint8_t element_type)
9050  {
9051  oa->write_character(to_char_type(element_type)); // boolean
9052  oa->write_characters(
9053  reinterpret_cast<const CharType*>(name.c_str()),
9054  name.size() + 1u);
9055  }
9056 
9061  const bool value)
9062  {
9063  write_bson_entry_header(name, 0x08);
9064  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
9065  }
9066 
9071  const double value)
9072  {
9073  write_bson_entry_header(name, 0x01);
9074  write_number<double, true>(value);
9075  }
9076 
9080  static std::size_t calc_bson_string_size(const string_t& value)
9081  {
9082  return sizeof(std::int32_t) + value.size() + 1ul;
9083  }
9084 
9089  const string_t& value)
9090  {
9091  write_bson_entry_header(name, 0x02);
9092 
9093  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
9094  oa->write_characters(
9095  reinterpret_cast<const CharType*>(value.c_str()),
9096  value.size() + 1);
9097  }
9098 
9103  {
9104  write_bson_entry_header(name, 0x0A);
9105  }
9106 
9110  static std::size_t calc_bson_integer_size(const std::int64_t value)
9111  {
9113  {
9114  return sizeof(std::int32_t);
9115  }
9116  else
9117  {
9118  return sizeof(std::int64_t);
9119  }
9120  }
9121 
9126  const std::int64_t value)
9127  {
9129  {
9130  write_bson_entry_header(name, 0x10); // int32
9131  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
9132  }
9133  else
9134  {
9135  write_bson_entry_header(name, 0x12); // int64
9136  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
9137  }
9138  }
9139 
9143  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
9144  {
9145  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
9146  ? sizeof(std::int32_t)
9147  : sizeof(std::int64_t);
9148  }
9149 
9154  const std::uint64_t value)
9155  {
9156  if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
9157  {
9158  write_bson_entry_header(name, 0x10 /* int32 */);
9159  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
9160  }
9161  else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
9162  {
9163  write_bson_entry_header(name, 0x12 /* int64 */);
9164  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
9165  }
9166  else
9167  {
9168  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
9169  }
9170  }
9171 
9176  const typename BasicJsonType::object_t& value)
9177  {
9178  write_bson_entry_header(name, 0x03); // object
9179  write_bson_object(value);
9180  }
9181 
9185  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
9186  {
9187  std::size_t embedded_document_size = 0ul;
9188  std::size_t array_index = 0ul;
9189 
9190  for (const auto& el : value)
9191  {
9192  embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
9193  }
9194 
9195  return sizeof(std::int32_t) + embedded_document_size + 1ul;
9196  }
9197 
9202  const typename BasicJsonType::array_t& value)
9203  {
9204  write_bson_entry_header(name, 0x04); // array
9205  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
9206 
9207  std::size_t array_index = 0ul;
9208 
9209  for (const auto& el : value)
9210  {
9211  write_bson_element(std::to_string(array_index++), el);
9212  }
9213 
9214  oa->write_character(to_char_type(0x00));
9215  }
9216 
9221  static std::size_t calc_bson_element_size(const string_t& name,
9222  const BasicJsonType& j)
9223  {
9224  const auto header_size = calc_bson_entry_header_size(name);
9225  switch (j.type())
9226  {
9227  case value_t::object:
9228  return header_size + calc_bson_object_size(*j.m_value.object);
9229 
9230  case value_t::array:
9231  return header_size + calc_bson_array_size(*j.m_value.array);
9232 
9233  case value_t::boolean:
9234  return header_size + 1ul;
9235 
9236  case value_t::number_float:
9237  return header_size + 8ul;
9238 
9240  return header_size + calc_bson_integer_size(j.m_value.number_integer);
9241 
9243  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
9244 
9245  case value_t::string:
9246  return header_size + calc_bson_string_size(*j.m_value.string);
9247 
9248  case value_t::null:
9249  return header_size + 0ul;
9250 
9251  // LCOV_EXCL_START
9252  default:
9253  assert(false);
9254  return 0ul;
9255  // LCOV_EXCL_STOP
9256  };
9257  }
9258 
9267  const BasicJsonType& j)
9268  {
9269  switch (j.type())
9270  {
9271  case value_t::object:
9272  return write_bson_object_entry(name, *j.m_value.object);
9273 
9274  case value_t::array:
9275  return write_bson_array(name, *j.m_value.array);
9276 
9277  case value_t::boolean:
9278  return write_bson_boolean(name, j.m_value.boolean);
9279 
9280  case value_t::number_float:
9281  return write_bson_double(name, j.m_value.number_float);
9282 
9284  return write_bson_integer(name, j.m_value.number_integer);
9285 
9287  return write_bson_unsigned(name, j.m_value.number_unsigned);
9288 
9289  case value_t::string:
9290  return write_bson_string(name, *j.m_value.string);
9291 
9292  case value_t::null:
9293  return write_bson_null(name);
9294 
9295  // LCOV_EXCL_START
9296  default:
9297  assert(false);
9298  return;
9299  // LCOV_EXCL_STOP
9300  };
9301  }
9302 
9309  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
9310  {
9311  std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
9312  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
9313  {
9314  return result += calc_bson_element_size(el.first, el.second);
9315  });
9316 
9317  return sizeof(std::int32_t) + document_size + 1ul;
9318  }
9319 
9324  void write_bson_object(const typename BasicJsonType::object_t& value)
9325  {
9326  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
9327 
9328  for (const auto& el : value)
9329  {
9330  write_bson_element(el.first, el.second);
9331  }
9332 
9333  oa->write_character(to_char_type(0x00));
9334  }
9335 
9337  // CBOR //
9339 
9340  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
9341  {
9342  return to_char_type(0xFA); // Single-Precision Float
9343  }
9344 
9345  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
9346  {
9347  return to_char_type(0xFB); // Double-Precision Float
9348  }
9349 
9351  // MsgPack //
9353 
9354  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
9355  {
9356  return to_char_type(0xCA); // float 32
9357  }
9358 
9359  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
9360  {
9361  return to_char_type(0xCB); // float 64
9362  }
9363 
9365  // UBJSON //
9367 
9368  // UBJSON: write number (floating point)
9369  template<typename NumberType, typename std::enable_if<
9371  void write_number_with_ubjson_prefix(const NumberType n,
9372  const bool add_prefix)
9373  {
9374  if (add_prefix)
9375  {
9376  oa->write_character(get_ubjson_float_prefix(n));
9377  }
9378  write_number(n);
9379  }
9380 
9381  // UBJSON: write number (unsigned integer)
9382  template<typename NumberType, typename std::enable_if<
9383  std::is_unsigned<NumberType>::value, int>::type = 0>
9384  void write_number_with_ubjson_prefix(const NumberType n,
9385  const bool add_prefix)
9386  {
9387  if (n <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
9388  {
9389  if (add_prefix)
9390  {
9391  oa->write_character(to_char_type('i')); // int8
9392  }
9393  write_number(static_cast<uint8_t>(n));
9394  }
9395  else if (n <= (std::numeric_limits<uint8_t>::max)())
9396  {
9397  if (add_prefix)
9398  {
9399  oa->write_character(to_char_type('U')); // uint8
9400  }
9401  write_number(static_cast<uint8_t>(n));
9402  }
9403  else if (n <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
9404  {
9405  if (add_prefix)
9406  {
9407  oa->write_character(to_char_type('I')); // int16
9408  }
9409  write_number(static_cast<int16_t>(n));
9410  }
9411  else if (n <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
9412  {
9413  if (add_prefix)
9414  {
9415  oa->write_character(to_char_type('l')); // int32
9416  }
9417  write_number(static_cast<int32_t>(n));
9418  }
9419  else if (n <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
9420  {
9421  if (add_prefix)
9422  {
9423  oa->write_character(to_char_type('L')); // int64
9424  }
9425  write_number(static_cast<int64_t>(n));
9426  }
9427  else
9428  {
9429  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
9430  }
9431  }
9432 
9433  // UBJSON: write number (signed integer)
9434  template<typename NumberType, typename std::enable_if<
9436  not std::is_floating_point<NumberType>::value, int>::type = 0>
9437  void write_number_with_ubjson_prefix(const NumberType n,
9438  const bool add_prefix)
9439  {
9441  {
9442  if (add_prefix)
9443  {
9444  oa->write_character(to_char_type('i')); // int8
9445  }
9446  write_number(static_cast<int8_t>(n));
9447  }
9448  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)()))
9449  {
9450  if (add_prefix)
9451  {
9452  oa->write_character(to_char_type('U')); // uint8
9453  }
9454  write_number(static_cast<uint8_t>(n));
9455  }
9457  {
9458  if (add_prefix)
9459  {
9460  oa->write_character(to_char_type('I')); // int16
9461  }
9462  write_number(static_cast<int16_t>(n));
9463  }
9465  {
9466  if (add_prefix)
9467  {
9468  oa->write_character(to_char_type('l')); // int32
9469  }
9470  write_number(static_cast<int32_t>(n));
9471  }
9473  {
9474  if (add_prefix)
9475  {
9476  oa->write_character(to_char_type('L')); // int64
9477  }
9478  write_number(static_cast<int64_t>(n));
9479  }
9480  // LCOV_EXCL_START
9481  else
9482  {
9483  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
9484  }
9485  // LCOV_EXCL_STOP
9486  }
9487 
9497  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
9498  {
9499  switch (j.type())
9500  {
9501  case value_t::null:
9502  return 'Z';
9503 
9504  case value_t::boolean:
9505  return j.m_value.boolean ? 'T' : 'F';
9506 
9508  {
9509  if ((std::numeric_limits<int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
9510  {
9511  return 'i';
9512  }
9513  if ((std::numeric_limits<uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
9514  {
9515  return 'U';
9516  }
9517  if ((std::numeric_limits<int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
9518  {
9519  return 'I';
9520  }
9521  if ((std::numeric_limits<int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
9522  {
9523  return 'l';
9524  }
9525  // no check and assume int64_t (see note above)
9526  return 'L';
9527  }
9528 
9530  {
9531  if (j.m_value.number_unsigned <= (std::numeric_limits<int8_t>::max)())
9532  {
9533  return 'i';
9534  }
9535  if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
9536  {
9537  return 'U';
9538  }
9539  if (j.m_value.number_unsigned <= (std::numeric_limits<int16_t>::max)())
9540  {
9541  return 'I';
9542  }
9543  if (j.m_value.number_unsigned <= (std::numeric_limits<int32_t>::max)())
9544  {
9545  return 'l';
9546  }
9547  // no check and assume int64_t (see note above)
9548  return 'L';
9549  }
9550 
9551  case value_t::number_float:
9552  return get_ubjson_float_prefix(j.m_value.number_float);
9553 
9554  case value_t::string:
9555  return 'S';
9556 
9557  case value_t::array:
9558  return '[';
9559 
9560  case value_t::object:
9561  return '{';
9562 
9563  default: // discarded values
9564  return 'N';
9565  }
9566  }
9567 
9568  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
9569  {
9570  return 'd'; // float 32
9571  }
9572 
9573  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
9574  {
9575  return 'D'; // float 64
9576  }
9577 
9579  // Utility functions //
9581 
9582  /*
9583  @brief write a number to output input
9584  @param[in] n number of type @a NumberType
9585  @tparam NumberType the type of the number
9586  @tparam OutputIsLittleEndian Set to true if output data is
9587  required to be little endian
9588 
9589  @note This function needs to respect the system's endianess, because bytes
9590  in CBOR, MessagePack, and UBJSON are stored in network order (big
9591  endian) and therefore need reordering on little endian systems.
9592  */
9593  template<typename NumberType, bool OutputIsLittleEndian = false>
9594  void write_number(const NumberType n)
9595  {
9596  // step 1: write number to array of length NumberType
9597  std::array<CharType, sizeof(NumberType)> vec;
9598  std::memcpy(vec.data(), &n, sizeof(NumberType));
9599 
9600  // step 2: write array to output (with possible reordering)
9601  if (is_little_endian and not OutputIsLittleEndian)
9602  {
9603  // reverse byte order prior to conversion if necessary
9604  std::reverse(vec.begin(), vec.end());
9605  }
9606 
9607  oa->write_characters(vec.data(), sizeof(NumberType));
9608  }
9609 
9610  public:
9611  // The following to_char_type functions are implement the conversion
9612  // between uint8_t and CharType. In case CharType is not unsigned,
9613  // such a conversion is required to allow values greater than 128.
9614  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
9615  template < typename C = CharType,
9617  static constexpr CharType to_char_type(std::uint8_t x) noexcept
9618  {
9619  return *reinterpret_cast<char*>(&x);
9620  }
9621 
9622  template < typename C = CharType,
9624  static CharType to_char_type(std::uint8_t x) noexcept
9625  {
9626  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
9627  static_assert(std::is_pod<CharType>::value, "CharType must be POD");
9628  CharType result;
9629  std::memcpy(&result, &x, sizeof(x));
9630  return result;
9631  }
9632 
9633  template<typename C = CharType,
9635  static constexpr CharType to_char_type(std::uint8_t x) noexcept
9636  {
9637  return x;
9638  }
9639 
9640  template < typename InputCharType, typename C = CharType,
9641  enable_if_t <
9643  std::is_signed<char>::value and
9644  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
9645  > * = nullptr >
9646  static constexpr CharType to_char_type(InputCharType x) noexcept
9647  {
9648  return x;
9649  }
9650 
9651  private:
9653  const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
9654 
9657 };
9658 } // namespace detail
9659 } // namespace nlohmann
9660 
9661 // #include <nlohmann/detail/output/serializer.hpp>
9662 
9663 
9664 #include <algorithm> // reverse, remove, fill, find, none_of
9665 #include <array> // array
9666 #include <cassert> // assert
9667 #include <ciso646> // and, or
9668 #include <clocale> // localeconv, lconv
9669 #include <cmath> // labs, isfinite, isnan, signbit
9670 #include <cstddef> // size_t, ptrdiff_t
9671 #include <cstdint> // uint8_t
9672 #include <cstdio> // snprintf
9673 #include <limits> // numeric_limits
9674 #include <string> // string
9675 #include <type_traits> // is_same
9676 
9677 // #include <nlohmann/detail/exceptions.hpp>
9678 
9679 // #include <nlohmann/detail/conversions/to_chars.hpp>
9680 
9681 
9682 #include <cassert> // assert
9683 #include <ciso646> // or, and, not
9684 #include <cmath> // signbit, isfinite
9685 #include <cstdint> // intN_t, uintN_t
9686 #include <cstring> // memcpy, memmove
9687 
9688 namespace nlohmann
9689 {
9690 namespace detail
9691 {
9692 
9712 namespace dtoa_impl
9713 {
9714 
9715 template <typename Target, typename Source>
9716 Target reinterpret_bits(const Source source)
9717 {
9718  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
9719 
9720  Target target;
9721  std::memcpy(&target, &source, sizeof(Source));
9722  return target;
9723 }
9724 
9725 struct diyfp // f * 2^e
9726 {
9727  static constexpr int kPrecision = 64; // = q
9728 
9729  uint64_t f = 0;
9730  int e = 0;
9731 
9732  constexpr diyfp(uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
9733 
9738  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
9739  {
9740  assert(x.e == y.e);
9741  assert(x.f >= y.f);
9742 
9743  return {x.f - y.f, x.e};
9744  }
9745 
9750  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
9751  {
9752  static_assert(kPrecision == 64, "internal error");
9753 
9754  // Computes:
9755  // f = round((x.f * y.f) / 2^q)
9756  // e = x.e + y.e + q
9757 
9758  // Emulate the 64-bit * 64-bit multiplication:
9759  //
9760  // p = u * v
9761  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
9762  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
9763  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
9764  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
9765  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
9766  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
9767  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
9768  //
9769  // (Since Q might be larger than 2^32 - 1)
9770  //
9771  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
9772  //
9773  // (Q_hi + H does not overflow a 64-bit int)
9774  //
9775  // = p_lo + 2^64 p_hi
9776 
9777  const uint64_t u_lo = x.f & 0xFFFFFFFF;
9778  const uint64_t u_hi = x.f >> 32;
9779  const uint64_t v_lo = y.f & 0xFFFFFFFF;
9780  const uint64_t v_hi = y.f >> 32;
9781 
9782  const uint64_t p0 = u_lo * v_lo;
9783  const uint64_t p1 = u_lo * v_hi;
9784  const uint64_t p2 = u_hi * v_lo;
9785  const uint64_t p3 = u_hi * v_hi;
9786 
9787  const uint64_t p0_hi = p0 >> 32;
9788  const uint64_t p1_lo = p1 & 0xFFFFFFFF;
9789  const uint64_t p1_hi = p1 >> 32;
9790  const uint64_t p2_lo = p2 & 0xFFFFFFFF;
9791  const uint64_t p2_hi = p2 >> 32;
9792 
9793  uint64_t Q = p0_hi + p1_lo + p2_lo;
9794 
9795  // The full product might now be computed as
9796  //
9797  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
9798  // p_lo = p0_lo + (Q << 32)
9799  //
9800  // But in this particular case here, the full p_lo is not required.
9801  // Effectively we only need to add the highest bit in p_lo to p_hi (and
9802  // Q_hi + 1 does not overflow).
9803 
9804  Q += uint64_t{1} << (64 - 32 - 1); // round, ties up
9805 
9806  const uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32);
9807 
9808  return {h, x.e + y.e + 64};
9809  }
9810 
9815  static diyfp normalize(diyfp x) noexcept
9816  {
9817  assert(x.f != 0);
9818 
9819  while ((x.f >> 63) == 0)
9820  {
9821  x.f <<= 1;
9822  x.e--;
9823  }
9824 
9825  return x;
9826  }
9827 
9832  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
9833  {
9834  const int delta = x.e - target_exponent;
9835 
9836  assert(delta >= 0);
9837  assert(((x.f << delta) >> delta) == x.f);
9838 
9839  return {x.f << delta, target_exponent};
9840  }
9841 };
9842 
9844 {
9848 };
9849 
9856 template <typename FloatType>
9858 {
9859  assert(std::isfinite(value));
9860  assert(value > 0);
9861 
9862  // Convert the IEEE representation into a diyfp.
9863  //
9864  // If v is denormal:
9865  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
9866  // If v is normalized:
9867  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
9868 
9869  static_assert(std::numeric_limits<FloatType>::is_iec559,
9870  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
9871 
9872  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
9873  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
9874  constexpr int kMinExp = 1 - kBias;
9875  constexpr uint64_t kHiddenBit = uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
9876 
9877  using bits_type = typename std::conditional< kPrecision == 24, uint32_t, uint64_t >::type;
9878 
9879  const uint64_t bits = reinterpret_bits<bits_type>(value);
9880  const uint64_t E = bits >> (kPrecision - 1);
9881  const uint64_t F = bits & (kHiddenBit - 1);
9882 
9883  const bool is_denormal = (E == 0);
9884  const diyfp v = is_denormal
9885  ? diyfp(F, kMinExp)
9886  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
9887 
9888  // Compute the boundaries m- and m+ of the floating-point value
9889  // v = f * 2^e.
9890  //
9891  // Determine v- and v+, the floating-point predecessor and successor if v,
9892  // respectively.
9893  //
9894  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
9895  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
9896  //
9897  // v+ = v + 2^e
9898  //
9899  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
9900  // between m- and m+ round to v, regardless of how the input rounding
9901  // algorithm breaks ties.
9902  //
9903  // ---+-------------+-------------+-------------+-------------+--- (A)
9904  // v- m- v m+ v+
9905  //
9906  // -----------------+------+------+-------------+-------------+--- (B)
9907  // v- m- v m+ v+
9908 
9909  const bool lower_boundary_is_closer = (F == 0 and E > 1);
9910  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
9911  const diyfp m_minus = lower_boundary_is_closer
9912  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
9913  : diyfp(2 * v.f - 1, v.e - 1); // (A)
9914 
9915  // Determine the normalized w+ = m+.
9916  const diyfp w_plus = diyfp::normalize(m_plus);
9917 
9918  // Determine w- = m- such that e_(w-) = e_(w+).
9919  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
9920 
9921  return {diyfp::normalize(v), w_minus, w_plus};
9922 }
9923 
9924 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
9925 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
9926 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
9927 //
9928 // alpha <= e = e_c + e_w + q <= gamma
9929 //
9930 // or
9931 //
9932 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
9933 // <= f_c * f_w * 2^gamma
9934 //
9935 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
9936 //
9937 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
9938 //
9939 // or
9940 //
9941 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
9942 //
9943 // The choice of (alpha,gamma) determines the size of the table and the form of
9944 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
9945 // in practice:
9946 //
9947 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
9948 // processed independently: An integral part p1, and a fractional part p2:
9949 //
9950 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
9951 // = (f div 2^-e) + (f mod 2^-e) * 2^e
9952 // = p1 + p2 * 2^e
9953 //
9954 // The conversion of p1 into decimal form requires a series of divisions and
9955 // modulos by (a power of) 10. These operations are faster for 32-bit than for
9956 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
9957 // achieved by choosing
9958 //
9959 // -e >= 32 or e <= -32 := gamma
9960 //
9961 // In order to convert the fractional part
9962 //
9963 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
9964 //
9965 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
9966 // d[-i] are extracted in order:
9967 //
9968 // (10 * p2) div 2^-e = d[-1]
9969 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
9970 //
9971 // The multiplication by 10 must not overflow. It is sufficient to choose
9972 //
9973 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
9974 //
9975 // Since p2 = f mod 2^-e < 2^-e,
9976 //
9977 // -e <= 60 or e >= -60 := alpha
9978 
9979 constexpr int kAlpha = -60;
9980 constexpr int kGamma = -32;
9981 
9982 struct cached_power // c = f * 2^e ~= 10^k
9983 {
9984  uint64_t f;
9985  int e;
9986  int k;
9987 };
9988 
9997 {
9998  // Now
9999  //
10000  // alpha <= e_c + e + q <= gamma (1)
10001  // ==> f_c * 2^alpha <= c * 2^e * 2^q
10002  //
10003  // and since the c's are normalized, 2^(q-1) <= f_c,
10004  //
10005  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
10006  // ==> 2^(alpha - e - 1) <= c
10007  //
10008  // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
10009  //
10010  // k = ceil( log_10( 2^(alpha - e - 1) ) )
10011  // = ceil( (alpha - e - 1) * log_10(2) )
10012  //
10013  // From the paper:
10014  // "In theory the result of the procedure could be wrong since c is rounded,
10015  // and the computation itself is approximated [...]. In practice, however,
10016  // this simple function is sufficient."
10017  //
10018  // For IEEE double precision floating-point numbers converted into
10019  // normalized diyfp's w = f * 2^e, with q = 64,
10020  //
10021  // e >= -1022 (min IEEE exponent)
10022  // -52 (p - 1)
10023  // -52 (p - 1, possibly normalize denormal IEEE numbers)
10024  // -11 (normalize the diyfp)
10025  // = -1137
10026  //
10027  // and
10028  //
10029  // e <= +1023 (max IEEE exponent)
10030  // -52 (p - 1)
10031  // -11 (normalize the diyfp)
10032  // = 960
10033  //
10034  // This binary exponent range [-1137,960] results in a decimal exponent
10035  // range [-307,324]. One does not need to store a cached power for each
10036  // k in this range. For each such k it suffices to find a cached power
10037  // such that the exponent of the product lies in [alpha,gamma].
10038  // This implies that the difference of the decimal exponents of adjacent
10039  // table entries must be less than or equal to
10040  //
10041  // floor( (gamma - alpha) * log_10(2) ) = 8.
10042  //
10043  // (A smaller distance gamma-alpha would require a larger table.)
10044 
10045  // NB:
10046  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
10047 
10048  constexpr int kCachedPowersSize = 79;
10049  constexpr int kCachedPowersMinDecExp = -300;
10050  constexpr int kCachedPowersDecStep = 8;
10051 
10052  static constexpr cached_power kCachedPowers[] =
10053  {
10054  { 0xAB70FE17C79AC6CA, -1060, -300 },
10055  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
10056  { 0xBE5691EF416BD60C, -1007, -284 },
10057  { 0x8DD01FAD907FFC3C, -980, -276 },
10058  { 0xD3515C2831559A83, -954, -268 },
10059  { 0x9D71AC8FADA6C9B5, -927, -260 },
10060  { 0xEA9C227723EE8BCB, -901, -252 },
10061  { 0xAECC49914078536D, -874, -244 },
10062  { 0x823C12795DB6CE57, -847, -236 },
10063  { 0xC21094364DFB5637, -821, -228 },
10064  { 0x9096EA6F3848984F, -794, -220 },
10065  { 0xD77485CB25823AC7, -768, -212 },
10066  { 0xA086CFCD97BF97F4, -741, -204 },
10067  { 0xEF340A98172AACE5, -715, -196 },
10068  { 0xB23867FB2A35B28E, -688, -188 },
10069  { 0x84C8D4DFD2C63F3B, -661, -180 },
10070  { 0xC5DD44271AD3CDBA, -635, -172 },
10071  { 0x936B9FCEBB25C996, -608, -164 },
10072  { 0xDBAC6C247D62A584, -582, -156 },
10073  { 0xA3AB66580D5FDAF6, -555, -148 },
10074  { 0xF3E2F893DEC3F126, -529, -140 },
10075  { 0xB5B5ADA8AAFF80B8, -502, -132 },
10076  { 0x87625F056C7C4A8B, -475, -124 },
10077  { 0xC9BCFF6034C13053, -449, -116 },
10078  { 0x964E858C91BA2655, -422, -108 },
10079  { 0xDFF9772470297EBD, -396, -100 },
10080  { 0xA6DFBD9FB8E5B88F, -369, -92 },
10081  { 0xF8A95FCF88747D94, -343, -84 },
10082  { 0xB94470938FA89BCF, -316, -76 },
10083  { 0x8A08F0F8BF0F156B, -289, -68 },
10084  { 0xCDB02555653131B6, -263, -60 },
10085  { 0x993FE2C6D07B7FAC, -236, -52 },
10086  { 0xE45C10C42A2B3B06, -210, -44 },
10087  { 0xAA242499697392D3, -183, -36 },
10088  { 0xFD87B5F28300CA0E, -157, -28 },
10089  { 0xBCE5086492111AEB, -130, -20 },
10090  { 0x8CBCCC096F5088CC, -103, -12 },
10091  { 0xD1B71758E219652C, -77, -4 },
10092  { 0x9C40000000000000, -50, 4 },
10093  { 0xE8D4A51000000000, -24, 12 },
10094  { 0xAD78EBC5AC620000, 3, 20 },
10095  { 0x813F3978F8940984, 30, 28 },
10096  { 0xC097CE7BC90715B3, 56, 36 },
10097  { 0x8F7E32CE7BEA5C70, 83, 44 },
10098  { 0xD5D238A4ABE98068, 109, 52 },
10099  { 0x9F4F2726179A2245, 136, 60 },
10100  { 0xED63A231D4C4FB27, 162, 68 },
10101  { 0xB0DE65388CC8ADA8, 189, 76 },
10102  { 0x83C7088E1AAB65DB, 216, 84 },
10103  { 0xC45D1DF942711D9A, 242, 92 },
10104  { 0x924D692CA61BE758, 269, 100 },
10105  { 0xDA01EE641A708DEA, 295, 108 },
10106  { 0xA26DA3999AEF774A, 322, 116 },
10107  { 0xF209787BB47D6B85, 348, 124 },
10108  { 0xB454E4A179DD1877, 375, 132 },
10109  { 0x865B86925B9BC5C2, 402, 140 },
10110  { 0xC83553C5C8965D3D, 428, 148 },
10111  { 0x952AB45CFA97A0B3, 455, 156 },
10112  { 0xDE469FBD99A05FE3, 481, 164 },
10113  { 0xA59BC234DB398C25, 508, 172 },
10114  { 0xF6C69A72A3989F5C, 534, 180 },
10115  { 0xB7DCBF5354E9BECE, 561, 188 },
10116  { 0x88FCF317F22241E2, 588, 196 },
10117  { 0xCC20CE9BD35C78A5, 614, 204 },
10118  { 0x98165AF37B2153DF, 641, 212 },
10119  { 0xE2A0B5DC971F303A, 667, 220 },
10120  { 0xA8D9D1535CE3B396, 694, 228 },
10121  { 0xFB9B7CD9A4A7443C, 720, 236 },
10122  { 0xBB764C4CA7A44410, 747, 244 },
10123  { 0x8BAB8EEFB6409C1A, 774, 252 },
10124  { 0xD01FEF10A657842C, 800, 260 },
10125  { 0x9B10A4E5E9913129, 827, 268 },
10126  { 0xE7109BFBA19C0C9D, 853, 276 },
10127  { 0xAC2820D9623BF429, 880, 284 },
10128  { 0x80444B5E7AA7CF85, 907, 292 },
10129  { 0xBF21E44003ACDD2D, 933, 300 },
10130  { 0x8E679C2F5E44FF8F, 960, 308 },
10131  { 0xD433179D9C8CB841, 986, 316 },
10132  { 0x9E19DB92B4E31BA9, 1013, 324 },
10133  };
10134 
10135  // This computation gives exactly the same results for k as
10136  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
10137  // for |e| <= 1500, but doesn't require floating-point operations.
10138  // NB: log_10(2) ~= 78913 / 2^18
10139  assert(e >= -1500);
10140  assert(e <= 1500);
10141  const int f = kAlpha - e - 1;
10142  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
10143 
10144  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
10145  assert(index >= 0);
10146  assert(index < kCachedPowersSize);
10147  static_cast<void>(kCachedPowersSize); // Fix warning.
10148 
10149  const cached_power cached = kCachedPowers[index];
10150  assert(kAlpha <= cached.e + e + 64);
10151  assert(kGamma >= cached.e + e + 64);
10152 
10153  return cached;
10154 }
10155 
10160 inline int find_largest_pow10(const uint32_t n, uint32_t& pow10)
10161 {
10162  // LCOV_EXCL_START
10163  if (n >= 1000000000)
10164  {
10165  pow10 = 1000000000;
10166  return 10;
10167  }
10168  // LCOV_EXCL_STOP
10169  else if (n >= 100000000)
10170  {
10171  pow10 = 100000000;
10172  return 9;
10173  }
10174  else if (n >= 10000000)
10175  {
10176  pow10 = 10000000;
10177  return 8;
10178  }
10179  else if (n >= 1000000)
10180  {
10181  pow10 = 1000000;
10182  return 7;
10183  }
10184  else if (n >= 100000)
10185  {
10186  pow10 = 100000;
10187  return 6;
10188  }
10189  else if (n >= 10000)
10190  {
10191  pow10 = 10000;
10192  return 5;
10193  }
10194  else if (n >= 1000)
10195  {
10196  pow10 = 1000;
10197  return 4;
10198  }
10199  else if (n >= 100)
10200  {
10201  pow10 = 100;
10202  return 3;
10203  }
10204  else if (n >= 10)
10205  {
10206  pow10 = 10;
10207  return 2;
10208  }
10209  else
10210  {
10211  pow10 = 1;
10212  return 1;
10213  }
10214 }
10215 
10216 inline void grisu2_round(char* buf, int len, uint64_t dist, uint64_t delta,
10217  uint64_t rest, uint64_t ten_k)
10218 {
10219  assert(len >= 1);
10220  assert(dist <= delta);
10221  assert(rest <= delta);
10222  assert(ten_k > 0);
10223 
10224  // <--------------------------- delta ---->
10225  // <---- dist --------->
10226  // --------------[------------------+-------------------]--------------
10227  // M- w M+
10228  //
10229  // ten_k
10230  // <------>
10231  // <---- rest ---->
10232  // --------------[------------------+----+--------------]--------------
10233  // w V
10234  // = buf * 10^k
10235  //
10236  // ten_k represents a unit-in-the-last-place in the decimal representation
10237  // stored in buf.
10238  // Decrement buf by ten_k while this takes buf closer to w.
10239 
10240  // The tests are written in this order to avoid overflow in unsigned
10241  // integer arithmetic.
10242 
10243  while (rest < dist
10244  and delta - rest >= ten_k
10245  and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
10246  {
10247  assert(buf[len - 1] != '0');
10248  buf[len - 1]--;
10249  rest += ten_k;
10250  }
10251 }
10252 
10257 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
10258  diyfp M_minus, diyfp w, diyfp M_plus)
10259 {
10260  static_assert(kAlpha >= -60, "internal error");
10261  static_assert(kGamma <= -32, "internal error");
10262 
10263  // Generates the digits (and the exponent) of a decimal floating-point
10264  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
10265  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
10266  //
10267  // <--------------------------- delta ---->
10268  // <---- dist --------->
10269  // --------------[------------------+-------------------]--------------
10270  // M- w M+
10271  //
10272  // Grisu2 generates the digits of M+ from left to right and stops as soon as
10273  // V is in [M-,M+].
10274 
10275  assert(M_plus.e >= kAlpha);
10276  assert(M_plus.e <= kGamma);
10277 
10278  uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
10279  uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
10280 
10281  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
10282  //
10283  // M+ = f * 2^e
10284  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
10285  // = ((p1 ) * 2^-e + (p2 )) * 2^e
10286  // = p1 + p2 * 2^e
10287 
10288  const diyfp one(uint64_t{1} << -M_plus.e, M_plus.e);
10289 
10290  auto 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.)
10291  uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
10292 
10293  // 1)
10294  //
10295  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
10296 
10297  assert(p1 > 0);
10298 
10299  uint32_t pow10;
10300  const int k = find_largest_pow10(p1, pow10);
10301 
10302  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
10303  //
10304  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
10305  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
10306  //
10307  // M+ = p1 + p2 * 2^e
10308  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
10309  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
10310  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
10311  //
10312  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
10313  //
10314  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
10315  //
10316  // but stop as soon as
10317  //
10318  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
10319 
10320  int n = k;
10321  while (n > 0)
10322  {
10323  // Invariants:
10324  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
10325  // pow10 = 10^(n-1) <= p1 < 10^n
10326  //
10327  const uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
10328  const uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
10329  //
10330  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
10331  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
10332  //
10333  assert(d <= 9);
10334  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
10335  //
10336  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
10337  //
10338  p1 = r;
10339  n--;
10340  //
10341  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
10342  // pow10 = 10^n
10343  //
10344 
10345  // Now check if enough digits have been generated.
10346  // Compute
10347  //
10348  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
10349  //
10350  // Note:
10351  // Since rest and delta share the same exponent e, it suffices to
10352  // compare the significands.
10353  const uint64_t rest = (uint64_t{p1} << -one.e) + p2;
10354  if (rest <= delta)
10355  {
10356  // V = buffer * 10^n, with M- <= V <= M+.
10357 
10358  decimal_exponent += n;
10359 
10360  // We may now just stop. But instead look if the buffer could be
10361  // decremented to bring V closer to w.
10362  //
10363  // pow10 = 10^n is now 1 ulp in the decimal representation V.
10364  // The rounding procedure works with diyfp's with an implicit
10365  // exponent of e.
10366  //
10367  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
10368  //
10369  const uint64_t ten_n = uint64_t{pow10} << -one.e;
10370  grisu2_round(buffer, length, dist, delta, rest, ten_n);
10371 
10372  return;
10373  }
10374 
10375  pow10 /= 10;
10376  //
10377  // pow10 = 10^(n-1) <= p1 < 10^n
10378  // Invariants restored.
10379  }
10380 
10381  // 2)
10382  //
10383  // The digits of the integral part have been generated:
10384  //
10385  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
10386  // = buffer + p2 * 2^e
10387  //
10388  // Now generate the digits of the fractional part p2 * 2^e.
10389  //
10390  // Note:
10391  // No decimal point is generated: the exponent is adjusted instead.
10392  //
10393  // p2 actually represents the fraction
10394  //
10395  // p2 * 2^e
10396  // = p2 / 2^-e
10397  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
10398  //
10399  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
10400  //
10401  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
10402  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
10403  //
10404  // using
10405  //
10406  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
10407  // = ( d) * 2^-e + ( r)
10408  //
10409  // or
10410  // 10^m * p2 * 2^e = d + r * 2^e
10411  //
10412  // i.e.
10413  //
10414  // M+ = buffer + p2 * 2^e
10415  // = buffer + 10^-m * (d + r * 2^e)
10416  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
10417  //
10418  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
10419 
10420  assert(p2 > delta);
10421 
10422  int m = 0;
10423  for (;;)
10424  {
10425  // Invariant:
10426  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
10427  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
10428  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
10429  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
10430  //
10431  assert(p2 <= UINT64_MAX / 10);
10432  p2 *= 10;
10433  const uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
10434  const uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
10435  //
10436  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
10437  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
10438  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
10439  //
10440  assert(d <= 9);
10441  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
10442  //
10443  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
10444  //
10445  p2 = r;
10446  m++;
10447  //
10448  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
10449  // Invariant restored.
10450 
10451  // Check if enough digits have been generated.
10452  //
10453  // 10^-m * p2 * 2^e <= delta * 2^e
10454  // p2 * 2^e <= 10^m * delta * 2^e
10455  // p2 <= 10^m * delta
10456  delta *= 10;
10457  dist *= 10;
10458  if (p2 <= delta)
10459  {
10460  break;
10461  }
10462  }
10463 
10464  // V = buffer * 10^-m, with M- <= V <= M+.
10465 
10466  decimal_exponent -= m;
10467 
10468  // 1 ulp in the decimal representation is now 10^-m.
10469  // Since delta and dist are now scaled by 10^m, we need to do the
10470  // same with ulp in order to keep the units in sync.
10471  //
10472  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
10473  //
10474  const uint64_t ten_m = one.f;
10475  grisu2_round(buffer, length, dist, delta, p2, ten_m);
10476 
10477  // By construction this algorithm generates the shortest possible decimal
10478  // number (Loitsch, Theorem 6.2) which rounds back to w.
10479  // For an input number of precision p, at least
10480  //
10481  // N = 1 + ceil(p * log_10(2))
10482  //
10483  // decimal digits are sufficient to identify all binary floating-point
10484  // numbers (Matula, "In-and-Out conversions").
10485  // This implies that the algorithm does not produce more than N decimal
10486  // digits.
10487  //
10488  // N = 17 for p = 53 (IEEE double precision)
10489  // N = 9 for p = 24 (IEEE single precision)
10490 }
10491 
10497 inline void grisu2(char* buf, int& len, int& decimal_exponent,
10498  diyfp m_minus, diyfp v, diyfp m_plus)
10499 {
10500  assert(m_plus.e == m_minus.e);
10501  assert(m_plus.e == v.e);
10502 
10503  // --------(-----------------------+-----------------------)-------- (A)
10504  // m- v m+
10505  //
10506  // --------------------(-----------+-----------------------)-------- (B)
10507  // m- v m+
10508  //
10509  // First scale v (and m- and m+) such that the exponent is in the range
10510  // [alpha, gamma].
10511 
10512  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
10513 
10514  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
10515 
10516  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
10517  const diyfp w = diyfp::mul(v, c_minus_k);
10518  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
10519  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
10520 
10521  // ----(---+---)---------------(---+---)---------------(---+---)----
10522  // w- w w+
10523  // = c*m- = c*v = c*m+
10524  //
10525  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
10526  // w+ are now off by a small amount.
10527  // In fact:
10528  //
10529  // w - v * 10^k < 1 ulp
10530  //
10531  // To account for this inaccuracy, add resp. subtract 1 ulp.
10532  //
10533  // --------+---[---------------(---+---)---------------]---+--------
10534  // w- M- w M+ w+
10535  //
10536  // Now any number in [M-, M+] (bounds included) will round to w when input,
10537  // regardless of how the input rounding algorithm breaks ties.
10538  //
10539  // And digit_gen generates the shortest possible such number in [M-, M+].
10540  // Note that this does not mean that Grisu2 always generates the shortest
10541  // possible number in the interval (m-, m+).
10542  const diyfp M_minus(w_minus.f + 1, w_minus.e);
10543  const diyfp M_plus (w_plus.f - 1, w_plus.e );
10544 
10545  decimal_exponent = -cached.k; // = -(-k) = k
10546 
10547  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
10548 }
10549 
10555 template <typename FloatType>
10556 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
10557 {
10558  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
10559  "internal error: not enough precision");
10560 
10561  assert(std::isfinite(value));
10562  assert(value > 0);
10563 
10564  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
10565  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
10566  // decimal representations are not exactly "short".
10567  //
10568  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
10569  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
10570  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
10571  // does.
10572  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
10573  // representation using the corresponding std::from_chars function recovers value exactly". That
10574  // indicates that single precision floating-point numbers should be recovered using
10575  // 'std::strtof'.
10576  //
10577  // NB: If the neighbors are computed for single-precision numbers, there is a single float
10578  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
10579  // value is off by 1 ulp.
10580 #if 0
10581  const boundaries w = compute_boundaries(static_cast<double>(value));
10582 #else
10583  const boundaries w = compute_boundaries(value);
10584 #endif
10585 
10586  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
10587 }
10588 
10594 inline char* append_exponent(char* buf, int e)
10595 {
10596  assert(e > -1000);
10597  assert(e < 1000);
10598 
10599  if (e < 0)
10600  {
10601  e = -e;
10602  *buf++ = '-';
10603  }
10604  else
10605  {
10606  *buf++ = '+';
10607  }
10608 
10609  auto k = static_cast<uint32_t>(e);
10610  if (k < 10)
10611  {
10612  // Always print at least two digits in the exponent.
10613  // This is for compatibility with printf("%g").
10614  *buf++ = '0';
10615  *buf++ = static_cast<char>('0' + k);
10616  }
10617  else if (k < 100)
10618  {
10619  *buf++ = static_cast<char>('0' + k / 10);
10620  k %= 10;
10621  *buf++ = static_cast<char>('0' + k);
10622  }
10623  else
10624  {
10625  *buf++ = static_cast<char>('0' + k / 100);
10626  k %= 100;
10627  *buf++ = static_cast<char>('0' + k / 10);
10628  k %= 10;
10629  *buf++ = static_cast<char>('0' + k);
10630  }
10631 
10632  return buf;
10633 }
10634 
10644 inline char* format_buffer(char* buf, int len, int decimal_exponent,
10645  int min_exp, int max_exp)
10646 {
10647  assert(min_exp < 0);
10648  assert(max_exp > 0);
10649 
10650  const int k = len;
10651  const int n = len + decimal_exponent;
10652 
10653  // v = buf * 10^(n-k)
10654  // k is the length of the buffer (number of decimal digits)
10655  // n is the position of the decimal point relative to the start of the buffer.
10656 
10657  if (k <= n and n <= max_exp)
10658  {
10659  // digits[000]
10660  // len <= max_exp + 2
10661 
10662  std::memset(buf + k, '0', static_cast<size_t>(n - k));
10663  // Make it look like a floating-point number (#362, #378)
10664  buf[n + 0] = '.';
10665  buf[n + 1] = '0';
10666  return buf + (n + 2);
10667  }
10668 
10669  if (0 < n and n <= max_exp)
10670  {
10671  // dig.its
10672  // len <= max_digits10 + 1
10673 
10674  assert(k > n);
10675 
10676  std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
10677  buf[n] = '.';
10678  return buf + (k + 1);
10679  }
10680 
10681  if (min_exp < n and n <= 0)
10682  {
10683  // 0.[000]digits
10684  // len <= 2 + (-min_exp - 1) + max_digits10
10685 
10686  std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
10687  buf[0] = '0';
10688  buf[1] = '.';
10689  std::memset(buf + 2, '0', static_cast<size_t>(-n));
10690  return buf + (2 + (-n) + k);
10691  }
10692 
10693  if (k == 1)
10694  {
10695  // dE+123
10696  // len <= 1 + 5
10697 
10698  buf += 1;
10699  }
10700  else
10701  {
10702  // d.igitsE+123
10703  // len <= max_digits10 + 1 + 5
10704 
10705  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
10706  buf[1] = '.';
10707  buf += 1 + k;
10708  }
10709 
10710  *buf++ = 'e';
10711  return append_exponent(buf, n - 1);
10712 }
10713 
10714 } // namespace dtoa_impl
10715 
10726 template <typename FloatType>
10727 char* to_chars(char* first, const char* last, FloatType value)
10728 {
10729  static_cast<void>(last); // maybe unused - fix warning
10730  assert(std::isfinite(value));
10731 
10732  // Use signbit(value) instead of (value < 0) since signbit works for -0.
10733  if (std::signbit(value))
10734  {
10735  value = -value;
10736  *first++ = '-';
10737  }
10738 
10739  if (value == 0) // +-0
10740  {
10741  *first++ = '0';
10742  // Make it look like a floating-point number (#362, #378)
10743  *first++ = '.';
10744  *first++ = '0';
10745  return first;
10746  }
10747 
10748  assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
10749 
10750  // Compute v = buffer * 10^decimal_exponent.
10751  // The decimal digits are stored in the buffer, which needs to be interpreted
10752  // as an unsigned decimal integer.
10753  // len is the length of the buffer, i.e. the number of decimal digits.
10754  int len = 0;
10755  int decimal_exponent = 0;
10756  dtoa_impl::grisu2(first, len, decimal_exponent, value);
10757 
10758  assert(len <= std::numeric_limits<FloatType>::max_digits10);
10759 
10760  // Format the buffer like printf("%.*g", prec, value)
10761  constexpr int kMinExp = -4;
10762  // Use digits10 here to increase compatibility with version 2.
10763  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
10764 
10765  assert(last - first >= kMaxExp + 2);
10766  assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
10767  assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
10768 
10769  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
10770 }
10771 
10772 } // namespace detail
10773 } // namespace nlohmann
10774 
10775 // #include <nlohmann/detail/macro_scope.hpp>
10776 
10777 // #include <nlohmann/detail/meta/cpp_future.hpp>
10778 
10779 // #include <nlohmann/detail/output/binary_writer.hpp>
10780 
10781 // #include <nlohmann/detail/output/output_adapters.hpp>
10782 
10783 // #include <nlohmann/detail/value_t.hpp>
10784 
10785 
10786 namespace nlohmann
10787 {
10788 namespace detail
10789 {
10791 // serialization //
10793 
10796 {
10797  strict,
10798  replace,
10799  ignore
10800 };
10801 
10802 template<typename BasicJsonType>
10804 {
10805  using string_t = typename BasicJsonType::string_t;
10806  using number_float_t = typename BasicJsonType::number_float_t;
10807  using number_integer_t = typename BasicJsonType::number_integer_t;
10808  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10809  static constexpr uint8_t UTF8_ACCEPT = 0;
10810  static constexpr uint8_t UTF8_REJECT = 1;
10811 
10812  public:
10818  serializer(output_adapter_t<char> s, const char ichar,
10819  error_handler_t error_handler_ = error_handler_t::strict)
10820  : o(std::move(s))
10821  , loc(std::localeconv())
10822  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
10823  , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
10824  , indent_char(ichar)
10825  , indent_string(512, indent_char)
10826  , error_handler(error_handler_)
10827  {}
10828 
10829  // delete because of pointer members
10830  serializer(const serializer&) = delete;
10831  serializer& operator=(const serializer&) = delete;
10832  serializer(serializer&&) = delete;
10833  serializer& operator=(serializer&&) = delete;
10834  ~serializer() = default;
10835 
10853  void dump(const BasicJsonType& val, const bool pretty_print,
10854  const bool ensure_ascii,
10855  const unsigned int indent_step,
10856  const unsigned int current_indent = 0)
10857  {
10858  switch (val.m_type)
10859  {
10860  case value_t::object:
10861  {
10862  if (val.m_value.object->empty())
10863  {
10864  o->write_characters("{}", 2);
10865  return;
10866  }
10867 
10868  if (pretty_print)
10869  {
10870  o->write_characters("{\n", 2);
10871 
10872  // variable to hold indentation for recursive calls
10873  const auto new_indent = current_indent + indent_step;
10874  if (JSON_UNLIKELY(indent_string.size() < new_indent))
10875  {
10876  indent_string.resize(indent_string.size() * 2, ' ');
10877  }
10878 
10879  // first n-1 elements
10880  auto i = val.m_value.object->cbegin();
10881  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
10882  {
10883  o->write_characters(indent_string.c_str(), new_indent);
10884  o->write_character('\"');
10885  dump_escaped(i->first, ensure_ascii);
10886  o->write_characters("\": ", 3);
10887  dump(i->second, true, ensure_ascii, indent_step, new_indent);
10888  o->write_characters(",\n", 2);
10889  }
10890 
10891  // last element
10892  assert(i != val.m_value.object->cend());
10893  assert(std::next(i) == val.m_value.object->cend());
10894  o->write_characters(indent_string.c_str(), new_indent);
10895  o->write_character('\"');
10896  dump_escaped(i->first, ensure_ascii);
10897  o->write_characters("\": ", 3);
10898  dump(i->second, true, ensure_ascii, indent_step, new_indent);
10899 
10900  o->write_character('\n');
10901  o->write_characters(indent_string.c_str(), current_indent);
10902  o->write_character('}');
10903  }
10904  else
10905  {
10906  o->write_character('{');
10907 
10908  // first n-1 elements
10909  auto i = val.m_value.object->cbegin();
10910  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
10911  {
10912  o->write_character('\"');
10913  dump_escaped(i->first, ensure_ascii);
10914  o->write_characters("\":", 2);
10915  dump(i->second, false, ensure_ascii, indent_step, current_indent);
10916  o->write_character(',');
10917  }
10918 
10919  // last element
10920  assert(i != val.m_value.object->cend());
10921  assert(std::next(i) == val.m_value.object->cend());
10922  o->write_character('\"');
10923  dump_escaped(i->first, ensure_ascii);
10924  o->write_characters("\":", 2);
10925  dump(i->second, false, ensure_ascii, indent_step, current_indent);
10926 
10927  o->write_character('}');
10928  }
10929 
10930  return;
10931  }
10932 
10933  case value_t::array:
10934  {
10935  if (val.m_value.array->empty())
10936  {
10937  o->write_characters("[]", 2);
10938  return;
10939  }
10940 
10941  if (pretty_print)
10942  {
10943  o->write_characters("[\n", 2);
10944 
10945  // variable to hold indentation for recursive calls
10946  const auto new_indent = current_indent + indent_step;
10947  if (JSON_UNLIKELY(indent_string.size() < new_indent))
10948  {
10949  indent_string.resize(indent_string.size() * 2, ' ');
10950  }
10951 
10952  // first n-1 elements
10953  for (auto i = val.m_value.array->cbegin();
10954  i != val.m_value.array->cend() - 1; ++i)
10955  {
10956  o->write_characters(indent_string.c_str(), new_indent);
10957  dump(*i, true, ensure_ascii, indent_step, new_indent);
10958  o->write_characters(",\n", 2);
10959  }
10960 
10961  // last element
10962  assert(not val.m_value.array->empty());
10963  o->write_characters(indent_string.c_str(), new_indent);
10964  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
10965 
10966  o->write_character('\n');
10967  o->write_characters(indent_string.c_str(), current_indent);
10968  o->write_character(']');
10969  }
10970  else
10971  {
10972  o->write_character('[');
10973 
10974  // first n-1 elements
10975  for (auto i = val.m_value.array->cbegin();
10976  i != val.m_value.array->cend() - 1; ++i)
10977  {
10978  dump(*i, false, ensure_ascii, indent_step, current_indent);
10979  o->write_character(',');
10980  }
10981 
10982  // last element
10983  assert(not val.m_value.array->empty());
10984  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
10985 
10986  o->write_character(']');
10987  }
10988 
10989  return;
10990  }
10991 
10992  case value_t::string:
10993  {
10994  o->write_character('\"');
10995  dump_escaped(*val.m_value.string, ensure_ascii);
10996  o->write_character('\"');
10997  return;
10998  }
10999 
11000  case value_t::boolean:
11001  {
11002  if (val.m_value.boolean)
11003  {
11004  o->write_characters("true", 4);
11005  }
11006  else
11007  {
11008  o->write_characters("false", 5);
11009  }
11010  return;
11011  }
11012 
11014  {
11015  dump_integer(val.m_value.number_integer);
11016  return;
11017  }
11018 
11020  {
11021  dump_integer(val.m_value.number_unsigned);
11022  return;
11023  }
11024 
11025  case value_t::number_float:
11026  {
11027  dump_float(val.m_value.number_float);
11028  return;
11029  }
11030 
11031  case value_t::discarded:
11032  {
11033  o->write_characters("<discarded>", 11);
11034  return;
11035  }
11036 
11037  case value_t::null:
11038  {
11039  o->write_characters("null", 4);
11040  return;
11041  }
11042  }
11043  }
11044 
11045  private:
11060  void dump_escaped(const string_t& s, const bool ensure_ascii)
11061  {
11062  uint32_t codepoint;
11063  uint8_t state = UTF8_ACCEPT;
11064  std::size_t bytes = 0; // number of bytes written to string_buffer
11065 
11066  // number of bytes written at the point of the last valid byte
11067  std::size_t bytes_after_last_accept = 0;
11068  std::size_t undumped_chars = 0;
11069 
11070  for (std::size_t i = 0; i < s.size(); ++i)
11071  {
11072  const auto byte = static_cast<uint8_t>(s[i]);
11073 
11074  switch (decode(state, codepoint, byte))
11075  {
11076  case UTF8_ACCEPT: // decode found a new code point
11077  {
11078  switch (codepoint)
11079  {
11080  case 0x08: // backspace
11081  {
11082  string_buffer[bytes++] = '\\';
11083  string_buffer[bytes++] = 'b';
11084  break;
11085  }
11086 
11087  case 0x09: // horizontal tab
11088  {
11089  string_buffer[bytes++] = '\\';
11090  string_buffer[bytes++] = 't';
11091  break;
11092  }
11093 
11094  case 0x0A: // newline
11095  {
11096  string_buffer[bytes++] = '\\';
11097  string_buffer[bytes++] = 'n';
11098  break;
11099  }
11100 
11101  case 0x0C: // formfeed
11102  {
11103  string_buffer[bytes++] = '\\';
11104  string_buffer[bytes++] = 'f';
11105  break;
11106  }
11107 
11108  case 0x0D: // carriage return
11109  {
11110  string_buffer[bytes++] = '\\';
11111  string_buffer[bytes++] = 'r';
11112  break;
11113  }
11114 
11115  case 0x22: // quotation mark
11116  {
11117  string_buffer[bytes++] = '\\';
11118  string_buffer[bytes++] = '\"';
11119  break;
11120  }
11121 
11122  case 0x5C: // reverse solidus
11123  {
11124  string_buffer[bytes++] = '\\';
11125  string_buffer[bytes++] = '\\';
11126  break;
11127  }
11128 
11129  default:
11130  {
11131  // escape control characters (0x00..0x1F) or, if
11132  // ensure_ascii parameter is used, non-ASCII characters
11133  if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
11134  {
11135  if (codepoint <= 0xFFFF)
11136  {
11137  std::snprintf(string_buffer.data() + bytes, 7, "\\u%04x",
11138  static_cast<uint16_t>(codepoint));
11139  bytes += 6;
11140  }
11141  else
11142  {
11143  std::snprintf(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
11144  static_cast<uint16_t>(0xD7C0 + (codepoint >> 10)),
11145  static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
11146  bytes += 12;
11147  }
11148  }
11149  else
11150  {
11151  // copy byte to buffer (all previous bytes
11152  // been copied have in default case above)
11153  string_buffer[bytes++] = s[i];
11154  }
11155  break;
11156  }
11157  }
11158 
11159  // write buffer and reset index; there must be 13 bytes
11160  // left, as this is the maximal number of bytes to be
11161  // written ("\uxxxx\uxxxx\0") for one code point
11162  if (string_buffer.size() - bytes < 13)
11163  {
11164  o->write_characters(string_buffer.data(), bytes);
11165  bytes = 0;
11166  }
11167 
11168  // remember the byte position of this accept
11169  bytes_after_last_accept = bytes;
11170  undumped_chars = 0;
11171  break;
11172  }
11173 
11174  case UTF8_REJECT: // decode found invalid UTF-8 byte
11175  {
11176  switch (error_handler)
11177  {
11179  {
11180  std::string sn(3, '\0');
11181  snprintf(&sn[0], sn.size(), "%.2X", byte);
11182  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
11183  }
11184 
11187  {
11188  // in case we saw this character the first time, we
11189  // would like to read it again, because the byte
11190  // may be OK for itself, but just not OK for the
11191  // previous sequence
11192  if (undumped_chars > 0)
11193  {
11194  --i;
11195  }
11196 
11197  // reset length buffer to the last accepted index;
11198  // thus removing/ignoring the invalid characters
11199  bytes = bytes_after_last_accept;
11200 
11201  if (error_handler == error_handler_t::replace)
11202  {
11203  // add a replacement character
11204  if (ensure_ascii)
11205  {
11206  string_buffer[bytes++] = '\\';
11207  string_buffer[bytes++] = 'u';
11208  string_buffer[bytes++] = 'f';
11209  string_buffer[bytes++] = 'f';
11210  string_buffer[bytes++] = 'f';
11211  string_buffer[bytes++] = 'd';
11212  }
11213  else
11214  {
11215  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
11216  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
11217  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
11218  }
11219  bytes_after_last_accept = bytes;
11220  }
11221 
11222  undumped_chars = 0;
11223 
11224  // continue processing the string
11225  state = UTF8_ACCEPT;
11226  break;
11227  }
11228  }
11229  break;
11230  }
11231 
11232  default: // decode found yet incomplete multi-byte code point
11233  {
11234  if (not ensure_ascii)
11235  {
11236  // code point will not be escaped - copy byte to buffer
11237  string_buffer[bytes++] = s[i];
11238  }
11239  ++undumped_chars;
11240  break;
11241  }
11242  }
11243  }
11244 
11245  // we finished processing the string
11246  if (JSON_LIKELY(state == UTF8_ACCEPT))
11247  {
11248  // write buffer
11249  if (bytes > 0)
11250  {
11251  o->write_characters(string_buffer.data(), bytes);
11252  }
11253  }
11254  else
11255  {
11256  // we finish reading, but do not accept: string was incomplete
11257  switch (error_handler)
11258  {
11260  {
11261  std::string sn(3, '\0');
11262  snprintf(&sn[0], sn.size(), "%.2X", static_cast<uint8_t>(s.back()));
11263  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
11264  }
11265 
11267  {
11268  // write all accepted bytes
11269  o->write_characters(string_buffer.data(), bytes_after_last_accept);
11270  break;
11271  }
11272 
11274  {
11275  // write all accepted bytes
11276  o->write_characters(string_buffer.data(), bytes_after_last_accept);
11277  // add a replacement character
11278  if (ensure_ascii)
11279  {
11280  o->write_characters("\\ufffd", 6);
11281  }
11282  else
11283  {
11284  o->write_characters("\xEF\xBF\xBD", 3);
11285  }
11286  break;
11287  }
11288  }
11289  }
11290  }
11291 
11301  template<typename NumberType, detail::enable_if_t<
11304  int> = 0>
11305  void dump_integer(NumberType x)
11306  {
11307  // special case for "0"
11308  if (x == 0)
11309  {
11310  o->write_character('0');
11311  return;
11312  }
11313 
11314  const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not (x >= 0); // see issue #755
11315  std::size_t i = 0;
11316 
11317  while (x != 0)
11318  {
11319  // spare 1 byte for '\0'
11320  assert(i < number_buffer.size() - 1);
11321 
11322  const auto digit = std::labs(static_cast<long>(x % 10));
11323  number_buffer[i++] = static_cast<char>('0' + digit);
11324  x /= 10;
11325  }
11326 
11327  if (is_negative)
11328  {
11329  // make sure there is capacity for the '-'
11330  assert(i < number_buffer.size() - 2);
11331  number_buffer[i++] = '-';
11332  }
11333 
11334  std::reverse(number_buffer.begin(), number_buffer.begin() + i);
11335  o->write_characters(number_buffer.data(), i);
11336  }
11337 
11347  {
11348  // NaN / inf
11349  if (not std::isfinite(x))
11350  {
11351  o->write_characters("null", 4);
11352  return;
11353  }
11354 
11355  // If number_float_t is an IEEE-754 single or double precision number,
11356  // use the Grisu2 algorithm to produce short numbers which are
11357  // guaranteed to round-trip, using strtof and strtod, resp.
11358  //
11359  // NB: The test below works if <long double> == <double>.
11360  static constexpr bool is_ieee_single_or_double
11361  = (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
11362  (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);
11363 
11364  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
11365  }
11366 
11367  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
11368  {
11369  char* begin = number_buffer.data();
11370  char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
11371 
11372  o->write_characters(begin, static_cast<size_t>(end - begin));
11373  }
11374 
11375  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
11376  {
11377  // get number of digits for a float -> text -> float round-trip
11378  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
11379 
11380  // the actual conversion
11381  std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
11382 
11383  // negative value indicates an error
11384  assert(len > 0);
11385  // check if buffer was large enough
11386  assert(static_cast<std::size_t>(len) < number_buffer.size());
11387 
11388  // erase thousands separator
11389  if (thousands_sep != '\0')
11390  {
11391  const auto end = std::remove(number_buffer.begin(),
11392  number_buffer.begin() + len, thousands_sep);
11393  std::fill(end, number_buffer.end(), '\0');
11394  assert((end - number_buffer.begin()) <= len);
11395  len = (end - number_buffer.begin());
11396  }
11397 
11398  // convert decimal point to '.'
11399  if (decimal_point != '\0' and decimal_point != '.')
11400  {
11401  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
11402  if (dec_pos != number_buffer.end())
11403  {
11404  *dec_pos = '.';
11405  }
11406  }
11407 
11408  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
11409 
11410  // determine if need to append ".0"
11411  const bool value_is_int_like =
11412  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
11413  [](char c)
11414  {
11415  return (c == '.' or c == 'e');
11416  });
11417 
11418  if (value_is_int_like)
11419  {
11420  o->write_characters(".0", 2);
11421  }
11422  }
11423 
11445  static uint8_t decode(uint8_t& state, uint32_t& codep, const uint8_t byte) noexcept
11446  {
11447  static const std::array<uint8_t, 400> utf8d =
11448  {
11449  {
11450  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
11451  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
11452  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
11453  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
11454  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
11455  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
11456  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
11457  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
11458  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
11459  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
11460  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
11461  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
11462  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
11463  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
11464  }
11465  };
11466 
11467  const uint8_t type = utf8d[byte];
11468 
11469  codep = (state != UTF8_ACCEPT)
11470  ? (byte & 0x3fu) | (codep << 6)
11471  : static_cast<uint32_t>(0xff >> type) & (byte);
11472 
11473  state = utf8d[256u + state * 16u + type];
11474  return state;
11475  }
11476 
11477  private:
11480 
11482  std::array<char, 64> number_buffer{{}};
11483 
11485  const std::lconv* loc = nullptr;
11487  const char thousands_sep = '\0';
11489  const char decimal_point = '\0';
11490 
11492  std::array<char, 512> string_buffer{{}};
11493 
11495  const char indent_char;
11498 
11501 };
11502 } // namespace detail
11503 } // namespace nlohmann
11504 
11505 // #include <nlohmann/detail/json_ref.hpp>
11506 
11507 
11508 #include <initializer_list>
11509 #include <utility>
11510 
11511 // #include <nlohmann/detail/meta/type_traits.hpp>
11512 
11513 
11514 namespace nlohmann
11515 {
11516 namespace detail
11517 {
11518 template<typename BasicJsonType>
11520 {
11521  public:
11522  using value_type = BasicJsonType;
11523 
11525  : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
11526  {}
11527 
11529  : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
11530  {}
11531 
11532  json_ref(std::initializer_list<json_ref> init)
11533  : owned_value(init), value_ref(&owned_value), is_rvalue(true)
11534  {}
11535 
11536  template <
11537  class... Args,
11538  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
11539  json_ref(Args && ... args)
11540  : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
11541  is_rvalue(true) {}
11542 
11543  // class should be movable only
11544  json_ref(json_ref&&) = default;
11545  json_ref(const json_ref&) = delete;
11546  json_ref& operator=(const json_ref&) = delete;
11547  json_ref& operator=(json_ref&&) = delete;
11548  ~json_ref() = default;
11549 
11550  value_type moved_or_copied() const
11551  {
11552  if (is_rvalue)
11553  {
11554  return std::move(*value_ref);
11555  }
11556  return *value_ref;
11557  }
11558 
11559  value_type const& operator*() const
11560  {
11561  return *static_cast<value_type const*>(value_ref);
11562  }
11563 
11564  value_type const* operator->() const
11565  {
11566  return static_cast<value_type const*>(value_ref);
11567  }
11568 
11569  private:
11570  mutable value_type owned_value = nullptr;
11571  value_type* value_ref = nullptr;
11572  const bool is_rvalue;
11573 };
11574 } // namespace detail
11575 } // namespace nlohmann
11576 
11577 // #include <nlohmann/detail/json_pointer.hpp>
11578 
11579 
11580 #include <cassert> // assert
11581 #include <numeric> // accumulate
11582 #include <string> // string
11583 #include <vector> // vector
11584 
11585 // #include <nlohmann/detail/macro_scope.hpp>
11586 
11587 // #include <nlohmann/detail/exceptions.hpp>
11588 
11589 // #include <nlohmann/detail/value_t.hpp>
11590 
11591 
11592 namespace nlohmann
11593 {
11594 template<typename BasicJsonType>
11595 class json_pointer
11596 {
11597  // allow basic_json to access private members
11599  friend class basic_json;
11600 
11601  public:
11623  explicit json_pointer(const std::string& s = "")
11624  : reference_tokens(split(s))
11625  {}
11626 
11643  {
11644  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11645  std::string{},
11646  [](const std::string & a, const std::string & b)
11647  {
11648  return a + "/" + escape(b);
11649  });
11650  }
11651 
11653  operator std::string() const
11654  {
11655  return to_string();
11656  }
11657 
11665  static int array_index(const std::string& s)
11666  {
11667  std::size_t processed_chars = 0;
11668  const int res = std::stoi(s, &processed_chars);
11669 
11670  // check if the string was completely read
11671  if (JSON_UNLIKELY(processed_chars != s.size()))
11672  {
11673  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11674  }
11675 
11676  return res;
11677  }
11678 
11679  private:
11685  {
11686  if (JSON_UNLIKELY(is_root()))
11687  {
11688  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11689  }
11690 
11691  auto last = reference_tokens.back();
11692  reference_tokens.pop_back();
11693  return last;
11694  }
11695 
11697  bool is_root() const noexcept
11698  {
11699  return reference_tokens.empty();
11700  }
11701 
11703  {
11704  if (JSON_UNLIKELY(is_root()))
11705  {
11706  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11707  }
11708 
11709  json_pointer result = *this;
11710  result.reference_tokens = {reference_tokens[0]};
11711  return result;
11712  }
11713 
11722  BasicJsonType& get_and_create(BasicJsonType& j) const
11723  {
11724  using size_type = typename BasicJsonType::size_type;
11725  auto result = &j;
11726 
11727  // in case no reference tokens exist, return a reference to the JSON value
11728  // j which will be overwritten by a primitive value
11729  for (const auto& reference_token : reference_tokens)
11730  {
11731  switch (result->m_type)
11732  {
11733  case detail::value_t::null:
11734  {
11735  if (reference_token == "0")
11736  {
11737  // start a new array if reference token is 0
11738  result = &result->operator[](0);
11739  }
11740  else
11741  {
11742  // start a new object otherwise
11743  result = &result->operator[](reference_token);
11744  }
11745  break;
11746  }
11747 
11749  {
11750  // create an entry in the object
11751  result = &result->operator[](reference_token);
11752  break;
11753  }
11754 
11756  {
11757  // create an entry in the array
11758  JSON_TRY
11759  {
11760  result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
11761  }
11762  JSON_CATCH(std::invalid_argument&)
11763  {
11764  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
11765  }
11766  break;
11767  }
11768 
11769  /*
11770  The following code is only reached if there exists a reference
11771  token _and_ the current value is primitive. In this case, we have
11772  an error situation, because primitive values may only occur as
11773  single value; that is, with an empty list of reference tokens.
11774  */
11775  default:
11776  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11777  }
11778  }
11779 
11780  return *result;
11781  }
11782 
11802  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
11803  {
11804  using size_type = typename BasicJsonType::size_type;
11805  for (const auto& reference_token : reference_tokens)
11806  {
11807  // convert null values to arrays or objects before continuing
11808  if (ptr->m_type == detail::value_t::null)
11809  {
11810  // check if reference token is a number
11811  const bool nums =
11812  std::all_of(reference_token.begin(), reference_token.end(),
11813  [](const char x)
11814  {
11815  return (x >= '0' and x <= '9');
11816  });
11817 
11818  // change value to array for numbers or "-" or to object otherwise
11819  *ptr = (nums or reference_token == "-")
11822  }
11823 
11824  switch (ptr->m_type)
11825  {
11827  {
11828  // use unchecked object access
11829  ptr = &ptr->operator[](reference_token);
11830  break;
11831  }
11832 
11834  {
11835  // error condition (cf. RFC 6901, Sect. 4)
11836  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
11837  {
11839  "array index '" + reference_token +
11840  "' must not begin with '0'"));
11841  }
11842 
11843  if (reference_token == "-")
11844  {
11845  // explicitly treat "-" as index beyond the end
11846  ptr = &ptr->operator[](ptr->m_value.array->size());
11847  }
11848  else
11849  {
11850  // convert array index to number; unchecked access
11851  JSON_TRY
11852  {
11853  ptr = &ptr->operator[](
11854  static_cast<size_type>(array_index(reference_token)));
11855  }
11856  JSON_CATCH(std::invalid_argument&)
11857  {
11858  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
11859  }
11860  }
11861  break;
11862  }
11863 
11864  default:
11865  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11866  }
11867  }
11868 
11869  return *ptr;
11870  }
11871 
11878  BasicJsonType& get_checked(BasicJsonType* ptr) const
11879  {
11880  using size_type = typename BasicJsonType::size_type;
11881  for (const auto& reference_token : reference_tokens)
11882  {
11883  switch (ptr->m_type)
11884  {
11886  {
11887  // note: at performs range check
11888  ptr = &ptr->at(reference_token);
11889  break;
11890  }
11891 
11893  {
11894  if (JSON_UNLIKELY(reference_token == "-"))
11895  {
11896  // "-" always fails the range check
11898  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11899  ") is out of range"));
11900  }
11901 
11902  // error condition (cf. RFC 6901, Sect. 4)
11903  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
11904  {
11906  "array index '" + reference_token +
11907  "' must not begin with '0'"));
11908  }
11909 
11910  // note: at performs range check
11911  JSON_TRY
11912  {
11913  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11914  }
11915  JSON_CATCH(std::invalid_argument&)
11916  {
11917  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
11918  }
11919  break;
11920  }
11921 
11922  default:
11923  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11924  }
11925  }
11926 
11927  return *ptr;
11928  }
11929 
11943  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
11944  {
11945  using size_type = typename BasicJsonType::size_type;
11946  for (const auto& reference_token : reference_tokens)
11947  {
11948  switch (ptr->m_type)
11949  {
11951  {
11952  // use unchecked object access
11953  ptr = &ptr->operator[](reference_token);
11954  break;
11955  }
11956 
11958  {
11959  if (JSON_UNLIKELY(reference_token == "-"))
11960  {
11961  // "-" cannot be used for const access
11963  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11964  ") is out of range"));
11965  }
11966 
11967  // error condition (cf. RFC 6901, Sect. 4)
11968  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
11969  {
11971  "array index '" + reference_token +
11972  "' must not begin with '0'"));
11973  }
11974 
11975  // use unchecked array access
11976  JSON_TRY
11977  {
11978  ptr = &ptr->operator[](
11979  static_cast<size_type>(array_index(reference_token)));
11980  }
11981  JSON_CATCH(std::invalid_argument&)
11982  {
11983  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
11984  }
11985  break;
11986  }
11987 
11988  default:
11989  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11990  }
11991  }
11992 
11993  return *ptr;
11994  }
11995 
12002  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12003  {
12004  using size_type = typename BasicJsonType::size_type;
12005  for (const auto& reference_token : reference_tokens)
12006  {
12007  switch (ptr->m_type)
12008  {
12010  {
12011  // note: at performs range check
12012  ptr = &ptr->at(reference_token);
12013  break;
12014  }
12015 
12017  {
12018  if (JSON_UNLIKELY(reference_token == "-"))
12019  {
12020  // "-" always fails the range check
12022  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12023  ") is out of range"));
12024  }
12025 
12026  // error condition (cf. RFC 6901, Sect. 4)
12027  if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
12028  {
12030  "array index '" + reference_token +
12031  "' must not begin with '0'"));
12032  }
12033 
12034  // note: at performs range check
12035  JSON_TRY
12036  {
12037  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
12038  }
12039  JSON_CATCH(std::invalid_argument&)
12040  {
12041  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12042  }
12043  break;
12044  }
12045 
12046  default:
12047  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12048  }
12049  }
12050 
12051  return *ptr;
12052  }
12053 
12063  static std::vector<std::string> split(const std::string& reference_string)
12064  {
12065  std::vector<std::string> result;
12066 
12067  // special case: empty reference string -> no reference tokens
12068  if (reference_string.empty())
12069  {
12070  return result;
12071  }
12072 
12073  // check if nonempty reference string begins with slash
12074  if (JSON_UNLIKELY(reference_string[0] != '/'))
12075  {
12077  "JSON pointer must be empty or begin with '/' - was: '" +
12078  reference_string + "'"));
12079  }
12080 
12081  // extract the reference tokens:
12082  // - slash: position of the last read slash (or end of string)
12083  // - start: position after the previous slash
12084  for (
12085  // search for the first slash after the first character
12086  std::size_t slash = reference_string.find_first_of('/', 1),
12087  // set the beginning of the first reference token
12088  start = 1;
12089  // we can stop if start == 0 (if slash == std::string::npos)
12090  start != 0;
12091  // set the beginning of the next reference token
12092  // (will eventually be 0 if slash == std::string::npos)
12093  start = (slash == std::string::npos) ? 0 : slash + 1,
12094  // find next slash
12095  slash = reference_string.find_first_of('/', start))
12096  {
12097  // use the text between the beginning of the reference token
12098  // (start) and the last slash (slash).
12099  auto reference_token = reference_string.substr(start, slash - start);
12100 
12101  // check reference tokens are properly escaped
12102  for (std::size_t pos = reference_token.find_first_of('~');
12103  pos != std::string::npos;
12104  pos = reference_token.find_first_of('~', pos + 1))
12105  {
12106  assert(reference_token[pos] == '~');
12107 
12108  // ~ must be followed by 0 or 1
12109  if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
12110  (reference_token[pos + 1] != '0' and
12111  reference_token[pos + 1] != '1')))
12112  {
12113  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12114  }
12115  }
12116 
12117  // finally, store the reference token
12118  unescape(reference_token);
12119  result.push_back(reference_token);
12120  }
12121 
12122  return result;
12123  }
12124 
12138  static void replace_substring(std::string& s, const std::string& f,
12139  const std::string& t)
12140  {
12141  assert(not f.empty());
12142  for (auto pos = s.find(f); // find first occurrence of f
12143  pos != std::string::npos; // make sure f was found
12144  s.replace(pos, f.size(), t), // replace with t, and
12145  pos = s.find(f, pos + t.size())) // find next occurrence of f
12146  {}
12147  }
12148 
12151  {
12152  replace_substring(s, "~", "~0");
12153  replace_substring(s, "/", "~1");
12154  return s;
12155  }
12156 
12158  static void unescape(std::string& s)
12159  {
12160  replace_substring(s, "~1", "/");
12161  replace_substring(s, "~0", "~");
12162  }
12163 
12171  static void flatten(const std::string& reference_string,
12172  const BasicJsonType& value,
12173  BasicJsonType& result)
12174  {
12175  switch (value.m_type)
12176  {
12178  {
12179  if (value.m_value.array->empty())
12180  {
12181  // flatten empty array as null
12182  result[reference_string] = nullptr;
12183  }
12184  else
12185  {
12186  // iterate array and use index as reference string
12187  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12188  {
12189  flatten(reference_string + "/" + std::to_string(i),
12190  value.m_value.array->operator[](i), result);
12191  }
12192  }
12193  break;
12194  }
12195 
12197  {
12198  if (value.m_value.object->empty())
12199  {
12200  // flatten empty object as null
12201  result[reference_string] = nullptr;
12202  }
12203  else
12204  {
12205  // iterate object and use keys as reference string
12206  for (const auto& element : *value.m_value.object)
12207  {
12208  flatten(reference_string + "/" + escape(element.first), element.second, result);
12209  }
12210  }
12211  break;
12212  }
12213 
12214  default:
12215  {
12216  // add primitive value with its reference string
12217  result[reference_string] = value;
12218  break;
12219  }
12220  }
12221  }
12222 
12233  static BasicJsonType
12234  unflatten(const BasicJsonType& value)
12235  {
12236  if (JSON_UNLIKELY(not value.is_object()))
12237  {
12238  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12239  }
12240 
12241  BasicJsonType result;
12242 
12243  // iterate the JSON object values
12244  for (const auto& element : *value.m_value.object)
12245  {
12246  if (JSON_UNLIKELY(not element.second.is_primitive()))
12247  {
12248  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12249  }
12250 
12251  // assign value to reference pointed to by JSON pointer; Note that if
12252  // the JSON pointer is "" (i.e., points to the whole value), function
12253  // get_and_create returns a reference to result itself. An assignment
12254  // will then create a primitive value.
12255  json_pointer(element.first).get_and_create(result) = element.second;
12256  }
12257 
12258  return result;
12259  }
12260 
12261  friend bool operator==(json_pointer const& lhs,
12262  json_pointer const& rhs) noexcept
12263  {
12264  return (lhs.reference_tokens == rhs.reference_tokens);
12265  }
12266 
12267  friend bool operator!=(json_pointer const& lhs,
12268  json_pointer const& rhs) noexcept
12269  {
12270  return not (lhs == rhs);
12271  }
12272 
12274  std::vector<std::string> reference_tokens;
12275 };
12276 } // namespace nlohmann
12277 
12278 // #include <nlohmann/adl_serializer.hpp>
12279 
12280 
12281 #include <utility>
12282 
12283 // #include <nlohmann/detail/conversions/from_json.hpp>
12284 
12285 // #include <nlohmann/detail/conversions/to_json.hpp>
12286 
12287 
12288 namespace nlohmann
12289 {
12290 
12291 template<typename, typename>
12292 struct adl_serializer
12293 {
12303  template<typename BasicJsonType, typename ValueType>
12304  static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
12305  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
12306  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
12307  {
12308  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
12309  }
12310 
12320  template <typename BasicJsonType, typename ValueType>
12321  static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
12322  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
12323  -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
12324  {
12325  ::nlohmann::to_json(j, std::forward<ValueType>(val));
12326  }
12327 };
12328 
12329 } // namespace nlohmann
12330 
12331 
12337 namespace nlohmann
12338 {
12339 
12422 class basic_json
12423 {
12424  private:
12425  template<detail::value_t> friend struct detail::external_constructor;
12426  friend ::nlohmann::json_pointer<basic_json>;
12427  friend ::nlohmann::detail::parser<basic_json>;
12428  friend ::nlohmann::detail::serializer<basic_json>;
12429  template<typename BasicJsonType>
12430  friend class ::nlohmann::detail::iter_impl;
12431  template<typename BasicJsonType, typename CharType>
12432  friend class ::nlohmann::detail::binary_writer;
12433  template<typename BasicJsonType, typename SAX>
12434  friend class ::nlohmann::detail::binary_reader;
12435  template<typename BasicJsonType>
12436  friend class ::nlohmann::detail::json_sax_dom_parser;
12437  template<typename BasicJsonType>
12438  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12439 
12442 
12443  // convenience aliases for types residing in namespace detail;
12446 
12448  template<typename BasicJsonType>
12450  template<typename BasicJsonType>
12452  template<typename Iterator>
12455 
12456  template<typename CharType>
12458 
12461 
12463 
12464  public:
12468  template<typename T, typename SFINAE>
12469  using json_serializer = JSONSerializer<T, SFINAE>;
12473  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
12474 
12478 
12480  // exceptions //
12482 
12486 
12499 
12501 
12502 
12504  // container types //
12506 
12511 
12514 
12518  using const_reference = const value_type&;
12519 
12521  using difference_type = std::ptrdiff_t;
12523  using size_type = std::size_t;
12524 
12526  using allocator_type = AllocatorType<basic_json>;
12527 
12529  using pointer = typename std::allocator_traits<allocator_type>::pointer;
12531  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
12532 
12541 
12543 
12544 
12549  {
12550  return allocator_type();
12551  }
12552 
12579  static basic_json meta()
12580  {
12581  basic_json result;
12582 
12583  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
12584  result["name"] = "JSON for Modern C++";
12585  result["url"] = "https://github.com/nlohmann/json";
12586  result["version"]["string"] =
12587  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
12588  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
12589  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
12590  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
12591  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
12592  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
12593 
12594 #ifdef _WIN32
12595  result["platform"] = "win32";
12596 #elif defined __linux__
12597  result["platform"] = "linux";
12598 #elif defined __APPLE__
12599  result["platform"] = "apple";
12600 #elif defined __unix__
12601  result["platform"] = "unix";
12602 #else
12603  result["platform"] = "unknown";
12604 #endif
12605 
12606 #if defined(__ICC) || defined(__INTEL_COMPILER)
12607  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
12608 #elif defined(__clang__)
12609  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
12610 #elif defined(__GNUC__) || defined(__GNUG__)
12611  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
12612 #elif defined(__HP_cc) || defined(__HP_aCC)
12613  result["compiler"] = "hp"
12614 #elif defined(__IBMCPP__)
12615  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
12616 #elif defined(_MSC_VER)
12617  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
12618 #elif defined(__PGI)
12619  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
12620 #elif defined(__SUNPRO_CC)
12621  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
12622 #else
12623  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
12624 #endif
12625 
12626 #ifdef __cplusplus
12627  result["compiler"]["c++"] = std::to_string(__cplusplus);
12628 #else
12629  result["compiler"]["c++"] = "unknown";
12630 #endif
12631  return result;
12632  }
12633 
12634 
12636  // JSON value data types //
12638 
12643 
12644 #if defined(JSON_HAS_CPP_14)
12645  // Use transparent comparator if possible, combined with perfect forwarding
12646  // on find() and count() calls prevents unnecessary string construction.
12647  using object_comparator_t = std::less<>;
12648 #else
12649  using object_comparator_t = std::less<StringType>;
12650 #endif
12651 
12735  using object_t = ObjectType<StringType,
12736  basic_json,
12738  AllocatorType<std::pair<const StringType,
12739  basic_json>>>;
12740 
12785  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
12786 
12838  using string_t = StringType;
12839 
12864  using boolean_t = BooleanType;
12865 
12936  using number_integer_t = NumberIntegerType;
12937 
13007  using number_unsigned_t = NumberUnsignedType;
13008 
13075  using number_float_t = NumberFloatType;
13076 
13078 
13079  private:
13080 
13082  template<typename T, typename... Args>
13083  static T* create(Args&& ... args)
13084  {
13085  AllocatorType<T> alloc;
13086  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13087 
13088  auto deleter = [&](T * object)
13089  {
13090  AllocatorTraits::deallocate(alloc, object, 1);
13091  };
13092  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13093  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13094  assert(object != nullptr);
13095  return object.release();
13096  }
13097 
13099  // JSON value storage //
13101 
13127  {
13142 
13144  json_value() = default;
13146  json_value(boolean_t v) noexcept : boolean(v) {}
13155  {
13156  switch (t)
13157  {
13158  case value_t::object:
13159  {
13160  object = create<object_t>();
13161  break;
13162  }
13163 
13164  case value_t::array:
13165  {
13166  array = create<array_t>();
13167  break;
13168  }
13169 
13170  case value_t::string:
13171  {
13172  string = create<string_t>("");
13173  break;
13174  }
13175 
13176  case value_t::boolean:
13177  {
13178  boolean = boolean_t(false);
13179  break;
13180  }
13181 
13183  {
13184  number_integer = number_integer_t(0);
13185  break;
13186  }
13187 
13189  {
13190  number_unsigned = number_unsigned_t(0);
13191  break;
13192  }
13193 
13194  case value_t::number_float:
13195  {
13196  number_float = number_float_t(0.0);
13197  break;
13198  }
13199 
13200  case value_t::null:
13201  {
13202  object = nullptr; // silence warning, see #821
13203  break;
13204  }
13205 
13206  default:
13207  {
13208  object = nullptr; // silence warning, see #821
13209  if (JSON_UNLIKELY(t == value_t::null))
13210  {
13211  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.4.0")); // LCOV_EXCL_LINE
13212  }
13213  break;
13214  }
13215  }
13216  }
13217 
13220  {
13221  string = create<string_t>(value);
13222  }
13223 
13226  {
13227  string = create<string_t>(std::move(value));
13228  }
13229 
13232  {
13233  object = create<object_t>(value);
13234  }
13235 
13238  {
13239  object = create<object_t>(std::move(value));
13240  }
13241 
13244  {
13245  array = create<array_t>(value);
13246  }
13247 
13250  {
13251  array = create<array_t>(std::move(value));
13252  }
13253 
13254  void destroy(value_t t) noexcept
13255  {
13256  switch (t)
13257  {
13258  case value_t::object:
13259  {
13260  AllocatorType<object_t> alloc;
13261  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13262  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13263  break;
13264  }
13265 
13266  case value_t::array:
13267  {
13268  AllocatorType<array_t> alloc;
13269  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13270  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13271  break;
13272  }
13273 
13274  case value_t::string:
13275  {
13276  AllocatorType<string_t> alloc;
13277  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13278  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13279  break;
13280  }
13281 
13282  default:
13283  {
13284  break;
13285  }
13286  }
13287  }
13288  };
13289 
13299  void assert_invariant() const noexcept
13300  {
13301  assert(m_type != value_t::object or m_value.object != nullptr);
13302  assert(m_type != value_t::array or m_value.array != nullptr);
13303  assert(m_type != value_t::string or m_value.string != nullptr);
13304  }
13305 
13306  public:
13308  // JSON parser callback //
13310 
13327 
13378 
13380  // constructors //
13382 
13387 
13418  : m_type(v), m_value(v)
13419  {
13420  assert_invariant();
13421  }
13422 
13441  basic_json(std::nullptr_t = nullptr) noexcept
13442  : basic_json(value_t::null)
13443  {
13444  assert_invariant();
13445  }
13446 
13504  template <typename CompatibleType,
13505  typename U = detail::uncvref_t<CompatibleType>,
13508  basic_json(CompatibleType && val) noexcept(noexcept(
13509  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
13510  std::forward<CompatibleType>(val))))
13511  {
13512  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
13513  assert_invariant();
13514  }
13515 
13542  template <typename BasicJsonType,
13545  basic_json(const BasicJsonType& val)
13546  {
13547  using other_boolean_t = typename BasicJsonType::boolean_t;
13548  using other_number_float_t = typename BasicJsonType::number_float_t;
13549  using other_number_integer_t = typename BasicJsonType::number_integer_t;
13550  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
13551  using other_string_t = typename BasicJsonType::string_t;
13552  using other_object_t = typename BasicJsonType::object_t;
13553  using other_array_t = typename BasicJsonType::array_t;
13554 
13555  switch (val.type())
13556  {
13557  case value_t::boolean:
13558  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
13559  break;
13560  case value_t::number_float:
13561  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
13562  break;
13564  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
13565  break;
13567  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
13568  break;
13569  case value_t::string:
13570  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
13571  break;
13572  case value_t::object:
13573  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
13574  break;
13575  case value_t::array:
13576  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
13577  break;
13578  case value_t::null:
13579  *this = nullptr;
13580  break;
13581  case value_t::discarded:
13582  m_type = value_t::discarded;
13583  break;
13584  }
13585  assert_invariant();
13586  }
13587 
13663  bool type_deduction = true,
13664  value_t manual_type = value_t::array)
13665  {
13666  // check if each element is an array with two elements whose first
13667  // element is a string
13668  bool is_an_object = std::all_of(init.begin(), init.end(),
13669  [](const detail::json_ref<basic_json>& element_ref)
13670  {
13671  return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
13672  });
13673 
13674  // adjust type if type deduction is not wanted
13675  if (not type_deduction)
13676  {
13677  // if array is wanted, do not create an object though possible
13678  if (manual_type == value_t::array)
13679  {
13680  is_an_object = false;
13681  }
13682 
13683  // if object is wanted but impossible, throw an exception
13684  if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
13685  {
13686  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
13687  }
13688  }
13689 
13690  if (is_an_object)
13691  {
13692  // the initializer list is a list of pairs -> create object
13693  m_type = value_t::object;
13694  m_value = value_t::object;
13695 
13696  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
13697  {
13698  auto element = element_ref.moved_or_copied();
13699  m_value.object->emplace(
13700  std::move(*((*element.m_value.array)[0].m_value.string)),
13701  std::move((*element.m_value.array)[1]));
13702  });
13703  }
13704  else
13705  {
13706  // the initializer list describes an array -> create array
13707  m_type = value_t::array;
13708  m_value.array = create<array_t>(init.begin(), init.end());
13709  }
13710 
13711  assert_invariant();
13712  }
13713 
13751  static basic_json array(initializer_list_t init = {})
13752  {
13753  return basic_json(init, false, value_t::array);
13754  }
13755 
13794  static basic_json object(initializer_list_t init = {})
13795  {
13796  return basic_json(init, false, value_t::object);
13797  }
13798 
13821  basic_json(size_type cnt, const basic_json& val)
13822  : m_type(value_t::array)
13823  {
13824  m_value.array = create<array_t>(cnt, val);
13825  assert_invariant();
13826  }
13827 
13883  template<class InputIT, typename std::enable_if<
13886  basic_json(InputIT first, InputIT last)
13887  {
13888  assert(first.m_object != nullptr);
13889  assert(last.m_object != nullptr);
13890 
13891  // make sure iterator fits the current value
13892  if (JSON_UNLIKELY(first.m_object != last.m_object))
13893  {
13894  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
13895  }
13896 
13897  // copy type from first iterator
13898  m_type = first.m_object->m_type;
13899 
13900  // check if iterator range is complete for primitive values
13901  switch (m_type)
13902  {
13903  case value_t::boolean:
13904  case value_t::number_float:
13907  case value_t::string:
13908  {
13909  if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
13910  or not last.m_it.primitive_iterator.is_end()))
13911  {
13912  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
13913  }
13914  break;
13915  }
13916 
13917  default:
13918  break;
13919  }
13920 
13921  switch (m_type)
13922  {
13924  {
13925  m_value.number_integer = first.m_object->m_value.number_integer;
13926  break;
13927  }
13928 
13930  {
13931  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
13932  break;
13933  }
13934 
13935  case value_t::number_float:
13936  {
13937  m_value.number_float = first.m_object->m_value.number_float;
13938  break;
13939  }
13940 
13941  case value_t::boolean:
13942  {
13943  m_value.boolean = first.m_object->m_value.boolean;
13944  break;
13945  }
13946 
13947  case value_t::string:
13948  {
13949  m_value = *first.m_object->m_value.string;
13950  break;
13951  }
13952 
13953  case value_t::object:
13954  {
13955  m_value.object = create<object_t>(first.m_it.object_iterator,
13956  last.m_it.object_iterator);
13957  break;
13958  }
13959 
13960  case value_t::array:
13961  {
13962  m_value.array = create<array_t>(first.m_it.array_iterator,
13963  last.m_it.array_iterator);
13964  break;
13965  }
13966 
13967  default:
13968  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
13969  std::string(first.m_object->type_name())));
13970  }
13971 
13972  assert_invariant();
13973  }
13974 
13975 
13977  // other constructors and destructor //
13979 
13982  : basic_json(ref.moved_or_copied())
13983  {}
13984 
14010  basic_json(const basic_json& other)
14011  : m_type(other.m_type)
14012  {
14013  // check of passed value is valid
14014  other.assert_invariant();
14015 
14016  switch (m_type)
14017  {
14018  case value_t::object:
14019  {
14020  m_value = *other.m_value.object;
14021  break;
14022  }
14023 
14024  case value_t::array:
14025  {
14026  m_value = *other.m_value.array;
14027  break;
14028  }
14029 
14030  case value_t::string:
14031  {
14032  m_value = *other.m_value.string;
14033  break;
14034  }
14035 
14036  case value_t::boolean:
14037  {
14038  m_value = other.m_value.boolean;
14039  break;
14040  }
14041 
14043  {
14044  m_value = other.m_value.number_integer;
14045  break;
14046  }
14047 
14049  {
14050  m_value = other.m_value.number_unsigned;
14051  break;
14052  }
14053 
14054  case value_t::number_float:
14055  {
14056  m_value = other.m_value.number_float;
14057  break;
14058  }
14059 
14060  default:
14061  break;
14062  }
14063 
14064  assert_invariant();
14065  }
14066 
14093  basic_json(basic_json&& other) noexcept
14094  : m_type(std::move(other.m_type)),
14095  m_value(std::move(other.m_value))
14096  {
14097  // check that passed value is valid
14098  other.assert_invariant();
14099 
14100  // invalidate payload
14101  other.m_type = value_t::null;
14102  other.m_value = {};
14103 
14104  assert_invariant();
14105  }
14106 
14130  basic_json& operator=(basic_json other) noexcept (
14135  )
14136  {
14137  // check that passed value is valid
14138  other.assert_invariant();
14139 
14140  using std::swap;
14141  swap(m_type, other.m_type);
14142  swap(m_value, other.m_value);
14143 
14144  assert_invariant();
14145  return *this;
14146  }
14147 
14163  ~basic_json() noexcept
14164  {
14165  assert_invariant();
14166  m_value.destroy(m_type);
14167  }
14168 
14170 
14171  public:
14173  // object inspection //
14175 
14179 
14221  string_t dump(const int indent = -1,
14222  const char indent_char = ' ',
14223  const bool ensure_ascii = false,
14224  const error_handler_t error_handler = error_handler_t::strict) const
14225  {
14226  string_t result;
14227  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14228 
14229  if (indent >= 0)
14230  {
14231  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
14232  }
14233  else
14234  {
14235  s.dump(*this, false, ensure_ascii, 0);
14236  }
14237 
14238  return result;
14239  }
14240 
14273  constexpr value_t type() const noexcept
14274  {
14275  return m_type;
14276  }
14277 
14303  constexpr bool is_primitive() const noexcept
14304  {
14305  return is_null() or is_string() or is_boolean() or is_number();
14306  }
14307 
14330  constexpr bool is_structured() const noexcept
14331  {
14332  return is_array() or is_object();
14333  }
14334 
14352  constexpr bool is_null() const noexcept
14353  {
14354  return (m_type == value_t::null);
14355  }
14356 
14374  constexpr bool is_boolean() const noexcept
14375  {
14376  return (m_type == value_t::boolean);
14377  }
14378 
14404  constexpr bool is_number() const noexcept
14405  {
14406  return is_number_integer() or is_number_float();
14407  }
14408 
14433  constexpr bool is_number_integer() const noexcept
14434  {
14435  return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
14436  }
14437 
14461  constexpr bool is_number_unsigned() const noexcept
14462  {
14463  return (m_type == value_t::number_unsigned);
14464  }
14465 
14489  constexpr bool is_number_float() const noexcept
14490  {
14491  return (m_type == value_t::number_float);
14492  }
14493 
14511  constexpr bool is_object() const noexcept
14512  {
14513  return (m_type == value_t::object);
14514  }
14515 
14533  constexpr bool is_array() const noexcept
14534  {
14535  return (m_type == value_t::array);
14536  }
14537 
14555  constexpr bool is_string() const noexcept
14556  {
14557  return (m_type == value_t::string);
14558  }
14559 
14582  constexpr bool is_discarded() const noexcept
14583  {
14584  return (m_type == value_t::discarded);
14585  }
14586 
14608  constexpr operator value_t() const noexcept
14609  {
14610  return m_type;
14611  }
14612 
14614 
14615  private:
14617  // value access //
14619 
14621  boolean_t get_impl(boolean_t* /*unused*/) const
14622  {
14623  if (JSON_LIKELY(is_boolean()))
14624  {
14625  return m_value.boolean;
14626  }
14627 
14628  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
14629  }
14630 
14632  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
14633  {
14634  return is_object() ? m_value.object : nullptr;
14635  }
14636 
14638  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
14639  {
14640  return is_object() ? m_value.object : nullptr;
14641  }
14642 
14644  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
14645  {
14646  return is_array() ? m_value.array : nullptr;
14647  }
14648 
14650  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
14651  {
14652  return is_array() ? m_value.array : nullptr;
14653  }
14654 
14656  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
14657  {
14658  return is_string() ? m_value.string : nullptr;
14659  }
14660 
14662  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
14663  {
14664  return is_string() ? m_value.string : nullptr;
14665  }
14666 
14668  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
14669  {
14670  return is_boolean() ? &m_value.boolean : nullptr;
14671  }
14672 
14674  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
14675  {
14676  return is_boolean() ? &m_value.boolean : nullptr;
14677  }
14678 
14681  {
14682  return is_number_integer() ? &m_value.number_integer : nullptr;
14683  }
14684 
14686  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
14687  {
14688  return is_number_integer() ? &m_value.number_integer : nullptr;
14689  }
14690 
14693  {
14694  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
14695  }
14696 
14698  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
14699  {
14700  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
14701  }
14702 
14705  {
14706  return is_number_float() ? &m_value.number_float : nullptr;
14707  }
14708 
14710  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
14711  {
14712  return is_number_float() ? &m_value.number_float : nullptr;
14713  }
14714 
14726  template<typename ReferenceType, typename ThisType>
14727  static ReferenceType get_ref_impl(ThisType& obj)
14728  {
14729  // delegate the call to get_ptr<>()
14730  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
14731 
14732  if (JSON_LIKELY(ptr != nullptr))
14733  {
14734  return *ptr;
14735  }
14736 
14737  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
14738  }
14739 
14740  public:
14744 
14759  template<typename BasicJsonType, detail::enable_if_t<
14760  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
14761  int> = 0>
14762  basic_json get() const
14763  {
14764  return *this;
14765  }
14766 
14782  template<typename BasicJsonType, detail::enable_if_t<
14785  BasicJsonType get() const
14786  {
14787  return *this;
14788  }
14789 
14829  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
14830  detail::enable_if_t <
14831  not detail::is_basic_json<ValueType>::value and
14832  detail::has_from_json<basic_json_t, ValueType>::value and
14833  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14834  int> = 0>
14835  ValueType get() const noexcept(noexcept(
14836  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
14837  {
14838  // we cannot static_assert on ValueTypeCV being non-const, because
14839  // there is support for get<const basic_json_t>(), which is why we
14840  // still need the uncvref
14841  static_assert(not std::is_reference<ValueTypeCV>::value,
14842  "get() cannot be used with reference types, you might want to use get_ref()");
14844  "types must be DefaultConstructible when used with get()");
14845 
14846  ValueType ret;
14848  return ret;
14849  }
14850 
14882  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
14883  detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
14884  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
14885  int> = 0>
14886  ValueType get() const noexcept(noexcept(
14887  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
14888  {
14889  static_assert(not std::is_reference<ValueTypeCV>::value,
14890  "get() cannot be used with reference types, you might want to use get_ref()");
14892  }
14893 
14927  template<typename ValueType,
14931  int> = 0>
14932  ValueType & get_to(ValueType& v) const noexcept(noexcept(
14933  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
14934  {
14936  return v;
14937  }
14938 
14939 
14966  template<typename PointerType, typename std::enable_if<
14967  std::is_pointer<PointerType>::value, int>::type = 0>
14968  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
14969  {
14970  // delegate the call to get_impl_ptr<>()
14971  return get_impl_ptr(static_cast<PointerType>(nullptr));
14972  }
14973 
14978  template<typename PointerType, typename std::enable_if<
14979  std::is_pointer<PointerType>::value and
14980  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
14981  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
14982  {
14983  // delegate the call to get_impl_ptr<>() const
14984  return get_impl_ptr(static_cast<PointerType>(nullptr));
14985  }
14986 
15014  template<typename PointerType, typename std::enable_if<
15015  std::is_pointer<PointerType>::value, int>::type = 0>
15016  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15017  {
15018  // delegate the call to get_ptr
15019  return get_ptr<PointerType>();
15020  }
15021 
15026  template<typename PointerType, typename std::enable_if<
15027  std::is_pointer<PointerType>::value, int>::type = 0>
15028  constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15029  {
15030  // delegate the call to get_ptr
15031  return get_ptr<PointerType>();
15032  }
15033 
15060  template<typename ReferenceType, typename std::enable_if<
15062  ReferenceType get_ref()
15063  {
15064  // delegate call to get_ref_impl
15065  return get_ref_impl<ReferenceType>(*this);
15066  }
15067 
15072  template<typename ReferenceType, typename std::enable_if<
15073  std::is_reference<ReferenceType>::value and
15074  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
15075  ReferenceType get_ref() const
15076  {
15077  // delegate call to get_ref_impl
15078  return get_ref_impl<ReferenceType>(*this);
15079  }
15080 
15110  template < typename ValueType, typename std::enable_if <
15112  not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15115 
15116 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
15117  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15118 #if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
15120 #endif
15121 #endif
15123  , int >::type = 0 >
15124  operator ValueType() const
15125  {
15126  // delegate the call to get<>() const
15127  return get<ValueType>();
15128  }
15129 
15131 
15132 
15134  // element access //
15136 
15140 
15168  {
15169  // at only works for arrays
15170  if (JSON_LIKELY(is_array()))
15171  {
15172  JSON_TRY
15173  {
15174  return m_value.array->at(idx);
15175  }
15176  JSON_CATCH (std::out_of_range&)
15177  {
15178  // create better exception explanation
15179  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15180  }
15181  }
15182  else
15183  {
15184  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15185  }
15186  }
15187 
15215  {
15216  // at only works for arrays
15217  if (JSON_LIKELY(is_array()))
15218  {
15219  JSON_TRY
15220  {
15221  return m_value.array->at(idx);
15222  }
15223  JSON_CATCH (std::out_of_range&)
15224  {
15225  // create better exception explanation
15226  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15227  }
15228  }
15229  else
15230  {
15231  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15232  }
15233  }
15234 
15265  reference at(const typename object_t::key_type& key)
15266  {
15267  // at only works for objects
15268  if (JSON_LIKELY(is_object()))
15269  {
15270  JSON_TRY
15271  {
15272  return m_value.object->at(key);
15273  }
15274  JSON_CATCH (std::out_of_range&)
15275  {
15276  // create better exception explanation
15277  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15278  }
15279  }
15280  else
15281  {
15282  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15283  }
15284  }
15285 
15316  const_reference at(const typename object_t::key_type& key) const
15317  {
15318  // at only works for objects
15319  if (JSON_LIKELY(is_object()))
15320  {
15321  JSON_TRY
15322  {
15323  return m_value.object->at(key);
15324  }
15325  JSON_CATCH (std::out_of_range&)
15326  {
15327  // create better exception explanation
15328  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15329  }
15330  }
15331  else
15332  {
15333  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15334  }
15335  }
15336 
15363  {
15364  // implicitly convert null value to an empty array
15365  if (is_null())
15366  {
15367  m_type = value_t::array;
15368  m_value.array = create<array_t>();
15369  assert_invariant();
15370  }
15371 
15372  // operator[] only works for arrays
15373  if (JSON_LIKELY(is_array()))
15374  {
15375  // fill up array with null values if given idx is outside range
15376  if (idx >= m_value.array->size())
15377  {
15378  m_value.array->insert(m_value.array->end(),
15379  idx - m_value.array->size() + 1,
15380  basic_json());
15381  }
15382 
15383  return m_value.array->operator[](idx);
15384  }
15385 
15386  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15387  }
15388 
15409  {
15410  // const operator[] only works for arrays
15411  if (JSON_LIKELY(is_array()))
15412  {
15413  return m_value.array->operator[](idx);
15414  }
15415 
15416  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15417  }
15418 
15446  reference operator[](const typename object_t::key_type& key)
15447  {
15448  // implicitly convert null value to an empty object
15449  if (is_null())
15450  {
15451  m_type = value_t::object;
15452  m_value.object = create<object_t>();
15453  assert_invariant();
15454  }
15455 
15456  // operator[] only works for objects
15457  if (JSON_LIKELY(is_object()))
15458  {
15459  return m_value.object->operator[](key);
15460  }
15461 
15462  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15463  }
15464 
15495  const_reference operator[](const typename object_t::key_type& key) const
15496  {
15497  // const operator[] only works for objects
15498  if (JSON_LIKELY(is_object()))
15499  {
15500  assert(m_value.object->find(key) != m_value.object->end());
15501  return m_value.object->find(key)->second;
15502  }
15503 
15504  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15505  }
15506 
15534  template<typename T>
15536  {
15537  // implicitly convert null to object
15538  if (is_null())
15539  {
15540  m_type = value_t::object;
15541  m_value = value_t::object;
15542  assert_invariant();
15543  }
15544 
15545  // at only works for objects
15546  if (JSON_LIKELY(is_object()))
15547  {
15548  return m_value.object->operator[](key);
15549  }
15550 
15551  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15552  }
15553 
15584  template<typename T>
15586  {
15587  // at only works for objects
15588  if (JSON_LIKELY(is_object()))
15589  {
15590  assert(m_value.object->find(key) != m_value.object->end());
15591  return m_value.object->find(key)->second;
15592  }
15593 
15594  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15595  }
15596 
15645  template<class ValueType, typename std::enable_if<
15647  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
15648  {
15649  // at only works for objects
15650  if (JSON_LIKELY(is_object()))
15651  {
15652  // if key is found, return value and given default value otherwise
15653  const auto it = find(key);
15654  if (it != end())
15655  {
15656  return *it;
15657  }
15658 
15659  return default_value;
15660  }
15661 
15662  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
15663  }
15664 
15669  string_t value(const typename object_t::key_type& key, const char* default_value) const
15670  {
15671  return value(key, string_t(default_value));
15672  }
15673 
15715  template<class ValueType, typename std::enable_if<
15716  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
15717  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
15718  {
15719  // at only works for objects
15720  if (JSON_LIKELY(is_object()))
15721  {
15722  // if pointer resolves a value, return it or use default value
15723  JSON_TRY
15724  {
15725  return ptr.get_checked(this);
15726  }
15728  {
15729  return default_value;
15730  }
15731  }
15732 
15733  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
15734  }
15735 
15740  string_t value(const json_pointer& ptr, const char* default_value) const
15741  {
15742  return value(ptr, string_t(default_value));
15743  }
15744 
15771  {
15772  return *begin();
15773  }
15774 
15779  {
15780  return *cbegin();
15781  }
15782 
15815  {
15816  auto tmp = end();
15817  --tmp;
15818  return *tmp;
15819  }
15820 
15825  {
15826  auto tmp = cend();
15827  --tmp;
15828  return *tmp;
15829  }
15830 
15877  template<class IteratorType, typename std::enable_if<
15880  = 0>
15881  IteratorType erase(IteratorType pos)
15882  {
15883  // make sure iterator fits the current value
15884  if (JSON_UNLIKELY(this != pos.m_object))
15885  {
15886  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
15887  }
15888 
15889  IteratorType result = end();
15890 
15891  switch (m_type)
15892  {
15893  case value_t::boolean:
15894  case value_t::number_float:
15897  case value_t::string:
15898  {
15899  if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
15900  {
15901  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
15902  }
15903 
15904  if (is_string())
15905  {
15906  AllocatorType<string_t> alloc;
15907  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
15908  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
15909  m_value.string = nullptr;
15910  }
15911 
15912  m_type = value_t::null;
15913  assert_invariant();
15914  break;
15915  }
15916 
15917  case value_t::object:
15918  {
15919  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
15920  break;
15921  }
15922 
15923  case value_t::array:
15924  {
15925  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
15926  break;
15927  }
15928 
15929  default:
15930  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
15931  }
15932 
15933  return result;
15934  }
15935 
15982  template<class IteratorType, typename std::enable_if<
15984  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
15985  = 0>
15986  IteratorType erase(IteratorType first, IteratorType last)
15987  {
15988  // make sure iterator fits the current value
15989  if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
15990  {
15991  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
15992  }
15993 
15994  IteratorType result = end();
15995 
15996  switch (m_type)
15997  {
15998  case value_t::boolean:
15999  case value_t::number_float:
16002  case value_t::string:
16003  {
16004  if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16005  or not last.m_it.primitive_iterator.is_end()))
16006  {
16007  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16008  }
16009 
16010  if (is_string())
16011  {
16012  AllocatorType<string_t> alloc;
16013  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16014  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16015  m_value.string = nullptr;
16016  }
16017 
16018  m_type = value_t::null;
16019  assert_invariant();
16020  break;
16021  }
16022 
16023  case value_t::object:
16024  {
16025  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16026  last.m_it.object_iterator);
16027  break;
16028  }
16029 
16030  case value_t::array:
16031  {
16032  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16033  last.m_it.array_iterator);
16034  break;
16035  }
16036 
16037  default:
16038  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16039  }
16040 
16041  return result;
16042  }
16043 
16073  size_type erase(const typename object_t::key_type& key)
16074  {
16075  // this erase only works for objects
16076  if (JSON_LIKELY(is_object()))
16077  {
16078  return m_value.object->erase(key);
16079  }
16080 
16081  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16082  }
16083 
16108  void erase(const size_type idx)
16109  {
16110  // this erase only works for arrays
16111  if (JSON_LIKELY(is_array()))
16112  {
16113  if (JSON_UNLIKELY(idx >= size()))
16114  {
16115  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
16116  }
16117 
16118  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
16119  }
16120  else
16121  {
16122  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16123  }
16124  }
16125 
16127 
16128 
16130  // lookup //
16132 
16135 
16158  template<typename KeyT>
16159  iterator find(KeyT&& key)
16160  {
16161  auto result = end();
16162 
16163  if (is_object())
16164  {
16165  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16166  }
16167 
16168  return result;
16169  }
16170 
16175  template<typename KeyT>
16176  const_iterator find(KeyT&& key) const
16177  {
16178  auto result = cend();
16179 
16180  if (is_object())
16181  {
16182  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16183  }
16184 
16185  return result;
16186  }
16187 
16209  template<typename KeyT>
16210  size_type count(KeyT&& key) const
16211  {
16212  // return 0 for all nonobject types
16213  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16214  }
16215 
16217 
16218 
16220  // iterators //
16222 
16225 
16250  iterator begin() noexcept
16251  {
16252  iterator result(this);
16253  result.set_begin();
16254  return result;
16255  }
16256 
16260  const_iterator begin() const noexcept
16261  {
16262  return cbegin();
16263  }
16264 
16290  const_iterator cbegin() const noexcept
16291  {
16292  const_iterator result(this);
16293  result.set_begin();
16294  return result;
16295  }
16296 
16321  iterator end() noexcept
16322  {
16323  iterator result(this);
16324  result.set_end();
16325  return result;
16326  }
16327 
16331  const_iterator end() const noexcept
16332  {
16333  return cend();
16334  }
16335 
16361  const_iterator cend() const noexcept
16362  {
16363  const_iterator result(this);
16364  result.set_end();
16365  return result;
16366  }
16367 
16392  {
16393  return reverse_iterator(end());
16394  }
16395 
16400  {
16401  return crbegin();
16402  }
16403 
16429  {
16430  return reverse_iterator(begin());
16431  }
16432 
16436  const_reverse_iterator rend() const noexcept
16437  {
16438  return crend();
16439  }
16440 
16466  {
16467  return const_reverse_iterator(cend());
16468  }
16469 
16495  {
16496  return const_reverse_iterator(cbegin());
16497  }
16498 
16499  public:
16559  {
16560  return ref.items();
16561  }
16562 
16568  {
16569  return ref.items();
16570  }
16571 
16625  {
16626  return iteration_proxy<iterator>(*this);
16627  }
16628 
16633  {
16634  return iteration_proxy<const_iterator>(*this);
16635  }
16636 
16638 
16639 
16641  // capacity //
16643 
16646 
16688  bool empty() const noexcept
16689  {
16690  switch (m_type)
16691  {
16692  case value_t::null:
16693  {
16694  // null values are empty
16695  return true;
16696  }
16697 
16698  case value_t::array:
16699  {
16700  // delegate call to array_t::empty()
16701  return m_value.array->empty();
16702  }
16703 
16704  case value_t::object:
16705  {
16706  // delegate call to object_t::empty()
16707  return m_value.object->empty();
16708  }
16709 
16710  default:
16711  {
16712  // all other types are nonempty
16713  return false;
16714  }
16715  }
16716  }
16717 
16760  size_type size() const noexcept
16761  {
16762  switch (m_type)
16763  {
16764  case value_t::null:
16765  {
16766  // null values are empty
16767  return 0;
16768  }
16769 
16770  case value_t::array:
16771  {
16772  // delegate call to array_t::size()
16773  return m_value.array->size();
16774  }
16775 
16776  case value_t::object:
16777  {
16778  // delegate call to object_t::size()
16779  return m_value.object->size();
16780  }
16781 
16782  default:
16783  {
16784  // all other types have size 1
16785  return 1;
16786  }
16787  }
16788  }
16789 
16830  size_type max_size() const noexcept
16831  {
16832  switch (m_type)
16833  {
16834  case value_t::array:
16835  {
16836  // delegate call to array_t::max_size()
16837  return m_value.array->max_size();
16838  }
16839 
16840  case value_t::object:
16841  {
16842  // delegate call to object_t::max_size()
16843  return m_value.object->max_size();
16844  }
16845 
16846  default:
16847  {
16848  // all other types have max_size() == size()
16849  return size();
16850  }
16851  }
16852  }
16853 
16855 
16856 
16858  // modifiers //
16860 
16863 
16900  void clear() noexcept
16901  {
16902  switch (m_type)
16903  {
16905  {
16906  m_value.number_integer = 0;
16907  break;
16908  }
16909 
16911  {
16912  m_value.number_unsigned = 0;
16913  break;
16914  }
16915 
16916  case value_t::number_float:
16917  {
16918  m_value.number_float = 0.0;
16919  break;
16920  }
16921 
16922  case value_t::boolean:
16923  {
16924  m_value.boolean = false;
16925  break;
16926  }
16927 
16928  case value_t::string:
16929  {
16930  m_value.string->clear();
16931  break;
16932  }
16933 
16934  case value_t::array:
16935  {
16936  m_value.array->clear();
16937  break;
16938  }
16939 
16940  case value_t::object:
16941  {
16942  m_value.object->clear();
16943  break;
16944  }
16945 
16946  default:
16947  break;
16948  }
16949  }
16950 
16971  void push_back(basic_json&& val)
16972  {
16973  // push_back only works for null objects or arrays
16974  if (JSON_UNLIKELY(not(is_null() or is_array())))
16975  {
16976  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
16977  }
16978 
16979  // transform null object into an array
16980  if (is_null())
16981  {
16982  m_type = value_t::array;
16983  m_value = value_t::array;
16984  assert_invariant();
16985  }
16986 
16987  // add element to array (move semantics)
16988  m_value.array->push_back(std::move(val));
16989  // invalidate object
16990  val.m_type = value_t::null;
16991  }
16992 
16997  reference operator+=(basic_json&& val)
16998  {
16999  push_back(std::move(val));
17000  return *this;
17001  }
17002 
17007  void push_back(const basic_json& val)
17008  {
17009  // push_back only works for null objects or arrays
17010  if (JSON_UNLIKELY(not(is_null() or is_array())))
17011  {
17012  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17013  }
17014 
17015  // transform null object into an array
17016  if (is_null())
17017  {
17018  m_type = value_t::array;
17019  m_value = value_t::array;
17020  assert_invariant();
17021  }
17022 
17023  // add element to array
17024  m_value.array->push_back(val);
17025  }
17026 
17031  reference operator+=(const basic_json& val)
17032  {
17033  push_back(val);
17034  return *this;
17035  }
17036 
17057  void push_back(const typename object_t::value_type& val)
17058  {
17059  // push_back only works for null objects or objects
17060  if (JSON_UNLIKELY(not(is_null() or is_object())))
17061  {
17062  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17063  }
17064 
17065  // transform null object into an object
17066  if (is_null())
17067  {
17068  m_type = value_t::object;
17069  m_value = value_t::object;
17070  assert_invariant();
17071  }
17072 
17073  // add element to array
17074  m_value.object->insert(val);
17075  }
17076 
17081  reference operator+=(const typename object_t::value_type& val)
17082  {
17083  push_back(val);
17084  return *this;
17085  }
17086 
17113  {
17114  if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17115  {
17116  basic_json&& key = init.begin()->moved_or_copied();
17117  push_back(typename object_t::value_type(
17118  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17119  }
17120  else
17121  {
17122  push_back(basic_json(init));
17123  }
17124  }
17125 
17131  {
17132  push_back(init);
17133  return *this;
17134  }
17135 
17157  template<class... Args>
17158  void emplace_back(Args&& ... args)
17159  {
17160  // emplace_back only works for null objects or arrays
17161  if (JSON_UNLIKELY(not(is_null() or is_array())))
17162  {
17163  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
17164  }
17165 
17166  // transform null object into an array
17167  if (is_null())
17168  {
17169  m_type = value_t::array;
17170  m_value = value_t::array;
17171  assert_invariant();
17172  }
17173 
17174  // add element to array (perfect forwarding)
17175  m_value.array->emplace_back(std::forward<Args>(args)...);
17176  }
17177 
17205  template<class... Args>
17206  std::pair<iterator, bool> emplace(Args&& ... args)
17207  {
17208  // emplace only works for null objects or arrays
17209  if (JSON_UNLIKELY(not(is_null() or is_object())))
17210  {
17211  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
17212  }
17213 
17214  // transform null object into an object
17215  if (is_null())
17216  {
17217  m_type = value_t::object;
17218  m_value = value_t::object;
17219  assert_invariant();
17220  }
17221 
17222  // add element to array (perfect forwarding)
17223  auto res = m_value.object->emplace(std::forward<Args>(args)...);
17224  // create result iterator and set iterator to the result of emplace
17225  auto it = begin();
17226  it.m_it.object_iterator = res.first;
17227 
17228  // return pair of iterator and boolean
17229  return {it, res.second};
17230  }
17231 
17235  template<typename... Args>
17237  {
17238  iterator result(this);
17239  assert(m_value.array != nullptr);
17240 
17241  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17242  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17243  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17244 
17245  // This could have been written as:
17246  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
17247  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
17248 
17249  return result;
17250  }
17251 
17274  iterator insert(const_iterator pos, const basic_json& val)
17275  {
17276  // insert only works for arrays
17277  if (JSON_LIKELY(is_array()))
17278  {
17279  // check if iterator pos fits to this JSON value
17280  if (JSON_UNLIKELY(pos.m_object != this))
17281  {
17282  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17283  }
17284 
17285  // insert to array and return iterator
17286  return insert_iterator(pos, val);
17287  }
17288 
17289  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17290  }
17291 
17296  iterator insert(const_iterator pos, basic_json&& val)
17297  {
17298  return insert(pos, val);
17299  }
17300 
17325  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
17326  {
17327  // insert only works for arrays
17328  if (JSON_LIKELY(is_array()))
17329  {
17330  // check if iterator pos fits to this JSON value
17331  if (JSON_UNLIKELY(pos.m_object != this))
17332  {
17333  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17334  }
17335 
17336  // insert to array and return iterator
17337  return insert_iterator(pos, cnt, val);
17338  }
17339 
17340  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17341  }
17342 
17374  {
17375  // insert only works for arrays
17376  if (JSON_UNLIKELY(not is_array()))
17377  {
17378  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17379  }
17380 
17381  // check if iterator pos fits to this JSON value
17382  if (JSON_UNLIKELY(pos.m_object != this))
17383  {
17384  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17385  }
17386 
17387  // check if range iterators belong to the same JSON object
17388  if (JSON_UNLIKELY(first.m_object != last.m_object))
17389  {
17390  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17391  }
17392 
17393  if (JSON_UNLIKELY(first.m_object == this))
17394  {
17395  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
17396  }
17397 
17398  // insert to array and return iterator
17399  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17400  }
17401 
17427  {
17428  // insert only works for arrays
17429  if (JSON_UNLIKELY(not is_array()))
17430  {
17431  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17432  }
17433 
17434  // check if iterator pos fits to this JSON value
17435  if (JSON_UNLIKELY(pos.m_object != this))
17436  {
17437  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17438  }
17439 
17440  // insert to array and return iterator
17441  return insert_iterator(pos, ilist.begin(), ilist.end());
17442  }
17443 
17468  {
17469  // insert only works for objects
17470  if (JSON_UNLIKELY(not is_object()))
17471  {
17472  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17473  }
17474 
17475  // check if range iterators belong to the same JSON object
17476  if (JSON_UNLIKELY(first.m_object != last.m_object))
17477  {
17478  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17479  }
17480 
17481  // passed iterators must belong to objects
17482  if (JSON_UNLIKELY(not first.m_object->is_object()))
17483  {
17484  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
17485  }
17486 
17487  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
17488  }
17489 
17510  {
17511  // implicitly convert null value to an empty object
17512  if (is_null())
17513  {
17514  m_type = value_t::object;
17515  m_value.object = create<object_t>();
17516  assert_invariant();
17517  }
17518 
17519  if (JSON_UNLIKELY(not is_object()))
17520  {
17521  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
17522  }
17523  if (JSON_UNLIKELY(not j.is_object()))
17524  {
17525  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
17526  }
17527 
17528  for (auto it = j.cbegin(); it != j.cend(); ++it)
17529  {
17530  m_value.object->operator[](it.key()) = it.value();
17531  }
17532  }
17533 
17561  {
17562  // implicitly convert null value to an empty object
17563  if (is_null())
17564  {
17565  m_type = value_t::object;
17566  m_value.object = create<object_t>();
17567  assert_invariant();
17568  }
17569 
17570  if (JSON_UNLIKELY(not is_object()))
17571  {
17572  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
17573  }
17574 
17575  // check if range iterators belong to the same JSON object
17576  if (JSON_UNLIKELY(first.m_object != last.m_object))
17577  {
17578  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17579  }
17580 
17581  // passed iterators must belong to objects
17582  if (JSON_UNLIKELY(not first.m_object->is_object()
17583  or not last.m_object->is_object()))
17584  {
17585  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
17586  }
17587 
17588  for (auto it = first; it != last; ++it)
17589  {
17590  m_value.object->operator[](it.key()) = it.value();
17591  }
17592  }
17593 
17611  void swap(reference other) noexcept (
17616  )
17617  {
17618  std::swap(m_type, other.m_type);
17619  std::swap(m_value, other.m_value);
17620  assert_invariant();
17621  }
17622 
17643  void swap(array_t& other)
17644  {
17645  // swap only works for arrays
17646  if (JSON_LIKELY(is_array()))
17647  {
17648  std::swap(*(m_value.array), other);
17649  }
17650  else
17651  {
17652  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
17653  }
17654  }
17655 
17676  void swap(object_t& other)
17677  {
17678  // swap only works for objects
17679  if (JSON_LIKELY(is_object()))
17680  {
17681  std::swap(*(m_value.object), other);
17682  }
17683  else
17684  {
17685  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
17686  }
17687  }
17688 
17709  void swap(string_t& other)
17710  {
17711  // swap only works for strings
17712  if (JSON_LIKELY(is_string()))
17713  {
17714  std::swap(*(m_value.string), other);
17715  }
17716  else
17717  {
17718  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
17719  }
17720  }
17721 
17723 
17724  public:
17726  // lexicographical comparison operators //
17728 
17731 
17771  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
17772  {
17773  const auto lhs_type = lhs.type();
17774  const auto rhs_type = rhs.type();
17775 
17776  if (lhs_type == rhs_type)
17777  {
17778  switch (lhs_type)
17779  {
17780  case value_t::array:
17781  return (*lhs.m_value.array == *rhs.m_value.array);
17782 
17783  case value_t::object:
17784  return (*lhs.m_value.object == *rhs.m_value.object);
17785 
17786  case value_t::null:
17787  return true;
17788 
17789  case value_t::string:
17790  return (*lhs.m_value.string == *rhs.m_value.string);
17791 
17792  case value_t::boolean:
17793  return (lhs.m_value.boolean == rhs.m_value.boolean);
17794 
17796  return (lhs.m_value.number_integer == rhs.m_value.number_integer);
17797 
17799  return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
17800 
17801  case value_t::number_float:
17802  return (lhs.m_value.number_float == rhs.m_value.number_float);
17803 
17804  default:
17805  return false;
17806  }
17807  }
17808  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
17809  {
17810  return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
17811  }
17812  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
17813  {
17814  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
17815  }
17816  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
17817  {
17818  return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
17819  }
17820  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
17821  {
17822  return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
17823  }
17824  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
17825  {
17826  return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
17827  }
17828  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
17829  {
17830  return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
17831  }
17832 
17833  return false;
17834  }
17835 
17840  template<typename ScalarType, typename std::enable_if<
17841  std::is_scalar<ScalarType>::value, int>::type = 0>
17842  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
17843  {
17844  return (lhs == basic_json(rhs));
17845  }
17846 
17851  template<typename ScalarType, typename std::enable_if<
17852  std::is_scalar<ScalarType>::value, int>::type = 0>
17853  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
17854  {
17855  return (basic_json(lhs) == rhs);
17856  }
17857 
17876  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
17877  {
17878  return not (lhs == rhs);
17879  }
17880 
17885  template<typename ScalarType, typename std::enable_if<
17886  std::is_scalar<ScalarType>::value, int>::type = 0>
17887  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
17888  {
17889  return (lhs != basic_json(rhs));
17890  }
17891 
17896  template<typename ScalarType, typename std::enable_if<
17897  std::is_scalar<ScalarType>::value, int>::type = 0>
17898  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
17899  {
17900  return (basic_json(lhs) != rhs);
17901  }
17902 
17929  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
17930  {
17931  const auto lhs_type = lhs.type();
17932  const auto rhs_type = rhs.type();
17933 
17934  if (lhs_type == rhs_type)
17935  {
17936  switch (lhs_type)
17937  {
17938  case value_t::array:
17939  return (*lhs.m_value.array) < (*rhs.m_value.array);
17940 
17941  case value_t::object:
17942  return *lhs.m_value.object < *rhs.m_value.object;
17943 
17944  case value_t::null:
17945  return false;
17946 
17947  case value_t::string:
17948  return *lhs.m_value.string < *rhs.m_value.string;
17949 
17950  case value_t::boolean:
17951  return lhs.m_value.boolean < rhs.m_value.boolean;
17952 
17954  return lhs.m_value.number_integer < rhs.m_value.number_integer;
17955 
17957  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
17958 
17959  case value_t::number_float:
17960  return lhs.m_value.number_float < rhs.m_value.number_float;
17961 
17962  default:
17963  return false;
17964  }
17965  }
17966  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
17967  {
17968  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
17969  }
17970  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
17971  {
17972  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
17973  }
17974  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
17975  {
17976  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
17977  }
17978  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
17979  {
17980  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
17981  }
17982  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
17983  {
17984  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
17985  }
17986  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
17987  {
17988  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
17989  }
17990 
17991  // We only reach this line if we cannot compare values. In that case,
17992  // we compare types. Note we have to call the operator explicitly,
17993  // because MSVC has problems otherwise.
17994  return operator<(lhs_type, rhs_type);
17995  }
17996 
18001  template<typename ScalarType, typename std::enable_if<
18002  std::is_scalar<ScalarType>::value, int>::type = 0>
18003  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
18004  {
18005  return (lhs < basic_json(rhs));
18006  }
18007 
18012  template<typename ScalarType, typename std::enable_if<
18013  std::is_scalar<ScalarType>::value, int>::type = 0>
18014  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
18015  {
18016  return (basic_json(lhs) < rhs);
18017  }
18018 
18038  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
18039  {
18040  return not (rhs < lhs);
18041  }
18042 
18047  template<typename ScalarType, typename std::enable_if<
18048  std::is_scalar<ScalarType>::value, int>::type = 0>
18049  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
18050  {
18051  return (lhs <= basic_json(rhs));
18052  }
18053 
18058  template<typename ScalarType, typename std::enable_if<
18059  std::is_scalar<ScalarType>::value, int>::type = 0>
18060  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
18061  {
18062  return (basic_json(lhs) <= rhs);
18063  }
18064 
18084  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
18085  {
18086  return not (lhs <= rhs);
18087  }
18088 
18093  template<typename ScalarType, typename std::enable_if<
18094  std::is_scalar<ScalarType>::value, int>::type = 0>
18095  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
18096  {
18097  return (lhs > basic_json(rhs));
18098  }
18099 
18104  template<typename ScalarType, typename std::enable_if<
18105  std::is_scalar<ScalarType>::value, int>::type = 0>
18106  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
18107  {
18108  return (basic_json(lhs) > rhs);
18109  }
18110 
18130  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
18131  {
18132  return not (lhs < rhs);
18133  }
18134 
18139  template<typename ScalarType, typename std::enable_if<
18140  std::is_scalar<ScalarType>::value, int>::type = 0>
18141  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
18142  {
18143  return (lhs >= basic_json(rhs));
18144  }
18145 
18150  template<typename ScalarType, typename std::enable_if<
18151  std::is_scalar<ScalarType>::value, int>::type = 0>
18152  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
18153  {
18154  return (basic_json(lhs) >= rhs);
18155  }
18156 
18158 
18160  // serialization //
18162 
18165 
18197  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
18198  {
18199  // read width member and use it as indentation parameter if nonzero
18200  const bool pretty_print = (o.width() > 0);
18201  const auto indentation = (pretty_print ? o.width() : 0);
18202 
18203  // reset width to 0 for subsequent calls to this stream
18204  o.width(0);
18205 
18206  // do the actual serialization
18207  serializer s(detail::output_adapter<char>(o), o.fill());
18208  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
18209  return o;
18210  }
18211 
18221  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
18222  {
18223  return o << j;
18224  }
18225 
18227 
18228 
18230  // deserialization //
18232 
18235 
18300  static basic_json parse(detail::input_adapter&& i,
18301  const parser_callback_t cb = nullptr,
18302  const bool allow_exceptions = true)
18303  {
18304  basic_json result;
18305  parser(i, cb, allow_exceptions).parse(true, result);
18306  return result;
18307  }
18308 
18310  {
18311  return parser(i).accept(true);
18312  }
18313 
18370  template <typename SAX>
18371  static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18373  const bool strict = true)
18374  {
18375  assert(sax);
18376  switch (format)
18377  {
18378  case input_format_t::json:
18379  return parser(std::move(i)).sax_parse(sax, strict);
18380  default:
18381  return detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18382  }
18383  }
18384 
18432  template<class IteratorType, typename std::enable_if<
18433  std::is_base_of<
18434  std::random_access_iterator_tag,
18435  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
18436  static basic_json parse(IteratorType first, IteratorType last,
18437  const parser_callback_t cb = nullptr,
18438  const bool allow_exceptions = true)
18439  {
18440  basic_json result;
18441  parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
18442  return result;
18443  }
18444 
18445  template<class IteratorType, typename std::enable_if<
18446  std::is_base_of<
18447  std::random_access_iterator_tag,
18448  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
18449  static bool accept(IteratorType first, IteratorType last)
18450  {
18451  return parser(detail::input_adapter(first, last)).accept(true);
18452  }
18453 
18454  template<class IteratorType, class SAX, typename std::enable_if<
18455  std::is_base_of<
18456  std::random_access_iterator_tag,
18457  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
18458  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
18459  {
18460  return parser(detail::input_adapter(first, last)).sax_parse(sax);
18461  }
18462 
18472  friend std::istream& operator<<(basic_json& j, std::istream& i)
18473  {
18474  return operator>>(i, j);
18475  }
18476 
18502  friend std::istream& operator>>(std::istream& i, basic_json& j)
18503  {
18504  parser(detail::input_adapter(i)).parse(false, j);
18505  return i;
18506  }
18507 
18509 
18511  // convenience functions //
18513 
18544  const char* type_name() const noexcept
18545  {
18546  {
18547  switch (m_type)
18548  {
18549  case value_t::null:
18550  return "null";
18551  case value_t::object:
18552  return "object";
18553  case value_t::array:
18554  return "array";
18555  case value_t::string:
18556  return "string";
18557  case value_t::boolean:
18558  return "boolean";
18559  case value_t::discarded:
18560  return "discarded";
18561  default:
18562  return "number";
18563  }
18564  }
18565  }
18566 
18567 
18568  private:
18570  // member variables //
18572 
18575 
18577  json_value m_value = {};
18578 
18580  // binary serialization/deserialization //
18582 
18585 
18586  public:
18675  static std::vector<uint8_t> to_cbor(const basic_json& j)
18676  {
18677  std::vector<uint8_t> result;
18678  to_cbor(j, result);
18679  return result;
18680  }
18681 
18682  static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
18683  {
18684  binary_writer<uint8_t>(o).write_cbor(j);
18685  }
18686 
18687  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
18688  {
18689  binary_writer<char>(o).write_cbor(j);
18690  }
18691 
18771  static std::vector<uint8_t> to_msgpack(const basic_json& j)
18772  {
18773  std::vector<uint8_t> result;
18774  to_msgpack(j, result);
18775  return result;
18776  }
18777 
18778  static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
18779  {
18780  binary_writer<uint8_t>(o).write_msgpack(j);
18781  }
18782 
18783  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
18784  {
18785  binary_writer<char>(o).write_msgpack(j);
18786  }
18787 
18868  static std::vector<uint8_t> to_ubjson(const basic_json& j,
18869  const bool use_size = false,
18870  const bool use_type = false)
18871  {
18872  std::vector<uint8_t> result;
18873  to_ubjson(j, result, use_size, use_type);
18874  return result;
18875  }
18876 
18877  static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
18878  const bool use_size = false, const bool use_type = false)
18879  {
18880  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
18881  }
18882 
18883  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
18884  const bool use_size = false, const bool use_type = false)
18885  {
18886  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
18887  }
18888 
18889 
18945  static std::vector<uint8_t> to_bson(const basic_json& j)
18946  {
18947  std::vector<uint8_t> result;
18948  to_bson(j, result);
18949  return result;
18950  }
18951 
18960  static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
18961  {
18962  binary_writer<uint8_t>(o).write_bson(j);
18963  }
18964 
18968  static void to_bson(const basic_json& j, detail::output_adapter<char> o)
18969  {
18970  binary_writer<char>(o).write_bson(j);
18971  }
18972 
18973 
19071  static basic_json from_cbor(detail::input_adapter&& i,
19072  const bool strict = true,
19073  const bool allow_exceptions = true)
19074  {
19075  basic_json result;
19076  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19078  return res ? result : basic_json(value_t::discarded);
19079  }
19080 
19084  template<typename A1, typename A2,
19086  static basic_json from_cbor(A1 && a1, A2 && a2,
19087  const bool strict = true,
19088  const bool allow_exceptions = true)
19089  {
19090  basic_json result;
19091  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19092  const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19093  return res ? result : basic_json(value_t::discarded);
19094  }
19095 
19176  static basic_json from_msgpack(detail::input_adapter&& i,
19177  const bool strict = true,
19178  const bool allow_exceptions = true)
19179  {
19180  basic_json result;
19181  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19183  return res ? result : basic_json(value_t::discarded);
19184  }
19185 
19189  template<typename A1, typename A2,
19190  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19191  static basic_json from_msgpack(A1 && a1, A2 && a2,
19192  const bool strict = true,
19193  const bool allow_exceptions = true)
19194  {
19195  basic_json result;
19196  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19197  const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19198  return res ? result : basic_json(value_t::discarded);
19199  }
19200 
19260  static basic_json from_ubjson(detail::input_adapter&& i,
19261  const bool strict = true,
19262  const bool allow_exceptions = true)
19263  {
19264  basic_json result;
19265  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19267  return res ? result : basic_json(value_t::discarded);
19268  }
19269 
19273  template<typename A1, typename A2,
19274  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19275  static basic_json from_ubjson(A1 && a1, A2 && a2,
19276  const bool strict = true,
19277  const bool allow_exceptions = true)
19278  {
19279  basic_json result;
19280  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19281  const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19282  return res ? result : basic_json(value_t::discarded);
19283  }
19284 
19343  static basic_json from_bson(detail::input_adapter&& i,
19344  const bool strict = true,
19345  const bool allow_exceptions = true)
19346  {
19347  basic_json result;
19348  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19350  return res ? result : basic_json(value_t::discarded);
19351  }
19352 
19356  template<typename A1, typename A2,
19357  detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19358  static basic_json from_bson(A1 && a1, A2 && a2,
19359  const bool strict = true,
19360  const bool allow_exceptions = true)
19361  {
19362  basic_json result;
19363  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19364  const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19365  return res ? result : basic_json(value_t::discarded);
19366  }
19367 
19368 
19369 
19371 
19373  // JSON Pointer support //
19375 
19378 
19413  {
19414  return ptr.get_unchecked(this);
19415  }
19416 
19441  {
19442  return ptr.get_unchecked(this);
19443  }
19444 
19484  {
19485  return ptr.get_checked(this);
19486  }
19487 
19526  const_reference at(const json_pointer& ptr) const
19527  {
19528  return ptr.get_checked(this);
19529  }
19530 
19553  basic_json flatten() const
19554  {
19555  basic_json result(value_t::object);
19556  json_pointer::flatten("", *this, result);
19557  return result;
19558  }
19559 
19590  basic_json unflatten() const
19591  {
19592  return json_pointer::unflatten(*this);
19593  }
19594 
19596 
19598  // JSON Patch functions //
19600 
19603 
19651  basic_json patch(const basic_json& json_patch) const
19652  {
19653  // make a working copy to apply the patch to
19654  basic_json result = *this;
19655 
19656  // the valid JSON Patch operations
19657  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
19658 
19659  const auto get_op = [](const std::string & op)
19660  {
19661  if (op == "add")
19662  {
19663  return patch_operations::add;
19664  }
19665  if (op == "remove")
19666  {
19667  return patch_operations::remove;
19668  }
19669  if (op == "replace")
19670  {
19672  }
19673  if (op == "move")
19674  {
19675  return patch_operations::move;
19676  }
19677  if (op == "copy")
19678  {
19679  return patch_operations::copy;
19680  }
19681  if (op == "test")
19682  {
19683  return patch_operations::test;
19684  }
19685 
19686  return patch_operations::invalid;
19687  };
19688 
19689  // wrapper for "add" operation; add value at ptr
19690  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
19691  {
19692  // adding to the root of the target document means replacing it
19693  if (ptr.is_root())
19694  {
19695  result = val;
19696  }
19697  else
19698  {
19699  // make sure the top element of the pointer exists
19700  json_pointer top_pointer = ptr.top();
19701  if (top_pointer != ptr)
19702  {
19703  result.at(top_pointer);
19704  }
19705 
19706  // get reference to parent of JSON pointer ptr
19707  const auto last_path = ptr.pop_back();
19708  basic_json& parent = result[ptr];
19709 
19710  switch (parent.m_type)
19711  {
19712  case value_t::null:
19713  case value_t::object:
19714  {
19715  // use operator[] to add value
19716  parent[last_path] = val;
19717  break;
19718  }
19719 
19720  case value_t::array:
19721  {
19722  if (last_path == "-")
19723  {
19724  // special case: append to back
19725  parent.push_back(val);
19726  }
19727  else
19728  {
19729  const auto idx = json_pointer::array_index(last_path);
19730  if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
19731  {
19732  // avoid undefined behavior
19733  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19734  }
19735 
19736  // default case: insert add offset
19737  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
19738  }
19739  break;
19740  }
19741 
19742  // LCOV_EXCL_START
19743  default:
19744  {
19745  // if there exists a parent it cannot be primitive
19746  assert(false);
19747  }
19748  // LCOV_EXCL_STOP
19749  }
19750  }
19751  };
19752 
19753  // wrapper for "remove" operation; remove value at ptr
19754  const auto operation_remove = [&result](json_pointer & ptr)
19755  {
19756  // get reference to parent of JSON pointer ptr
19757  const auto last_path = ptr.pop_back();
19758  basic_json& parent = result.at(ptr);
19759 
19760  // remove child
19761  if (parent.is_object())
19762  {
19763  // perform range check
19764  auto it = parent.find(last_path);
19765  if (JSON_LIKELY(it != parent.end()))
19766  {
19767  parent.erase(it);
19768  }
19769  else
19770  {
19771  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
19772  }
19773  }
19774  else if (parent.is_array())
19775  {
19776  // note erase performs range check
19777  parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
19778  }
19779  };
19780 
19781  // type check: top level value must be an array
19782  if (JSON_UNLIKELY(not json_patch.is_array()))
19783  {
19784  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
19785  }
19786 
19787  // iterate and apply the operations
19788  for (const auto& val : json_patch)
19789  {
19790  // wrapper to get a value for an operation
19791  const auto get_value = [&val](const std::string & op,
19792  const std::string & member,
19793  bool string_type) -> basic_json &
19794  {
19795  // find value
19796  auto it = val.m_value.object->find(member);
19797 
19798  // context-sensitive error message
19799  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
19800 
19801  // check if desired value is present
19802  if (JSON_UNLIKELY(it == val.m_value.object->end()))
19803  {
19804  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
19805  }
19806 
19807  // check if result is of type string
19808  if (JSON_UNLIKELY(string_type and not it->second.is_string()))
19809  {
19810  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
19811  }
19812 
19813  // no error: return value
19814  return it->second;
19815  };
19816 
19817  // type check: every element of the array must be an object
19818  if (JSON_UNLIKELY(not val.is_object()))
19819  {
19820  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
19821  }
19822 
19823  // collect mandatory members
19824  const std::string op = get_value("op", "op", true);
19825  const std::string path = get_value(op, "path", true);
19826  json_pointer ptr(path);
19827 
19828  switch (get_op(op))
19829  {
19830  case patch_operations::add:
19831  {
19832  operation_add(ptr, get_value("add", "value", false));
19833  break;
19834  }
19835 
19836  case patch_operations::remove:
19837  {
19838  operation_remove(ptr);
19839  break;
19840  }
19841 
19843  {
19844  // the "path" location must exist - use at()
19845  result.at(ptr) = get_value("replace", "value", false);
19846  break;
19847  }
19848 
19849  case patch_operations::move:
19850  {
19851  const std::string from_path = get_value("move", "from", true);
19852  json_pointer from_ptr(from_path);
19853 
19854  // the "from" location must exist - use at()
19855  basic_json v = result.at(from_ptr);
19856 
19857  // The move operation is functionally identical to a
19858  // "remove" operation on the "from" location, followed
19859  // immediately by an "add" operation at the target
19860  // location with the value that was just removed.
19861  operation_remove(from_ptr);
19862  operation_add(ptr, v);
19863  break;
19864  }
19865 
19866  case patch_operations::copy:
19867  {
19868  const std::string from_path = get_value("copy", "from", true);
19869  const json_pointer from_ptr(from_path);
19870 
19871  // the "from" location must exist - use at()
19872  basic_json v = result.at(from_ptr);
19873 
19874  // The copy is functionally identical to an "add"
19875  // operation at the target location using the value
19876  // specified in the "from" member.
19877  operation_add(ptr, v);
19878  break;
19879  }
19880 
19881  case patch_operations::test:
19882  {
19883  bool success = false;
19884  JSON_TRY
19885  {
19886  // check if "value" matches the one at "path"
19887  // the "path" location must exist - use at()
19888  success = (result.at(ptr) == get_value("test", "value", false));
19889  }
19891  {
19892  // ignore out of range errors: success remains false
19893  }
19894 
19895  // throw an exception if test fails
19896  if (JSON_UNLIKELY(not success))
19897  {
19898  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
19899  }
19900 
19901  break;
19902  }
19903 
19904  case patch_operations::invalid:
19905  {
19906  // op must be "add", "remove", "replace", "move", "copy", or
19907  // "test"
19908  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
19909  }
19910  }
19911  }
19912 
19913  return result;
19914  }
19915 
19949  static basic_json diff(const basic_json& source, const basic_json& target,
19950  const std::string& path = "")
19951  {
19952  // the patch
19953  basic_json result(value_t::array);
19954 
19955  // if the values are the same, return empty patch
19956  if (source == target)
19957  {
19958  return result;
19959  }
19960 
19961  if (source.type() != target.type())
19962  {
19963  // different types: replace value
19964  result.push_back(
19965  {
19966  {"op", "replace"}, {"path", path}, {"value", target}
19967  });
19968  }
19969  else
19970  {
19971  switch (source.type())
19972  {
19973  case value_t::array:
19974  {
19975  // first pass: traverse common elements
19976  std::size_t i = 0;
19977  while (i < source.size() and i < target.size())
19978  {
19979  // recursive call to compare array values at index i
19980  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
19981  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
19982  ++i;
19983  }
19984 
19985  // i now reached the end of at least one array
19986  // in a second pass, traverse the remaining elements
19987 
19988  // remove my remaining elements
19989  const auto end_index = static_cast<difference_type>(result.size());
19990  while (i < source.size())
19991  {
19992  // add operations in reverse order to avoid invalid
19993  // indices
19994  result.insert(result.begin() + end_index, object(
19995  {
19996  {"op", "remove"},
19997  {"path", path + "/" + std::to_string(i)}
19998  }));
19999  ++i;
20000  }
20001 
20002  // add other remaining elements
20003  while (i < target.size())
20004  {
20005  result.push_back(
20006  {
20007  {"op", "add"},
20008  {"path", path + "/" + std::to_string(i)},
20009  {"value", target[i]}
20010  });
20011  ++i;
20012  }
20013 
20014  break;
20015  }
20016 
20017  case value_t::object:
20018  {
20019  // first pass: traverse this object's elements
20020  for (auto it = source.cbegin(); it != source.cend(); ++it)
20021  {
20022  // escape the key name to be used in a JSON patch
20023  const auto key = json_pointer::escape(it.key());
20024 
20025  if (target.find(it.key()) != target.end())
20026  {
20027  // recursive call to compare object values at key it
20028  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
20029  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20030  }
20031  else
20032  {
20033  // found a key that is not in o -> remove it
20034  result.push_back(object(
20035  {
20036  {"op", "remove"}, {"path", path + "/" + key}
20037  }));
20038  }
20039  }
20040 
20041  // second pass: traverse other object's elements
20042  for (auto it = target.cbegin(); it != target.cend(); ++it)
20043  {
20044  if (source.find(it.key()) == source.end())
20045  {
20046  // found a key that is not in this -> add it
20047  const auto key = json_pointer::escape(it.key());
20048  result.push_back(
20049  {
20050  {"op", "add"}, {"path", path + "/" + key},
20051  {"value", it.value()}
20052  });
20053  }
20054  }
20055 
20056  break;
20057  }
20058 
20059  default:
20060  {
20061  // both primitive type: replace value
20062  result.push_back(
20063  {
20064  {"op", "replace"}, {"path", path}, {"value", target}
20065  });
20066  break;
20067  }
20068  }
20069  }
20070 
20071  return result;
20072  }
20073 
20075 
20077  // JSON Merge Patch functions //
20079 
20082 
20125  void merge_patch(const basic_json& patch)
20126  {
20127  if (patch.is_object())
20128  {
20129  if (not is_object())
20130  {
20131  *this = object();
20132  }
20133  for (auto it = patch.begin(); it != patch.end(); ++it)
20134  {
20135  if (it.value().is_null())
20136  {
20137  erase(it.key());
20138  }
20139  else
20140  {
20141  operator[](it.key()).merge_patch(it.value());
20142  }
20143  }
20144  }
20145  else
20146  {
20147  *this = patch;
20148  }
20149  }
20150 
20152 };
20153 } // namespace nlohmann
20154 
20156 // nonmember support //
20158 
20159 // specialization of std::swap, and std::hash
20160 namespace std
20161 {
20162 
20164 template<>
20165 struct hash<nlohmann::json>
20166 {
20172  std::size_t operator()(const nlohmann::json& j) const
20173  {
20174  // a naive hashing via the string representation
20175  const auto& h = hash<nlohmann::json::string_t>();
20176  return h(j.dump());
20177  }
20178 };
20179 
20183 template<>
20185 {
20191  nlohmann::detail::value_t rhs) const noexcept
20192  {
20193  return nlohmann::detail::operator<(lhs, rhs);
20194  }
20195 };
20196 
20202 template<>
20203 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
20206 )
20207 {
20208  j1.swap(j2);
20209 }
20210 
20211 } // namespace std
20212 
20226 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
20227 {
20228  return nlohmann::json::parse(s, s + n);
20229 }
20230 
20244 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
20245 {
20247 }
20248 
20249 // #include <nlohmann/detail/macro_unscope.hpp>
20250 
20251 
20252 // restore GCC/clang diagnostic settings
20253 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
20254  #pragma GCC diagnostic pop
20255 #endif
20256 #if defined(__clang__)
20257  #pragma GCC diagnostic pop
20258 #endif
20259 
20260 // clean up
20261 #undef JSON_INTERNAL_CATCH
20262 #undef JSON_CATCH
20263 #undef JSON_THROW
20264 #undef JSON_TRY
20265 #undef JSON_LIKELY
20266 #undef JSON_UNLIKELY
20267 #undef JSON_DEPRECATED
20268 #undef JSON_HAS_CPP_14
20269 #undef JSON_HAS_CPP_17
20270 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
20271 #undef NLOHMANN_BASIC_JSON_TPL
20272 
20273 
20274 #endif
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:13225
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: json.hpp:9371
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:9568
object_t * object
object (stored with pointer to save storage)
Definition: json.hpp:13129
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:17031
value_type const & operator*() const
Definition: json.hpp:11559
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:13886
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:13249
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:4811
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:16176
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:4004
reference value() const
return the value of an iterator
Definition: json.hpp:6199
input_buffer_adapter(const char *b, const std::size_t l) noexcept
Definition: json.hpp:2144
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:17560
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:1362
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:14656
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:3769
typename parser::parser_callback_t parser_callback_t
per-element parser callback type
Definition: json.hpp:13377
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:1830
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:5992
token_type
token types for the parser
Definition: json.hpp:2484
typename T::pointer pointer_t
Definition: json.hpp:451
const int id
the id of the exception
Definition: json.hpp:823
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:14638
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:921
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:1764
std::shared_ptr< input_adapter_protocol > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:2095
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:1229
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:9340
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:14692
input_adapter(IteratorType first, IteratorType last)
input adapter for iterator range with contiguous storage
Definition: json.hpp:2385
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:16830
static basic_json from_ubjson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:19260
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:6528
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:17929
error_handler_t
how to treat decoding errors
Definition: json.hpp:10795
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:16624
double double
Definition: precision.hpp:19
std::initializer_list< detail::json_ref< basic_json >> initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:12473
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:10806
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:9080
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:14093
#define JSON_CATCH(exception)
Definition: json.hpp:164
bool unexpect_eof(const input_format_t format, const char *context) const
Definition: json.hpp:8240
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:13075
constexpr auto get_ptr() const noexcept-> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:14981
static basic_json from_bson(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:19343
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition: json.hpp:4425
typename BasicJsonType::string_t string_t
Definition: json.hpp:4441
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:9738
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:5932
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:3988
value_t
the JSON type enumeration
Definition: json.hpp:1159
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:13545
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:5420
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:5970
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:10257
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:6192
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:15647
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:3836
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:16632
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:5556
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:15881
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:6150
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:1776
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:9324
~basic_json() noexcept
destructor
Definition: json.hpp:14163
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:13131
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:13508
static void fill_buffer(const WideStringType &str, size_t &current_wchar, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:2176
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:13133
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:14932
static void strtof(long double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:3272
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:268
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:1820
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:15075
bool start_array(std::size_t len)
Definition: json.hpp:4339
typename BasicJsonType::string_t string_t
Definition: json.hpp:4266
static basic_json from_cbor(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:19071
void destroy(value_t t) noexcept
Definition: json.hpp:13254
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:5394
bool number_integer(number_integer_t val)
Definition: json.hpp:4289
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:13219
typename BasicJsonType::string_t string_t
Definition: json.hpp:6375
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:15717
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:6126
a signed integer – use get_number_integer() for actual value
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition: json.hpp:4730
constexpr int kAlpha
Definition: json.hpp:9979
array (ordered collection of values)
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:19526
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:9070
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11623
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:5382
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:13007
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:14273
boolean_t boolean
boolean
Definition: json.hpp:13135
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:18049
static other_error create(int id_, const std::string &what_arg)
Definition: json.hpp:1107
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:5767
static bool sax_parse(IteratorType first, IteratorType last, SAX *sax)
Definition: json.hpp:18458
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:13152
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:13154
friend class basic_json
Definition: json.hpp:11599
T const & operator+(T const &value, StreamEndStop)
Definition: catch.hpp:417
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:9646
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:12138
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:12936
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:15446
a template for a reverse iterator class
Definition: json.hpp:6121
bool start_object(std::size_t=std::size_t(-1))
Definition: json.hpp:4786
const char indent_char
the indentation character
Definition: json.hpp:11495
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:5596
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:14303
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:835
a class to store JSON values
Definition: json.hpp:86
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:18783
constexpr diyfp(uint64_t f_, int e_) noexcept
Definition: json.hpp:9732
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:18778
constexpr int kGamma
Definition: json.hpp:9980
bool operator==(const iteration_proxy_internal &o) const noexcept
equality operator (needed for InputIterator)
Definition: json.hpp:1650
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:12529
not_this_one end(...)
typename T::iterator iterator_t
Definition: json.hpp:460
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:19483
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:7728
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:6264
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:17296
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:2478
value_type moved_or_copied() const
Definition: json.hpp:11550
typename BasicJsonType::string_t string_t
Definition: json.hpp:4039
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:13417
default JSONSerializer template argument
Definition: json.hpp:74
std::shared_ptr< output_adapter_protocol< CharType >> output_adapter_t
a type to simplify interfaces
Definition: json.hpp:6234
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:17467
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:5799
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:14644
typename lexer_t::token_type token_type
Definition: json.hpp:4846
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:14668
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:14330
static std::string escape(std::string s)
escape "~" to "~0" and "/" to "~1"
Definition: json.hpp:12150
input_adapter(T(&array)[N])
input adapter for array
Definition: json.hpp:2420
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:18197
type_error(int id_, const char *what_arg)
Definition: json.hpp:1031
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
Definition: json.hpp:4615
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:12548
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:9175
StringType string_t
a type for a string
Definition: json.hpp:12838
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:2033
lexer_t m_lexer
the lexer
Definition: json.hpp:5306
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:4888
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:9832
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:6620
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:16321
static std::string position_string(const position_t &pos)
Definition: json.hpp:924
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
Definition: json.hpp:12739
number value (signed integer)
char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:10727
std::char_traits< char >::int_type get_character() noexceptoverride
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:2155
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:2477
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:13821
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:165
Target reinterpret_bits(const Source source)
Definition: json.hpp:9716
bool operator!=(const iteration_proxy_internal &o) const noexcept
inequality operator (needed for range-based for)
Definition: json.hpp:1656
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:6003
void dump_integer(NumberType x)
dump an integer
Definition: json.hpp:11305
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:17611
Definition: json.hpp:20160
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:16250
output_adapter(StringType &s)
Definition: json.hpp:6315
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:1746
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:19651
auto operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
Definition: json.hpp:1556
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:6162
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:6180
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:12521
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
Definition: json.hpp:12158
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:17081
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:9573
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:17373
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6372
input_adapter(CharT b, std::size_t l)
input adapter for buffer
Definition: json.hpp:2364
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:17898
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:11722
pointer m_object
associated JSON instance
Definition: json.hpp:6078
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:10853
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:18095
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:1701
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:5961
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:16399
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:13139
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:5654
number_float_t number_float
number (floating-point)
Definition: json.hpp:13141
pointer operator->() const
dereference the iterator
Definition: json.hpp:5722
a template for a bidirectional iterator for the basic_json class
Definition: json.hpp:5511
ignore invalid UTF-8 sequences
token_type get_token()
get next token from lexer
Definition: json.hpp:5266
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:17853
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:1243
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:762
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:12457
bool parse_cbor_internal(const bool get_char=true)
Definition: json.hpp:6686
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:5531
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:14511
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:6312
void write_character(CharType c) override
Definition: json.hpp:6291
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:9996
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:7672
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:4019
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:6131
#define JSON_UNLIKELY(x)
Definition: json.hpp:194
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:12063
lexical analysis
Definition: json.hpp:2475
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:6168
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:1788
void write_bson(const BasicJsonType &j)
Definition: json.hpp:8363
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:3781
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:6024
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:5355
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4751
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:2591
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12261
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:1537
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:18106
syntax analysis
Definition: json.hpp:4839
void emplace_back(Args &&...args)
add an object to an array
Definition: json.hpp:17158
serialization to CBOR and MessagePack values
Definition: json.hpp:8344
std::false_type value_t
Definition: json.hpp:369
name
Definition: setup.py:39
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:16558
output adapter for byte vectors
Definition: json.hpp:6238
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:14662
const std::size_t byte
byte index of the parse error
Definition: json.hpp:918
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:6186
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
Definition: json.hpp:4734
abstract input adapter interface
Definition: json.hpp:2087
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:6250
typename BasicJsonType::number_unsigned_t number_unsigned_t
type for unsigned integers
Definition: json.hpp:4144
void unget()
unget current character (read it again on next get)
Definition: json.hpp:3725
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:13148
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:18141
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:5454
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:1902
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:5923
static void strtof(double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:3267
throw a type_error exception in case of invalid UTF-8
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:13794
json_ref(Args &&...args)
Definition: json.hpp:11539
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:4301
exception indicating access out of the defined range
Definition: json.hpp:1067
bool next_byte_in_range(std::initializer_list< int > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:2639
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:14352
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:14489
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4439
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
Definition: json.hpp:4866
token_type scan()
Definition: json.hpp:3850
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:8175
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:5407
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:12469
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:16159
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:15408
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:5349
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:469
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:8627
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:9143
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:9815
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:15167
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:13441
typename BasicJsonType::exception exception_t
Definition: json.hpp:4040
primitive_iterator_t const operator++(int) noexcept
Definition: json.hpp:5400
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:16073
void add(int c)
add a character to token_buffer
Definition: json.hpp:3752
typename T::difference_type difference_type_t
Definition: json.hpp:448
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:4956
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:18003
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:14010
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:4442
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:5914
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:3791
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:9088
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:5756
const_reference back() const
access the last element
Definition: json.hpp:15824
not_this_one begin(...)
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:4015
static iteration_proxy< const_iterator > iterator_wrapper(const_reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:16567
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:397
const WideStringType & str
the wstring to process
Definition: json.hpp:2321
const_reference front() const
access the first element
Definition: json.hpp:15778
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:4260
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:384
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:1868
bool is_root() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11697
void clear() noexcept
clears the contents
Definition: json.hpp:16900
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:17325
static T * create(Args &&...args)
helper for exception-safe object creation
Definition: json.hpp:13083
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:17130
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4037
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:3763
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:14404
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:16210
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:19949
exception indicating a parse error
Definition: json.hpp:882
reference operator[](T *key)
access specified object element
Definition: json.hpp:15535
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:14621
#define JSON_THROW(exception)
Definition: json.hpp:162
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:3775
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:6135
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:15316
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:18883
const char * what() const noexceptoverride
returns the explanatory string
Definition: json.hpp:817
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:19412
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:4027
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:19590
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:381
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:6138
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:4471
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:1812
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:4022
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:15265
std::vector< CharType > & v
Definition: json.hpp:6256
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:7709
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:6128
Grid< NDIM, T > operator*(Grid< NDIM, T > lhs, const Grid< NDIM, T > &rhs)
Definition: grid.h:195
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:3671
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:5458
position_t position
the start position of the current token
Definition: json.hpp:3932
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:15495
abstract output adapter interface
Definition: json.hpp:6225
static basic_json from_msgpack(detail::input_adapter &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:19176
void write_character(CharType c) override
Definition: json.hpp:6245
#define JSON_DEPRECATED
Definition: json.hpp:152
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:18687
general exception of the basic_json class
Definition: json.hpp:813
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:20172
basic_json(const detail::json_ref< basic_json > &ref)
Definition: json.hpp:13981
IteratorType::reference container
the container to iterate
Definition: json.hpp:1697
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:16760
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:479
bool sax_parse_internal(SAX *sax)
Definition: json.hpp:4975
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:18868
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:9857
out_of_range(int id_, const char *what_arg)
Definition: json.hpp:1077
static basic_json from_cbor(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:19086
bool get_cbor_object(const std::size_t len)
Definition: json.hpp:7153
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:11802
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:18675
value_type const * operator->() const
Definition: json.hpp:11564
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:9102
char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:10594
std::string pop_back()
remove and return last reference pointer
Definition: json.hpp:11684
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4843
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:11500
reference back()
access the last element
Definition: json.hpp:15814
static basic_json from_msgpack(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:19191
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:1800
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:5456
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
Definition: json.hpp:2025
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:6657
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:5545
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:17842
bool number_integer(number_integer_t val)
Definition: json.hpp:4465
output_adapter(std::vector< CharType > &vec)
Definition: json.hpp:6309
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:18544
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:6080
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:11878
void dump_float(number_float_t x, std::false_type)
Definition: json.hpp:11375
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:16260
input_adapter(CharT b)
input adapter for string literal
Definition: json.hpp:2376
exception indicating errors with iterators
Definition: json.hpp:968
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:16428
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:14374
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:1182
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:1504
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:18945
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:10497
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:14680
namespace for Niels Lohmann
Definition: json.hpp:64
bool number_integer(number_integer_t)
Definition: json.hpp:4766
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:4477
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:11532
bool get_cbor_array(const std::size_t len)
Definition: json.hpp:7117
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:15986
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:14674
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:14555
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:6471
constexpr difference_type get_value() const noexcept
Definition: json.hpp:5343
input adapter for buffer input
Definition: json.hpp:2141
an floating point number – use get_number_float() for actual value
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:10807
bool start_object(std::size_t len)
Definition: json.hpp:4313
object (unordered set of name/value pairs)
void write_number(const NumberType n)
Definition: json.hpp:9594
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:14727
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:1641
static CCL_BEGIN_DECLS double x[111][8]
void dump_float(number_float_t x, std::true_type)
Definition: json.hpp:11367
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:15062
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4841
static T max(const std::vector< T > &data)
Definition: core_app.cpp:61
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:4869
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:265
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:5540
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:247
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12267
exception indicating executing a member function with a wrong type
Definition: json.hpp:1021
value_t m_type
the type of the current element
Definition: json.hpp:18574
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:13150
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:18060
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:35
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:12171
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:9048
BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:4399
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:9345
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:5361
void assert_invariant() const noexcept
checks the class invariants
Definition: json.hpp:13299
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4440
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:3262
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:18502
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:4443
#define JSON_LIKELY(x)
Definition: json.hpp:193
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6373
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:17771
static basic_json from_ubjson(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:19275
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:1876
static auto from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:12304
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:19553
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:18221
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:12467
typename parser::parse_event_t parse_event_t
parser event types
Definition: json.hpp:13326
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4752
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:18472
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:3992
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:17007
static bool sax_parse(detail::input_adapter &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true)
generate SAX events
Definition: json.hpp:18371
iterator insert_iterator(const_iterator pos, Args &&...args)
Definition: json.hpp:17236
typename T::value_type value_type_t
Definition: json.hpp:445
output_vector_adapter(std::vector< CharType > &vec) noexcept
Definition: json.hpp:6241
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:17112
bool get_ubjson_value(const int prefix)
Definition: json.hpp:7898
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:6273
bool parse_error(std::size_t, const std::string &, const detail::exception &ex)
Definition: json.hpp:4358
wide_string_input_adapter(const WideStringType &w) noexcept
Definition: json.hpp:2292
bool start_array(std::size_t=std::size_t(-1))
Definition: json.hpp:4801
Grid< NDIM, T > operator-(Grid< NDIM, T > lhs, const Grid< NDIM, T > &rhs)
Definition: grid.h:189
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:18436
j template void())
Definition: json.hpp:1424
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:9185
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:3984
typename BasicJsonType::number_float_t number_float_t
type for floating-point numbers
Definition: json.hpp:4146
void merge_patch(const basic_json &patch)
applies a JSON Merge Patch
Definition: json.hpp:20125
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:9201
static invalid_iterator create(int id_, const std::string &what_arg)
Definition: json.hpp:971
std::is_same< Expected, detected_t< Op, Args... >> is_detected_exact
Definition: json.hpp:393
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
Definition: json.hpp:12785
typename BasicJsonType::exception exception_t
Definition: json.hpp:4072
const char * cursor
pointer to the current character
Definition: json.hpp:2167
static int array_index(const std::string &s)
Definition: json.hpp:11665
std::string get_token_string() const
Definition: json.hpp:8253
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:4423
#define JSON_TRY
Definition: json.hpp:163
typename BasicJsonType::string_t string_t
Definition: json.hpp:4844
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
typename T::key_type key_type_t
Definition: json.hpp:442
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:14582
output adapter for basic_string
Definition: json.hpp:6284
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:17509
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:6496
input_stream_adapter(std::istream &i)
Definition: json.hpp:2116
input_adapter(const std::u32string &ws)
Definition: json.hpp:2354
input_adapter(std::istream &&i)
input adapter for input stream
Definition: json.hpp:2345
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:12864
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:18084
constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:3823
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4753
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:4771
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:8354
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:4949
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:12234
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:10644
output adapter for output streams
Definition: json.hpp:6261
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:5685
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:9309
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:34
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:16997
typename BasicJsonType::object_t object_t
Definition: json.hpp:5518
void dump_float(number_float_t x)
dump a floating-point number
Definition: json.hpp:11346
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:5878
input_adapter(const std::wstring &ws)
Definition: json.hpp:2348
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:8218
json_ref(value_type &&value)
Definition: json.hpp:11524
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:14433
exception indicating other library errors
Definition: json.hpp:1104
typename BasicJsonType::number_integer_t number_integer_t
type for (signed) integers
Definition: json.hpp:4142
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4070
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:4000
invalid_iterator(int id_, const char *what_arg)
Definition: json.hpp:978
static std::size_t calc_bson_entry_header_size(const string_t &name)
Definition: json.hpp:9033
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:828
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:5367
typename BasicJsonType::string_t string_t
Definition: json.hpp:10805
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:16290
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:18152
void swap(array_t &other)
exchanges the values
Definition: json.hpp:17643
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:4665
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:4008
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:14632
auto range(T const &first, T const &last) -> Generator< T >
Definition: catch.hpp:3156
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:12531
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:6370
const std::string & key() const
return key of the iterator
Definition: json.hpp:1662
static void to_bson(const basic_json &j, detail::output_adapter< uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:18960
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:12002
bool get_ubjson_size_value(std::size_t &result)
Definition: json.hpp:7782
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:2019
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:18968
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:5534
static int p
Definition: ccl_emu17.c:25
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:11445
std::size_t lines_read
the number of lines read
Definition: json.hpp:764
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:3996
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:4273
std::char_traits< char >::int_type get_character() override
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:2129
T min(const std::vector< T > &data)
Definition: chameleon.cpp:140
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4038
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:9110
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:7574
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:5372
constexpr bool is_errored() const
Definition: json.hpp:4386
std::basic_ostream< CharType > & stream
Definition: json.hpp:6279
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:20190
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:14461
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:14650
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:9354
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:18877
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:1840
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:1705
static constexpr std::size_t size() noexcept
Definition: json.hpp:277
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:13237
void write_character(CharType c) override
Definition: json.hpp:6268
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:9125
number_integer_t number_integer
number (integer)
Definition: json.hpp:13137
static auto to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< ValueType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:12321
BasicJsonType value_type
Definition: json.hpp:11522
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:466
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:11642
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:9624
void swap(string_t &other)
exchanges the values
Definition: json.hpp:17709
std::vector< bool > keep_stack
stack to manage which values to keep
Definition: json.hpp:4732
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:5605
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4842
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:9221
exception(int id_, const char *what_arg)
Definition: json.hpp:826
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:13243
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:8266
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:9060
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:1690
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:15740
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:5810
replace invalid UTF-8 sequences with U+FFFD
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:17274
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:14533
typename make_void< Ts... >::type void_t
Definition: json.hpp:345
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:6384
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:1854
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:16331
std::less< StringType > object_comparator_t
Definition: json.hpp:12649
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:16465
typename BasicJsonType::string_t string_t
Definition: json.hpp:2480
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:9617
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:1635
typename BasicJsonType::string_t string_t
Definition: json.hpp:8346
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:4445
input_format_t
the supported input formats
Definition: json.hpp:2070
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4438
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4069
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:1885
static out_of_range create(int id_, const std::string &what_arg)
Definition: json.hpp:1070
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:17426
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:10808
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:2506
static int m[2]
Definition: ccl_emu17.c:25
typename BasicJsonType::string_t string_t
Definition: json.hpp:4071
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:13146
void dump_escaped(const string_t &s, const bool ensure_ascii)
dump escaped string
Definition: json.hpp:11060
static basic_json from_bson(A1 &&a1, A2 &&a2, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:19358
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:5536
token_type scan_literal(const char *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:3651
static bool accept(detail::input_adapter &&i)
Definition: json.hpp:18309
primitive_iterator_t const operator--(int) noexcept
Definition: json.hpp:5413
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:390
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:15362
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:19440
std::char_traits< char >::int_type get_character() noexceptoverride
get a character [0,255] or std::char_traits<char>::eof().
Definition: json.hpp:2296
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:4728
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:15214
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:16971
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:8869
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:18014
reference front()
access the first element
Definition: json.hpp:15770
JSON Pointer.
Definition: json.hpp:100
string_t dump(const int indent=-1, const char indent_char= ' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:14221
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:16391
token_type scan_number()
scan a number literal
Definition: json.hpp:3317
bool get_ubjson_size_type(std::pair< std::size_t, int > &result)
determine the type and size for a container
Definition: json.hpp:7859
struct to capture the start position of the current token
Definition: json.hpp:757
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:5905
number value (unsigned integer)
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:12523
typename BasicJsonType::array_t array_t
Definition: json.hpp:5519
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:16494
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:10818
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.hpp:9497
static constexpr bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:6457
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:4012
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:509
static bool accept(IteratorType first, IteratorType last)
Definition: json.hpp:18449
basic_json & 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:14130
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:11943
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:17887
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:18300
typename T::iterator_category iterator_category_t
Definition: json.hpp:457
std::istream & is
the associated input stream
Definition: json.hpp:2136
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:5389
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4068
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:6055
input_adapter(std::istream &i)
input adapter for input stream
Definition: json.hpp:2341
auto value(T const &val) -> Generator< T >
Definition: catch.hpp:3177
static void fill_buffer(const WideStringType &str, size_t &current_wchar, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:2231
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:5869
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:6174
void swap(object_t &other)
exchanges the values
Definition: json.hpp:17676
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:13231
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:463
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:18771
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4263
static char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:2565
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:10556
typename T::reference reference_t
Definition: json.hpp:454
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:16361
proxy class for the items() function
Definition: json.hpp:1606
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:14704
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:6156
reference value() const
return the value of an iterator
Definition: json.hpp:6071
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:5842
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:4295
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4265
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:17057
void write_bson_unsigned(const string_t &name, const std::uint64_t value)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:9153
void write_characters(const CharType *s, std::size_t length) override
Definition: json.hpp:6296
string_t indent_string
the indentation string
Definition: json.hpp:11497
other_error(int id_, const char *what_arg)
Definition: json.hpp:1114
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:14698
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:13662
lexer(detail::input_adapter_t &&adapter)
Definition: json.hpp:2549
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:5377
SAX interface.
Definition: json.hpp:4139
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:13751
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:18038
number value (floating-point)
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:16108
token_type scan_string()
scan a string literal
Definition: json.hpp:2676
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4264
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:18130
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:1711
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4036
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:12274
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:17876
input_adapter(const std::u16string &ws)
Definition: json.hpp:2351
const char *const limit
pointer past the last character
Definition: json.hpp:2169
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:7028
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:8383
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:2479
typename BasicJsonType::string_t string_t
Definition: json.hpp:4754
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
Definition: json.hpp:901
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:1734
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
Definition: json.hpp:17206
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:760
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:14710
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:1754
static double w[2][28][111]
Definition: ccl_emu17.c:33
static type_error create(int id_, const std::string &what_arg)
Definition: json.hpp:1024
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:239
bool parse_bson_element_internal(const int element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:6549
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:5271
void grisu2_round(char *buf, int len, uint64_t dist, uint64_t delta, uint64_t rest, uint64_t ten_k)
Definition: json.hpp:10216
std::string get_token_string() const
Definition: json.hpp:3799
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:12526
json_ref(const value_type &value)
Definition: json.hpp:11528
input_adapter(const ContiguousContainer &c)
input adapter for contiguous container
Definition: json.hpp:2428
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:9266
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:6144
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:7650
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:6287
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:894
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:5426
auto get_ptr() noexcept-> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:14968
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:18682
int find_largest_pow10(const uint32_t n, uint32_t &pow10)
Definition: json.hpp:10160
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:9359
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true)
Definition: json.hpp:6397
json_value m_value
the value of the current element
Definition: json.hpp:18577
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6374
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:15585
typename BasicJsonType::string_t string_t
type for strings
Definition: json.hpp:4148
json_pointer top() const
Definition: json.hpp:11702
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:5981
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:16436
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:33
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:15669
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:16688
typename T::mapped_type mapped_type_t
Definition: json.hpp:439
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:5617
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:4776
static basic_json meta()
returns version information on the library
Definition: json.hpp:12579
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:9750
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:14686