Electroneum
json.hpp
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 2.1.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28 
29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
31 
32 #include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
33 #include <array> // array
34 #include <cassert> // assert
35 #include <ciso646> // and, not, or
36 #include <clocale> // lconv, localeconv
37 #include <cmath> // isfinite, labs, ldexp, signbit
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <cstdint> // int64_t, uint64_t
40 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
41 #include <cstring> // memcpy, strlen
42 #include <forward_list> // forward_list
43 #include <functional> // function, hash, less
44 #include <initializer_list> // initializer_list
45 #include <iomanip> // hex
46 #include <iostream> // istream, ostream
47 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
48 #include <limits> // numeric_limits
49 #include <locale> // locale
50 #include <map> // map
51 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
52 #include <numeric> // accumulate
53 #include <sstream> // stringstream
54 #include <string> // getline, stoi, string, to_string
55 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
56 #include <utility> // declval, forward, make_pair, move, pair, swap
57 #include <vector> // vector
58 
59 // exclude unsupported compilers
60 #if defined(__clang__)
61  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
62  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
63  #endif
64 #elif defined(__GNUC__)
65  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
66  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
67  #endif
68 #endif
69 
70 // disable float-equal warnings on GCC/clang
71 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
72  #pragma GCC diagnostic push
73  #pragma GCC diagnostic ignored "-Wfloat-equal"
74 #endif
75 
76 // disable documentation warnings on clang
77 #if defined(__clang__)
78  #pragma GCC diagnostic push
79  #pragma GCC diagnostic ignored "-Wdocumentation"
80 #endif
81 
82 // allow for portable deprecation warnings
83 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
84  #define JSON_DEPRECATED __attribute__((deprecated))
85 #elif defined(_MSC_VER)
86  #define JSON_DEPRECATED __declspec(deprecated)
87 #else
88  #define JSON_DEPRECATED
89 #endif
90 
91 // allow to disable exceptions
92 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
93  #define JSON_THROW(exception) throw exception
94  #define JSON_TRY try
95  #define JSON_CATCH(exception) catch(exception)
96 #else
97  #define JSON_THROW(exception) std::abort()
98  #define JSON_TRY if(true)
99  #define JSON_CATCH(exception) if(false)
100 #endif
101 
102 // manual branch prediction
103 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
104  #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
105  #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
106 #else
107  #define JSON_LIKELY(x) x
108  #define JSON_UNLIKELY(x) x
109 #endif
110 
116 namespace nlohmann
117 {
118 
127 namespace detail
128 {
130 // exceptions //
132 
145 class exception : public std::exception
146 {
147  public:
149  virtual const char* what() const noexcept override
150  {
151  return m.what();
152  }
153 
155  const int id;
156 
157  protected:
158  exception(int id_, const char* what_arg)
159  : id(id_), m(what_arg)
160  {}
161 
162  static std::string name(const std::string& ename, int id)
163  {
164  return "[json.exception." + ename + "." + std::to_string(id) + "] ";
165  }
166 
167  private:
169  std::runtime_error m;
170 };
171 
207 class parse_error : public exception
208 {
209  public:
218  static parse_error create(int id, size_t byte_, const std::string& what_arg)
219  {
220  std::string w = exception::name("parse_error", id) + "parse error" +
221  (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
222  ": " + what_arg;
223  return parse_error(id, byte_, w.c_str());
224  }
225 
236  const size_t byte;
237 
238  private:
239  parse_error(int id_, size_t byte_, const char* what_arg)
240  : exception(id_, what_arg), byte(byte_)
241  {}
242 };
243 
269 {
270  public:
271  static invalid_iterator create(int id, const std::string& what_arg)
272  {
273  std::string w = exception::name("invalid_iterator", id) + what_arg;
274  return invalid_iterator(id, w.c_str());
275  }
276 
277  private:
278  invalid_iterator(int id_, const char* what_arg)
279  : exception(id_, what_arg)
280  {}
281 };
282 
307 class type_error : public exception
308 {
309  public:
310  static type_error create(int id, const std::string& what_arg)
311  {
312  std::string w = exception::name("type_error", id) + what_arg;
313  return type_error(id, w.c_str());
314  }
315 
316  private:
317  type_error(int id_, const char* what_arg)
318  : exception(id_, what_arg)
319  {}
320 };
321 
338 class out_of_range : public exception
339 {
340  public:
341  static out_of_range create(int id, const std::string& what_arg)
342  {
343  std::string w = exception::name("out_of_range", id) + what_arg;
344  return out_of_range(id, w.c_str());
345  }
346 
347  private:
348  out_of_range(int id_, const char* what_arg)
349  : exception(id_, what_arg)
350  {}
351 };
352 
364 class other_error : public exception
365 {
366  public:
367  static other_error create(int id, const std::string& what_arg)
368  {
369  std::string w = exception::name("other_error", id) + what_arg;
370  return other_error(id, w.c_str());
371  }
372 
373  private:
374  other_error(int id_, const char* what_arg)
375  : exception(id_, what_arg)
376  {}
377 };
378 
379 
380 
382 // JSON type enumeration //
384 
409 enum class value_t : uint8_t
410 {
411  null,
412  object,
413  array,
414  string,
415  boolean,
418  number_float,
419  discarded
420 };
421 
431 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
432 {
433  static constexpr std::array<uint8_t, 8> order = {{
434  0, // null
435  3, // object
436  4, // array
437  5, // string
438  1, // boolean
439  2, // integer
440  2, // unsigned
441  2, // float
442  }
443  };
444 
445  // discarded values are not comparable
446  if (lhs == value_t::discarded or rhs == value_t::discarded)
447  {
448  return false;
449  }
450 
451  return order[static_cast<std::size_t>(lhs)] <
452  order[static_cast<std::size_t>(rhs)];
453 }
454 
455 
457 // helpers //
459 
460 // alias templates to reduce boilerplate
461 template<bool B, typename T = void>
463 
464 template<typename T>
466 
467 /*
468 Implementation of two C++17 constructs: conjunction, negation. This is needed
469 to avoid evaluating all the traits in a condition
470 
471 For example: not std::is_same<void, T>::value and has_value_type<T>::value
472 will not compile when T = void (on MSVC at least). Whereas
473 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
474 stop evaluating if negation<...>::value == false
475 
476 Please note that those constructs must be used with caution, since symbols can
477 become very long quickly (which can slow down compilation and cause MSVC
478 internal compiler errors). Only use it when you have to (see example ahead).
479 */
480 template<class...> struct conjunction : std::true_type {};
481 template<class B1> struct conjunction<B1> : B1 {};
482 template<class B1, class... Bn>
483 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
484 
485 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
486 
487 // dispatch utility (taken from ranges-v3)
488 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
489 template<> struct priority_tag<0> {};
490 
491 
493 // constructors //
495 
496 template<value_t> struct external_constructor;
497 
498 template<>
500 {
501  template<typename BasicJsonType>
502  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
503  {
504  j.m_type = value_t::boolean;
505  j.m_value = b;
506  j.assert_invariant();
507  }
508 };
509 
510 template<>
512 {
513  template<typename BasicJsonType>
514  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
515  {
516  j.m_type = value_t::string;
517  j.m_value = s;
518  j.assert_invariant();
519  }
520 };
521 
522 template<>
524 {
525  template<typename BasicJsonType>
526  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
527  {
528  j.m_type = value_t::number_float;
529  j.m_value = val;
530  j.assert_invariant();
531  }
532 };
533 
534 template<>
536 {
537  template<typename BasicJsonType>
538  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
539  {
540  j.m_type = value_t::number_unsigned;
541  j.m_value = val;
542  j.assert_invariant();
543  }
544 };
545 
546 template<>
548 {
549  template<typename BasicJsonType>
550  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
551  {
552  j.m_type = value_t::number_integer;
553  j.m_value = val;
554  j.assert_invariant();
555  }
556 };
557 
558 template<>
560 {
561  template<typename BasicJsonType>
562  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
563  {
564  j.m_type = value_t::array;
565  j.m_value = arr;
566  j.assert_invariant();
567  }
568 
569  template<typename BasicJsonType, typename CompatibleArrayType,
570  enable_if_t<not std::is_same<CompatibleArrayType,
571  typename BasicJsonType::array_t>::value,
572  int> = 0>
573  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
574  {
575  using std::begin;
576  using std::end;
577  j.m_type = value_t::array;
578  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
579  j.assert_invariant();
580  }
581 
582  template<typename BasicJsonType>
583  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
584  {
585  j.m_type = value_t::array;
586  j.m_value = value_t::array;
587  j.m_value.array->reserve(arr.size());
588  for (bool x : arr)
589  {
590  j.m_value.array->push_back(x);
591  }
592  j.assert_invariant();
593  }
594 };
595 
596 template<>
598 {
599  template<typename BasicJsonType>
600  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
601  {
602  j.m_type = value_t::object;
603  j.m_value = obj;
604  j.assert_invariant();
605  }
606 
607  template<typename BasicJsonType, typename CompatibleObjectType,
608  enable_if_t<not std::is_same<CompatibleObjectType,
609  typename BasicJsonType::object_t>::value,
610  int> = 0>
611  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
612  {
613  using std::begin;
614  using std::end;
615 
616  j.m_type = value_t::object;
617  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
618  j.assert_invariant();
619  }
620 };
621 
622 
624 // has_/is_ functions //
626 
637 #define NLOHMANN_JSON_HAS_HELPER(type) \
638  template<typename T> struct has_##type { \
639  private: \
640  template<typename U, typename = typename U::type> \
641  static int detect(U &&); \
642  static void detect(...); \
643  public: \
644  static constexpr bool value = \
645  std::is_integral<decltype(detect(std::declval<T>()))>::value; \
646  }
647 
648 NLOHMANN_JSON_HAS_HELPER(mapped_type);
649 NLOHMANN_JSON_HAS_HELPER(key_type);
650 NLOHMANN_JSON_HAS_HELPER(value_type);
651 NLOHMANN_JSON_HAS_HELPER(iterator);
652 
653 #undef NLOHMANN_JSON_HAS_HELPER
654 
655 
656 template<bool B, class RealType, class CompatibleObjectType>
657 struct is_compatible_object_type_impl : std::false_type {};
658 
659 template<class RealType, class CompatibleObjectType>
660 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
661 {
662  static constexpr auto value =
663  std::is_constructible<typename RealType::key_type,
664  typename CompatibleObjectType::key_type>::value and
665  std::is_constructible<typename RealType::mapped_type,
666  typename CompatibleObjectType::mapped_type>::value;
667 };
668 
669 template<class BasicJsonType, class CompatibleObjectType>
671 {
672  static auto constexpr value = is_compatible_object_type_impl <
674  has_mapped_type<CompatibleObjectType>,
675  has_key_type<CompatibleObjectType>>::value,
676  typename BasicJsonType::object_t, CompatibleObjectType >::value;
677 };
678 
679 template<typename BasicJsonType, typename T>
681 {
682  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
683  std::is_same<T, typename BasicJsonType::const_iterator>::value or
684  std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
685  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
686  std::is_same<T, typename BasicJsonType::json_pointer>::value;
687 };
688 
689 template<class BasicJsonType, class CompatibleArrayType>
691 {
692  static auto constexpr value =
695  BasicJsonType, CompatibleArrayType>>,
696  negation<std::is_constructible<typename BasicJsonType::string_t,
697  CompatibleArrayType>>,
699  has_value_type<CompatibleArrayType>,
700  has_iterator<CompatibleArrayType>>::value;
701 };
702 
703 template<bool, typename, typename>
704 struct is_compatible_integer_type_impl : std::false_type {};
705 
706 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
707 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
708 {
709  // is there an assert somewhere on overflows?
710  using RealLimits = std::numeric_limits<RealIntegerType>;
711  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
712 
713  static constexpr auto value =
714  std::is_constructible<RealIntegerType,
715  CompatibleNumberIntegerType>::value and
716  CompatibleLimits::is_integer and
717  RealLimits::is_signed == CompatibleLimits::is_signed;
718 };
719 
720 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
722 {
723  static constexpr auto value =
725  std::is_integral<CompatibleNumberIntegerType>::value and
726  not std::is_same<bool, CompatibleNumberIntegerType>::value,
727  RealIntegerType, CompatibleNumberIntegerType > ::value;
728 };
729 
730 
731 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
732 template<typename BasicJsonType, typename T>
734 {
735  private:
736  // also check the return type of from_json
738  std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
739  static int detect(U&&);
740  static void detect(...);
741 
742  public:
743  static constexpr bool value = std::is_integral<decltype(
744  detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
745 };
746 
747 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
748 // this overload is used for non-default-constructible user-defined-types
749 template<typename BasicJsonType, typename T>
751 {
752  private:
753  template <
754  typename U,
755  typename = enable_if_t<std::is_same<
756  T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
757  static int detect(U&&);
758  static void detect(...);
759 
760  public:
761  static constexpr bool value = std::is_integral<decltype(detect(
762  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
763 };
764 
765 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
766 template<typename BasicJsonType, typename T>
768 {
769  private:
771  std::declval<BasicJsonType&>(), std::declval<T>()))>
772  static int detect(U&&);
773  static void detect(...);
774 
775  public:
776  static constexpr bool value = std::is_integral<decltype(detect(
777  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
778 };
779 
780 
782 // to_json //
784 
785 template<typename BasicJsonType, typename T, enable_if_t<
786  std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
787 void to_json(BasicJsonType& j, T b) noexcept
788 {
790 }
791 
792 template<typename BasicJsonType, typename CompatibleString,
793  enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
794  CompatibleString>::value, int> = 0>
795 void to_json(BasicJsonType& j, const CompatibleString& s)
796 {
798 }
799 
800 template<typename BasicJsonType, typename FloatType,
801  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
802 void to_json(BasicJsonType& j, FloatType val) noexcept
803 {
804  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
805 }
806 
807 template <
808  typename BasicJsonType, typename CompatibleNumberUnsignedType,
809  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
810  CompatibleNumberUnsignedType>::value, int> = 0 >
811 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
812 {
813  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
814 }
815 
816 template <
817  typename BasicJsonType, typename CompatibleNumberIntegerType,
818  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
819  CompatibleNumberIntegerType>::value, int> = 0 >
820 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
821 {
822  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
823 }
824 
825 template<typename BasicJsonType, typename EnumType,
826  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
827 void to_json(BasicJsonType& j, EnumType e) noexcept
828 {
829  using underlying_type = typename std::underlying_type<EnumType>::type;
830  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
831 }
832 
833 template<typename BasicJsonType>
834 void to_json(BasicJsonType& j, const std::vector<bool>& e)
835 {
837 }
838 
839 template <
840  typename BasicJsonType, typename CompatibleArrayType,
841  enable_if_t <
843  std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
844  int > = 0 >
845 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
846 {
848 }
849 
850 template <
851  typename BasicJsonType, typename CompatibleObjectType,
852  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
853  int> = 0 >
854 void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
855 {
857 }
858 
859 template <typename BasicJsonType, typename T, std::size_t N,
860  enable_if_t<not std::is_constructible<
861  typename BasicJsonType::string_t, T (&)[N]>::value,
862  int> = 0>
863 void to_json(BasicJsonType& j, T (&arr)[N])
864 {
866 }
867 
869 // from_json //
871 
872 // overloads for basic_json template parameters
873 template<typename BasicJsonType, typename ArithmeticType,
874  enable_if_t<std::is_arithmetic<ArithmeticType>::value and
875  not std::is_same<ArithmeticType,
876  typename BasicJsonType::boolean_t>::value,
877  int> = 0>
878 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
879 {
880  switch (static_cast<value_t>(j))
881  {
883  {
884  val = static_cast<ArithmeticType>(
885  *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
886  break;
887  }
889  {
890  val = static_cast<ArithmeticType>(
891  *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
892  break;
893  }
895  {
896  val = static_cast<ArithmeticType>(
897  *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
898  break;
899  }
900  default:
901  {
902  JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
903  }
904  }
905 }
906 
907 template<typename BasicJsonType>
908 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
909 {
910  if (not j.is_boolean())
911  {
912  JSON_THROW(type_error::create(302, "type must be boolean, but is " + j.type_name()));
913  }
914  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
915 }
916 
917 template<typename BasicJsonType>
918 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
919 {
920  if (not j.is_string())
921  {
922  JSON_THROW(type_error::create(302, "type must be string, but is " + j.type_name()));
923  }
924  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
925 }
926 
927 template<typename BasicJsonType>
928 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
929 {
930  get_arithmetic_value(j, val);
931 }
932 
933 template<typename BasicJsonType>
934 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
935 {
936  get_arithmetic_value(j, val);
937 }
938 
939 template<typename BasicJsonType>
940 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
941 {
942  get_arithmetic_value(j, val);
943 }
944 
945 template<typename BasicJsonType, typename EnumType,
946  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
947 void from_json(const BasicJsonType& j, EnumType& e)
948 {
950  get_arithmetic_value(j, val);
951  e = static_cast<EnumType>(val);
952 }
953 
954 template<typename BasicJsonType>
955 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
956 {
957  if (not j.is_array())
958  {
959  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
960  }
961  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
962 }
963 
964 // forward_list doesn't have an insert method
965 template<typename BasicJsonType, typename T, typename Allocator,
966  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
967 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
968 {
969  if (not j.is_array())
970  {
971  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
972  }
973 
974  for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
975  {
976  l.push_front(it->template get<T>());
977  }
978 }
979 
980 template<typename BasicJsonType, typename CompatibleArrayType>
981 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
982 {
983  using std::begin;
984  using std::end;
985 
986  std::transform(j.begin(), j.end(),
987  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
988  {
989  // get<BasicJsonType>() returns *this, this won't call a from_json
990  // method when value_type is BasicJsonType
991  return i.template get<typename CompatibleArrayType::value_type>();
992  });
993 }
994 
995 template<typename BasicJsonType, typename CompatibleArrayType>
996 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
997 -> decltype(
998  arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
999  void())
1000 {
1001  using std::begin;
1002  using std::end;
1003 
1004  arr.reserve(j.size());
1005  std::transform(j.begin(), j.end(),
1006  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1007  {
1008  // get<BasicJsonType>() returns *this, this won't call a from_json
1009  // method when value_type is BasicJsonType
1010  return i.template get<typename CompatibleArrayType::value_type>();
1011  });
1012 }
1013 
1014 template<typename BasicJsonType, typename CompatibleArrayType,
1015  enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1016  std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1017  not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
1018 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1019 {
1020  if (not j.is_array())
1021  {
1022  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
1023  }
1024 
1026 }
1027 
1028 template<typename BasicJsonType, typename CompatibleObjectType,
1029  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1030 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1031 {
1032  if (not j.is_object())
1033  {
1034  JSON_THROW(type_error::create(302, "type must be object, but is " + j.type_name()));
1035  }
1036 
1037  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1038  using std::begin;
1039  using std::end;
1040  // we could avoid the assignment, but this might require a for loop, which
1041  // might be less efficient than the container constructor for some
1042  // containers (would it?)
1043  obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
1044 }
1045 
1046 // overload for arithmetic types, not chosen for basic_json template arguments
1047 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1048 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1049 // an arithmetic type?
1050 template<typename BasicJsonType, typename ArithmeticType,
1051  enable_if_t <
1052  std::is_arithmetic<ArithmeticType>::value and
1053  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1054  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1055  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1056  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1057  int> = 0>
1058 void from_json(const BasicJsonType& j, ArithmeticType& val)
1059 {
1060  switch (static_cast<value_t>(j))
1061  {
1063  {
1064  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1065  break;
1066  }
1068  {
1069  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1070  break;
1071  }
1072  case value_t::number_float:
1073  {
1074  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1075  break;
1076  }
1077  case value_t::boolean:
1078  {
1079  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1080  break;
1081  }
1082  default:
1083  {
1084  JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
1085  }
1086  }
1087 }
1088 
1090 {
1091  private:
1092  template<typename BasicJsonType, typename T>
1093  auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1094  -> decltype(to_json(j, std::forward<T>(val)), void())
1095  {
1096  return to_json(j, std::forward<T>(val));
1097  }
1098 
1099  template<typename BasicJsonType, typename T>
1100  void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
1101  {
1102  static_assert(sizeof(BasicJsonType) == 0,
1103  "could not find to_json() method in T's namespace");
1104  }
1105 
1106  public:
1107  template<typename BasicJsonType, typename T>
1108  void operator()(BasicJsonType& j, T&& val) const
1109  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1110  {
1111  return call(j, std::forward<T>(val), priority_tag<1> {});
1112  }
1113 };
1114 
1116 {
1117  private:
1118  template<typename BasicJsonType, typename T>
1119  auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
1120  noexcept(noexcept(from_json(j, val)))
1121  -> decltype(from_json(j, val), void())
1122  {
1123  return from_json(j, val);
1124  }
1125 
1126  template<typename BasicJsonType, typename T>
1127  void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
1128  {
1129  static_assert(sizeof(BasicJsonType) == 0,
1130  "could not find from_json() method in T's namespace");
1131  }
1132 
1133  public:
1134  template<typename BasicJsonType, typename T>
1135  void operator()(const BasicJsonType& j, T& val) const
1136  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1137  {
1138  return call(j, val, priority_tag<1> {});
1139  }
1140 };
1141 
1142 // taken from ranges-v3
1143 template<typename T>
1145 {
1146  static constexpr T value{};
1147 };
1148 
1149 template<typename T>
1150 constexpr T static_const<T>::value;
1151 } // namespace detail
1152 
1153 
1155 namespace
1156 {
1159 }
1160 
1161 
1169 template<typename = void, typename = void>
1171 {
1181  template<typename BasicJsonType, typename ValueType>
1182  static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
1183  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
1184  {
1185  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
1186  }
1187 
1197  template<typename BasicJsonType, typename ValueType>
1198  static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
1199  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
1200  {
1201  ::nlohmann::to_json(j, std::forward<ValueType>(val));
1202  }
1203 };
1204 
1205 
1287 template <
1288  template<typename U, typename V, typename... Args> class ObjectType = std::map,
1289  template<typename U, typename... Args> class ArrayType = std::vector,
1290  class StringType = std::string,
1291  class BooleanType = bool,
1292  class NumberIntegerType = std::int64_t,
1293  class NumberUnsignedType = std::uint64_t,
1294  class NumberFloatType = double,
1295  template<typename U> class AllocatorType = std::allocator,
1296  template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
1297  >
1299 {
1300  private:
1301  template<detail::value_t> friend struct detail::external_constructor;
1303  using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
1304  BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1305  AllocatorType, JSONSerializer>;
1306 
1307  public:
1309  // forward declarations
1310  template<typename U> class iter_impl;
1311  template<typename Base> class json_reverse_iterator;
1312  class json_pointer;
1313  template<typename T, typename SFINAE>
1314  using json_serializer = JSONSerializer<T, SFINAE>;
1315 
1316 
1318  // exceptions //
1320 
1324 
1337 
1339 
1340 
1342  // container types //
1344 
1349 
1352 
1356  using const_reference = const value_type&;
1357 
1359  using difference_type = std::ptrdiff_t;
1361  using size_type = std::size_t;
1362 
1364  using allocator_type = AllocatorType<basic_json>;
1365 
1367  using pointer = typename std::allocator_traits<allocator_type>::pointer;
1369  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
1370 
1379 
1381 
1382 
1387  {
1388  return allocator_type();
1389  }
1390 
1414  static basic_json meta()
1415  {
1416  basic_json result;
1417 
1418  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
1419  result["name"] = "JSON for Modern C++";
1420  result["url"] = "https://github.com/nlohmann/json";
1421  result["version"] =
1422  {
1423  {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
1424  };
1425 
1426 #ifdef _WIN32
1427  result["platform"] = "win32";
1428 #elif defined __linux__
1429  result["platform"] = "linux";
1430 #elif defined __APPLE__
1431  result["platform"] = "apple";
1432 #elif defined __unix__
1433  result["platform"] = "unix";
1434 #else
1435  result["platform"] = "unknown";
1436 #endif
1437 
1438 #if defined(__clang__)
1439  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
1440 #elif defined(__ICC) || defined(__INTEL_COMPILER)
1441  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
1442 #elif defined(__GNUC__) || defined(__GNUG__)
1443  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
1444 #elif defined(__HP_cc) || defined(__HP_aCC)
1445  result["compiler"] = "hp"
1446 #elif defined(__IBMCPP__)
1447  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
1448 #elif defined(_MSC_VER)
1449  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
1450 #elif defined(__PGI)
1451  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
1452 #elif defined(__SUNPRO_CC)
1453  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
1454 #else
1455  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
1456 #endif
1457 
1458 #ifdef __cplusplus
1459  result["compiler"]["c++"] = std::to_string(__cplusplus);
1460 #else
1461  result["compiler"]["c++"] = "unknown";
1462 #endif
1463  return result;
1464  }
1465 
1466 
1468  // JSON value data types //
1470 
1475 
1559  using object_t = ObjectType<StringType,
1560  basic_json,
1561  std::less<StringType>,
1562  AllocatorType<std::pair<const StringType,
1564 
1609  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1610 
1662  using string_t = StringType;
1663 
1688  using boolean_t = BooleanType;
1689 
1760  using number_integer_t = NumberIntegerType;
1761 
1831  using number_unsigned_t = NumberUnsignedType;
1832 
1899  using number_float_t = NumberFloatType;
1900 
1902 
1903  private:
1904 
1906  template<typename T, typename... Args>
1907  static T* create(Args&& ... args)
1908  {
1909  AllocatorType<T> alloc;
1910  auto deleter = [&](T * object)
1911  {
1912  alloc.deallocate(object, 1);
1913  };
1914  std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1915  alloc.construct(object.get(), std::forward<Args>(args)...);
1916  assert(object != nullptr);
1917  return object.release();
1918  }
1919 
1921  // JSON value storage //
1923 
1949  {
1964 
1966  json_value() = default;
1968  json_value(boolean_t v) noexcept : boolean(v) {}
1977  {
1978  switch (t)
1979  {
1980  case value_t::object:
1981  {
1982  object = create<object_t>();
1983  break;
1984  }
1985 
1986  case value_t::array:
1987  {
1988  array = create<array_t>();
1989  break;
1990  }
1991 
1992  case value_t::string:
1993  {
1994  string = create<string_t>("");
1995  break;
1996  }
1997 
1998  case value_t::boolean:
1999  {
2000  boolean = boolean_t(false);
2001  break;
2002  }
2003 
2005  {
2007  break;
2008  }
2009 
2011  {
2013  break;
2014  }
2015 
2016  case value_t::number_float:
2017  {
2019  break;
2020  }
2021 
2022  case value_t::null:
2023  {
2024  break;
2025  }
2026 
2027  default:
2028  {
2029  if (JSON_UNLIKELY(t == value_t::null))
2030  {
2031  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
2032  }
2033  break;
2034  }
2035  }
2036  }
2037 
2040  {
2041  string = create<string_t>(value);
2042  }
2043 
2046  {
2047  object = create<object_t>(value);
2048  }
2049 
2052  {
2053  array = create<array_t>(value);
2054  }
2055  };
2056 
2066  void assert_invariant() const
2067  {
2068  assert(m_type != value_t::object or m_value.object != nullptr);
2069  assert(m_type != value_t::array or m_value.array != nullptr);
2070  assert(m_type != value_t::string or m_value.string != nullptr);
2071  }
2072 
2073  public:
2075  // JSON parser callback //
2077 
2088  enum class parse_event_t : uint8_t
2089  {
2091  object_start,
2093  object_end,
2095  array_start,
2097  array_end,
2099  key,
2101  value
2102  };
2103 
2156  using parser_callback_t = std::function<bool(int depth,
2157  parse_event_t event,
2158  basic_json& parsed)>;
2159 
2160 
2162  // constructors //
2164 
2169 
2196  {
2197  assert_invariant();
2198  }
2199 
2218  basic_json(std::nullptr_t = nullptr) noexcept
2219  : basic_json(value_t::null)
2220  {
2221  assert_invariant();
2222  }
2223 
2277  template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
2278  detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
2279  not std::is_same<U, basic_json_t>::value and
2280  not detail::is_basic_json_nested_type<
2281  basic_json_t, U>::value and
2282  detail::has_to_json<basic_json, U>::value,
2283  int> = 0>
2284  basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
2285  std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
2286  {
2287  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
2288  assert_invariant();
2289  }
2290 
2362  basic_json(std::initializer_list<basic_json> init,
2363  bool type_deduction = true,
2364  value_t manual_type = value_t::array)
2365  {
2366  // check if each element is an array with two elements whose first
2367  // element is a string
2368  bool is_an_object = std::all_of(init.begin(), init.end(),
2369  [](const basic_json & element)
2370  {
2371  return element.is_array() and element.size() == 2 and element[0].is_string();
2372  });
2373 
2374  // adjust type if type deduction is not wanted
2375  if (not type_deduction)
2376  {
2377  // if array is wanted, do not create an object though possible
2378  if (manual_type == value_t::array)
2379  {
2380  is_an_object = false;
2381  }
2382 
2383  // if object is wanted but impossible, throw an exception
2384  if (manual_type == value_t::object and not is_an_object)
2385  {
2386  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
2387  }
2388  }
2389 
2390  if (is_an_object)
2391  {
2392  // the initializer list is a list of pairs -> create object
2395 
2396  std::for_each(init.begin(), init.end(), [this](const basic_json & element)
2397  {
2398  m_value.object->emplace(*(element[0].m_value.string), element[1]);
2399  });
2400  }
2401  else
2402  {
2403  // the initializer list describes an array -> create array
2405  m_value.array = create<array_t>(init);
2406  }
2407 
2408  assert_invariant();
2409  }
2410 
2445  static basic_json array(std::initializer_list<basic_json> init =
2446  std::initializer_list<basic_json>())
2447  {
2448  return basic_json(init, false, value_t::array);
2449  }
2450 
2486  static basic_json object(std::initializer_list<basic_json> init =
2487  std::initializer_list<basic_json>())
2488  {
2489  return basic_json(init, false, value_t::object);
2490  }
2491 
2511  : m_type(value_t::array)
2512  {
2513  m_value.array = create<array_t>(cnt, val);
2514  assert_invariant();
2515  }
2516 
2559  template<class InputIT, typename std::enable_if<
2560  std::is_same<InputIT, typename basic_json_t::iterator>::value or
2561  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
2562  basic_json(InputIT first, InputIT last)
2563  {
2564  assert(first.m_object != nullptr);
2565  assert(last.m_object != nullptr);
2566 
2567  // make sure iterator fits the current value
2568  if (first.m_object != last.m_object)
2569  {
2570  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
2571  }
2572 
2573  // copy type from first iterator
2574  m_type = first.m_object->m_type;
2575 
2576  // check if iterator range is complete for primitive values
2577  switch (m_type)
2578  {
2579  case value_t::boolean:
2580  case value_t::number_float:
2583  case value_t::string:
2584  {
2585  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2586  {
2587  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
2588  }
2589  break;
2590  }
2591 
2592  default:
2593  {
2594  break;
2595  }
2596  }
2597 
2598  switch (m_type)
2599  {
2601  {
2602  m_value.number_integer = first.m_object->m_value.number_integer;
2603  break;
2604  }
2605 
2607  {
2608  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2609  break;
2610  }
2611 
2612  case value_t::number_float:
2613  {
2614  m_value.number_float = first.m_object->m_value.number_float;
2615  break;
2616  }
2617 
2618  case value_t::boolean:
2619  {
2620  m_value.boolean = first.m_object->m_value.boolean;
2621  break;
2622  }
2623 
2624  case value_t::string:
2625  {
2626  m_value = *first.m_object->m_value.string;
2627  break;
2628  }
2629 
2630  case value_t::object:
2631  {
2632  m_value.object = create<object_t>(first.m_it.object_iterator,
2633  last.m_it.object_iterator);
2634  break;
2635  }
2636 
2637  case value_t::array:
2638  {
2639  m_value.array = create<array_t>(first.m_it.array_iterator,
2640  last.m_it.array_iterator);
2641  break;
2642  }
2643 
2644  default:
2645  {
2646  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
2647  first.m_object->type_name()));
2648  }
2649  }
2650 
2651  assert_invariant();
2652  }
2653 
2654 
2656  // other constructors and destructor //
2658 
2679  basic_json(const basic_json& other)
2680  : m_type(other.m_type)
2681  {
2682  // check of passed value is valid
2683  other.assert_invariant();
2684 
2685  switch (m_type)
2686  {
2687  case value_t::object:
2688  {
2689  m_value = *other.m_value.object;
2690  break;
2691  }
2692 
2693  case value_t::array:
2694  {
2695  m_value = *other.m_value.array;
2696  break;
2697  }
2698 
2699  case value_t::string:
2700  {
2701  m_value = *other.m_value.string;
2702  break;
2703  }
2704 
2705  case value_t::boolean:
2706  {
2707  m_value = other.m_value.boolean;
2708  break;
2709  }
2710 
2712  {
2713  m_value = other.m_value.number_integer;
2714  break;
2715  }
2716 
2718  {
2720  break;
2721  }
2722 
2723  case value_t::number_float:
2724  {
2725  m_value = other.m_value.number_float;
2726  break;
2727  }
2728 
2729  default:
2730  {
2731  break;
2732  }
2733  }
2734 
2735  assert_invariant();
2736  }
2737 
2756  basic_json(basic_json&& other) noexcept
2757  : m_type(std::move(other.m_type)),
2758  m_value(std::move(other.m_value))
2759  {
2760  // check that passed value is valid
2761  other.assert_invariant();
2762 
2763  // invalidate payload
2764  other.m_type = value_t::null;
2765  other.m_value = {};
2766 
2767  assert_invariant();
2768  }
2769 
2793  reference& operator=(basic_json other) noexcept (
2794  std::is_nothrow_move_constructible<value_t>::value and
2795  std::is_nothrow_move_assignable<value_t>::value and
2796  std::is_nothrow_move_constructible<json_value>::value and
2797  std::is_nothrow_move_assignable<json_value>::value
2798  )
2799  {
2800  // check that passed value is valid
2801  other.assert_invariant();
2802 
2803  using std::swap;
2804  swap(m_type, other.m_type);
2805  swap(m_value, other.m_value);
2806 
2807  assert_invariant();
2808  return *this;
2809  }
2810 
2827  {
2828  assert_invariant();
2829 
2830  switch (m_type)
2831  {
2832  case value_t::object:
2833  {
2834  AllocatorType<object_t> alloc;
2835  alloc.destroy(m_value.object);
2836  alloc.deallocate(m_value.object, 1);
2837  break;
2838  }
2839 
2840  case value_t::array:
2841  {
2842  AllocatorType<array_t> alloc;
2843  alloc.destroy(m_value.array);
2844  alloc.deallocate(m_value.array, 1);
2845  break;
2846  }
2847 
2848  case value_t::string:
2849  {
2850  AllocatorType<string_t> alloc;
2851  alloc.destroy(m_value.string);
2852  alloc.deallocate(m_value.string, 1);
2853  break;
2854  }
2855 
2856  default:
2857  {
2858  // all other types need no specific destructor
2859  break;
2860  }
2861  }
2862  }
2863 
2865 
2866  public:
2868  // object inspection //
2870 
2874 
2900  string_t dump(const int indent = -1, const char indent_char = ' ') const
2901  {
2902  string_t result;
2903  serializer s(output_adapter<char>::create(result), indent_char);
2904 
2905  if (indent >= 0)
2906  {
2907  s.dump(*this, true, static_cast<unsigned int>(indent));
2908  }
2909  else
2910  {
2911  s.dump(*this, false, 0);
2912  }
2913 
2914  return result;
2915  }
2916 
2935  constexpr value_t type() const noexcept
2936  {
2937  return m_type;
2938  }
2939 
2965  constexpr bool is_primitive() const noexcept
2966  {
2967  return is_null() or is_string() or is_boolean() or is_number();
2968  }
2969 
2992  constexpr bool is_structured() const noexcept
2993  {
2994  return is_array() or is_object();
2995  }
2996 
3014  constexpr bool is_null() const noexcept
3015  {
3016  return m_type == value_t::null;
3017  }
3018 
3036  constexpr bool is_boolean() const noexcept
3037  {
3038  return m_type == value_t::boolean;
3039  }
3040 
3066  constexpr bool is_number() const noexcept
3067  {
3068  return is_number_integer() or is_number_float();
3069  }
3070 
3095  constexpr bool is_number_integer() const noexcept
3096  {
3098  }
3099 
3123  constexpr bool is_number_unsigned() const noexcept
3124  {
3125  return m_type == value_t::number_unsigned;
3126  }
3127 
3151  constexpr bool is_number_float() const noexcept
3152  {
3153  return m_type == value_t::number_float;
3154  }
3155 
3173  constexpr bool is_object() const noexcept
3174  {
3175  return m_type == value_t::object;
3176  }
3177 
3195  constexpr bool is_array() const noexcept
3196  {
3197  return m_type == value_t::array;
3198  }
3199 
3217  constexpr bool is_string() const noexcept
3218  {
3219  return m_type == value_t::string;
3220  }
3221 
3244  constexpr bool is_discarded() const noexcept
3245  {
3246  return m_type == value_t::discarded;
3247  }
3248 
3267  constexpr operator value_t() const noexcept
3268  {
3269  return m_type;
3270  }
3271 
3273 
3274  private:
3276  // value access //
3278 
3280  boolean_t get_impl(boolean_t* /*unused*/) const
3281  {
3282  if (is_boolean())
3283  {
3284  return m_value.boolean;
3285  }
3286 
3287  JSON_THROW(type_error::create(302, "type must be boolean, but is " + type_name()));
3288  }
3289 
3291  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
3292  {
3293  return is_object() ? m_value.object : nullptr;
3294  }
3295 
3297  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
3298  {
3299  return is_object() ? m_value.object : nullptr;
3300  }
3301 
3303  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
3304  {
3305  return is_array() ? m_value.array : nullptr;
3306  }
3307 
3309  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
3310  {
3311  return is_array() ? m_value.array : nullptr;
3312  }
3313 
3315  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
3316  {
3317  return is_string() ? m_value.string : nullptr;
3318  }
3319 
3321  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
3322  {
3323  return is_string() ? m_value.string : nullptr;
3324  }
3325 
3327  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
3328  {
3329  return is_boolean() ? &m_value.boolean : nullptr;
3330  }
3331 
3333  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
3334  {
3335  return is_boolean() ? &m_value.boolean : nullptr;
3336  }
3337 
3340  {
3341  return is_number_integer() ? &m_value.number_integer : nullptr;
3342  }
3343 
3345  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
3346  {
3347  return is_number_integer() ? &m_value.number_integer : nullptr;
3348  }
3349 
3352  {
3353  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3354  }
3355 
3357  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
3358  {
3359  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3360  }
3361 
3364  {
3365  return is_number_float() ? &m_value.number_float : nullptr;
3366  }
3367 
3369  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
3370  {
3371  return is_number_float() ? &m_value.number_float : nullptr;
3372  }
3373 
3385  template<typename ReferenceType, typename ThisType>
3386  static ReferenceType get_ref_impl(ThisType& obj)
3387  {
3388  // helper type
3389  using PointerType = typename std::add_pointer<ReferenceType>::type;
3390 
3391  // delegate the call to get_ptr<>()
3392  auto ptr = obj.template get_ptr<PointerType>();
3393 
3394  if (ptr != nullptr)
3395  {
3396  return *ptr;
3397  }
3398 
3399  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name()));
3400  }
3401 
3402  public:
3406 
3421  template <
3422  typename BasicJsonType,
3425  int> = 0 >
3426  basic_json get() const
3427  {
3428  return *this;
3429  }
3430 
3470  template <
3471  typename ValueTypeCV,
3472  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3474  not std::is_same<basic_json_t, ValueType>::value and
3477  int > = 0 >
3478  ValueType get() const noexcept(noexcept(
3479  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3480  {
3481  // we cannot static_assert on ValueTypeCV being non-const, because
3482  // there is support for get<const basic_json_t>(), which is why we
3483  // still need the uncvref
3484  static_assert(not std::is_reference<ValueTypeCV>::value,
3485  "get() cannot be used with reference types, you might want to use get_ref()");
3486  static_assert(std::is_default_constructible<ValueType>::value,
3487  "types must be DefaultConstructible when used with get()");
3488 
3489  ValueType ret;
3491  return ret;
3492  }
3493 
3525  template <
3526  typename ValueTypeCV,
3527  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3530  ValueType>::value, int> = 0 >
3531  ValueType get() const noexcept(noexcept(
3532  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
3533  {
3534  static_assert(not std::is_reference<ValueTypeCV>::value,
3535  "get() cannot be used with reference types, you might want to use get_ref()");
3537  }
3538 
3566  template<typename PointerType, typename std::enable_if<
3567  std::is_pointer<PointerType>::value, int>::type = 0>
3568  PointerType get() noexcept
3569  {
3570  // delegate the call to get_ptr
3571  return get_ptr<PointerType>();
3572  }
3573 
3578  template<typename PointerType, typename std::enable_if<
3579  std::is_pointer<PointerType>::value, int>::type = 0>
3580  constexpr const PointerType get() const noexcept
3581  {
3582  // delegate the call to get_ptr
3583  return get_ptr<PointerType>();
3584  }
3585 
3612  template<typename PointerType, typename std::enable_if<
3613  std::is_pointer<PointerType>::value, int>::type = 0>
3614  PointerType get_ptr() noexcept
3615  {
3616  // get the type of the PointerType (remove pointer and const)
3617  using pointee_t = typename std::remove_const<typename
3618  std::remove_pointer<typename
3620  // make sure the type matches the allowed types
3621  static_assert(
3622  std::is_same<object_t, pointee_t>::value
3623  or std::is_same<array_t, pointee_t>::value
3624  or std::is_same<string_t, pointee_t>::value
3625  or std::is_same<boolean_t, pointee_t>::value
3626  or std::is_same<number_integer_t, pointee_t>::value
3627  or std::is_same<number_unsigned_t, pointee_t>::value
3628  or std::is_same<number_float_t, pointee_t>::value
3629  , "incompatible pointer type");
3630 
3631  // delegate the call to get_impl_ptr<>()
3632  return get_impl_ptr(static_cast<PointerType>(nullptr));
3633  }
3634 
3639  template<typename PointerType, typename std::enable_if<
3640  std::is_pointer<PointerType>::value and
3642  constexpr const PointerType get_ptr() const noexcept
3643  {
3644  // get the type of the PointerType (remove pointer and const)
3645  using pointee_t = typename std::remove_const<typename
3646  std::remove_pointer<typename
3648  // make sure the type matches the allowed types
3649  static_assert(
3650  std::is_same<object_t, pointee_t>::value
3651  or std::is_same<array_t, pointee_t>::value
3652  or std::is_same<string_t, pointee_t>::value
3653  or std::is_same<boolean_t, pointee_t>::value
3654  or std::is_same<number_integer_t, pointee_t>::value
3655  or std::is_same<number_unsigned_t, pointee_t>::value
3656  or std::is_same<number_float_t, pointee_t>::value
3657  , "incompatible pointer type");
3658 
3659  // delegate the call to get_impl_ptr<>() const
3660  return get_impl_ptr(static_cast<const PointerType>(nullptr));
3661  }
3662 
3689  template<typename ReferenceType, typename std::enable_if<
3690  std::is_reference<ReferenceType>::value, int>::type = 0>
3691  ReferenceType get_ref()
3692  {
3693  // delegate call to get_ref_impl
3694  return get_ref_impl<ReferenceType>(*this);
3695  }
3696 
3701  template<typename ReferenceType, typename std::enable_if<
3702  std::is_reference<ReferenceType>::value and
3704  ReferenceType get_ref() const
3705  {
3706  // delegate call to get_ref_impl
3707  return get_ref_impl<ReferenceType>(*this);
3708  }
3709 
3739  template < typename ValueType, typename std::enable_if <
3740  not std::is_pointer<ValueType>::value and
3741  not std::is_same<ValueType, typename string_t::value_type>::value
3742 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
3743  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3744 #endif
3745 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
3746  and not std::is_same<ValueType, typename std::string_view>::value
3747 #endif
3748  , int >::type = 0 >
3749  operator ValueType() const
3750  {
3751  // delegate the call to get<>() const
3752  return get<ValueType>();
3753  }
3754 
3756 
3757 
3759  // element access //
3761 
3765 
3793  {
3794  // at only works for arrays
3795  if (is_array())
3796  {
3797  JSON_TRY
3798  {
3799  return m_value.array->at(idx);
3800  }
3801  JSON_CATCH (std::out_of_range&)
3802  {
3803  // create better exception explanation
3804  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3805  }
3806  }
3807  else
3808  {
3809  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3810  }
3811  }
3812 
3840  {
3841  // at only works for arrays
3842  if (is_array())
3843  {
3844  JSON_TRY
3845  {
3846  return m_value.array->at(idx);
3847  }
3848  JSON_CATCH (std::out_of_range&)
3849  {
3850  // create better exception explanation
3851  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3852  }
3853  }
3854  else
3855  {
3856  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3857  }
3858  }
3859 
3890  reference at(const typename object_t::key_type& key)
3891  {
3892  // at only works for objects
3893  if (is_object())
3894  {
3895  JSON_TRY
3896  {
3897  return m_value.object->at(key);
3898  }
3899  JSON_CATCH (std::out_of_range&)
3900  {
3901  // create better exception explanation
3902  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3903  }
3904  }
3905  else
3906  {
3907  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3908  }
3909  }
3910 
3941  const_reference at(const typename object_t::key_type& key) const
3942  {
3943  // at only works for objects
3944  if (is_object())
3945  {
3946  JSON_TRY
3947  {
3948  return m_value.object->at(key);
3949  }
3950  JSON_CATCH (std::out_of_range&)
3951  {
3952  // create better exception explanation
3953  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3954  }
3955  }
3956  else
3957  {
3958  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3959  }
3960  }
3961 
3988  {
3989  // implicitly convert null value to an empty array
3990  if (is_null())
3991  {
3993  m_value.array = create<array_t>();
3994  assert_invariant();
3995  }
3996 
3997  // operator[] only works for arrays
3998  if (is_array())
3999  {
4000  // fill up array with null values if given idx is outside range
4001  if (idx >= m_value.array->size())
4002  {
4003  m_value.array->insert(m_value.array->end(),
4004  idx - m_value.array->size() + 1,
4005  basic_json());
4006  }
4007 
4008  return m_value.array->operator[](idx);
4009  }
4010 
4011  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4012  }
4013 
4034  {
4035  // const operator[] only works for arrays
4036  if (is_array())
4037  {
4038  return m_value.array->operator[](idx);
4039  }
4040 
4041  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4042  }
4043 
4071  reference operator[](const typename object_t::key_type& key)
4072  {
4073  // implicitly convert null value to an empty object
4074  if (is_null())
4075  {
4077  m_value.object = create<object_t>();
4078  assert_invariant();
4079  }
4080 
4081  // operator[] only works for objects
4082  if (is_object())
4083  {
4084  return m_value.object->operator[](key);
4085  }
4086 
4087  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4088  }
4089 
4120  const_reference operator[](const typename object_t::key_type& key) const
4121  {
4122  // const operator[] only works for objects
4123  if (is_object())
4124  {
4125  assert(m_value.object->find(key) != m_value.object->end());
4126  return m_value.object->find(key)->second;
4127  }
4128 
4129  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4130  }
4131 
4159  template<typename T, std::size_t n>
4160  reference operator[](T * (&key)[n])
4161  {
4162  return operator[](static_cast<const T>(key));
4163  }
4164 
4194  template<typename T, std::size_t n>
4195  const_reference operator[](T * (&key)[n]) const
4196  {
4197  return operator[](static_cast<const T>(key));
4198  }
4199 
4227  template<typename T>
4229  {
4230  // implicitly convert null to object
4231  if (is_null())
4232  {
4235  assert_invariant();
4236  }
4237 
4238  // at only works for objects
4239  if (is_object())
4240  {
4241  return m_value.object->operator[](key);
4242  }
4243 
4244  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4245  }
4246 
4277  template<typename T>
4279  {
4280  // at only works for objects
4281  if (is_object())
4282  {
4283  assert(m_value.object->find(key) != m_value.object->end());
4284  return m_value.object->find(key)->second;
4285  }
4286 
4287  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4288  }
4289 
4338  template<class ValueType, typename std::enable_if<
4339  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4340  ValueType value(const typename object_t::key_type& key, ValueType default_value) const
4341  {
4342  // at only works for objects
4343  if (is_object())
4344  {
4345  // if key is found, return value and given default value otherwise
4346  const auto it = find(key);
4347  if (it != end())
4348  {
4349  return *it;
4350  }
4351 
4352  return default_value;
4353  }
4354  else
4355  {
4356  JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
4357  }
4358  }
4359 
4364  string_t value(const typename object_t::key_type& key, const char* default_value) const
4365  {
4366  return value(key, string_t(default_value));
4367  }
4368 
4410  template<class ValueType, typename std::enable_if<
4411  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4412  ValueType value(const json_pointer& ptr, ValueType default_value) const
4413  {
4414  // at only works for objects
4415  if (is_object())
4416  {
4417  // if pointer resolves a value, return it or use default value
4418  JSON_TRY
4419  {
4420  return ptr.get_checked(this);
4421  }
4423  {
4424  return default_value;
4425  }
4426  }
4427 
4428  JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
4429  }
4430 
4435  string_t value(const json_pointer& ptr, const char* default_value) const
4436  {
4437  return value(ptr, string_t(default_value));
4438  }
4439 
4466  {
4467  return *begin();
4468  }
4469 
4474  {
4475  return *cbegin();
4476  }
4477 
4510  {
4511  auto tmp = end();
4512  --tmp;
4513  return *tmp;
4514  }
4515 
4520  {
4521  auto tmp = cend();
4522  --tmp;
4523  return *tmp;
4524  }
4525 
4572  template<class IteratorType, typename std::enable_if<
4573  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4574  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4575  = 0>
4576  IteratorType erase(IteratorType pos)
4577  {
4578  // make sure iterator fits the current value
4579  if (this != pos.m_object)
4580  {
4581  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
4582  }
4583 
4584  IteratorType result = end();
4585 
4586  switch (m_type)
4587  {
4588  case value_t::boolean:
4589  case value_t::number_float:
4592  case value_t::string:
4593  {
4594  if (not pos.m_it.primitive_iterator.is_begin())
4595  {
4596  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
4597  }
4598 
4599  if (is_string())
4600  {
4601  AllocatorType<string_t> alloc;
4602  alloc.destroy(m_value.string);
4603  alloc.deallocate(m_value.string, 1);
4604  m_value.string = nullptr;
4605  }
4606 
4607  m_type = value_t::null;
4608  assert_invariant();
4609  break;
4610  }
4611 
4612  case value_t::object:
4613  {
4614  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4615  break;
4616  }
4617 
4618  case value_t::array:
4619  {
4620  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4621  break;
4622  }
4623 
4624  default:
4625  {
4626  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4627  }
4628  }
4629 
4630  return result;
4631  }
4632 
4679  template<class IteratorType, typename std::enable_if<
4680  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4681  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4682  = 0>
4683  IteratorType erase(IteratorType first, IteratorType last)
4684  {
4685  // make sure iterator fits the current value
4686  if (this != first.m_object or this != last.m_object)
4687  {
4688  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
4689  }
4690 
4691  IteratorType result = end();
4692 
4693  switch (m_type)
4694  {
4695  case value_t::boolean:
4696  case value_t::number_float:
4699  case value_t::string:
4700  {
4701  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4702  {
4703  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
4704  }
4705 
4706  if (is_string())
4707  {
4708  AllocatorType<string_t> alloc;
4709  alloc.destroy(m_value.string);
4710  alloc.deallocate(m_value.string, 1);
4711  m_value.string = nullptr;
4712  }
4713 
4714  m_type = value_t::null;
4715  assert_invariant();
4716  break;
4717  }
4718 
4719  case value_t::object:
4720  {
4721  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4722  last.m_it.object_iterator);
4723  break;
4724  }
4725 
4726  case value_t::array:
4727  {
4728  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4729  last.m_it.array_iterator);
4730  break;
4731  }
4732 
4733  default:
4734  {
4735  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4736  }
4737  }
4738 
4739  return result;
4740  }
4741 
4771  size_type erase(const typename object_t::key_type& key)
4772  {
4773  // this erase only works for objects
4774  if (is_object())
4775  {
4776  return m_value.object->erase(key);
4777  }
4778 
4779  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4780  }
4781 
4806  void erase(const size_type idx)
4807  {
4808  // this erase only works for arrays
4809  if (is_array())
4810  {
4811  if (idx >= size())
4812  {
4813  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
4814  }
4815 
4816  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4817  }
4818  else
4819  {
4820  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4821  }
4822  }
4823 
4825 
4826 
4828  // lookup //
4830 
4833 
4856  iterator find(typename object_t::key_type key)
4857  {
4858  auto result = end();
4859 
4860  if (is_object())
4861  {
4862  result.m_it.object_iterator = m_value.object->find(key);
4863  }
4864 
4865  return result;
4866  }
4867 
4872  const_iterator find(typename object_t::key_type key) const
4873  {
4874  auto result = cend();
4875 
4876  if (is_object())
4877  {
4878  result.m_it.object_iterator = m_value.object->find(key);
4879  }
4880 
4881  return result;
4882  }
4883 
4905  size_type count(typename object_t::key_type key) const
4906  {
4907  // return 0 for all nonobject types
4908  return is_object() ? m_value.object->count(key) : 0;
4909  }
4910 
4912 
4913 
4915  // iterators //
4917 
4920 
4945  iterator begin() noexcept
4946  {
4947  iterator result(this);
4948  result.set_begin();
4949  return result;
4950  }
4951 
4955  const_iterator begin() const noexcept
4956  {
4957  return cbegin();
4958  }
4959 
4985  const_iterator cbegin() const noexcept
4986  {
4987  const_iterator result(this);
4988  result.set_begin();
4989  return result;
4990  }
4991 
5016  iterator end() noexcept
5017  {
5018  iterator result(this);
5019  result.set_end();
5020  return result;
5021  }
5022 
5026  const_iterator end() const noexcept
5027  {
5028  return cend();
5029  }
5030 
5056  const_iterator cend() const noexcept
5057  {
5058  const_iterator result(this);
5059  result.set_end();
5060  return result;
5061  }
5062 
5087  {
5088  return reverse_iterator(end());
5089  }
5090 
5095  {
5096  return crbegin();
5097  }
5098 
5124  {
5125  return reverse_iterator(begin());
5126  }
5127 
5131  const_reverse_iterator rend() const noexcept
5132  {
5133  return crend();
5134  }
5135 
5161  {
5162  return const_reverse_iterator(cend());
5163  }
5164 
5190  {
5191  return const_reverse_iterator(cbegin());
5192  }
5193 
5194  private:
5195  // forward declaration
5196  template<typename IteratorType> class iteration_proxy;
5197 
5198  public:
5213  {
5214  return iteration_proxy<iterator>(cont);
5215  }
5216 
5221  {
5222  return iteration_proxy<const_iterator>(cont);
5223  }
5224 
5226 
5227 
5229  // capacity //
5231 
5234 
5272  bool empty() const noexcept
5273  {
5274  switch (m_type)
5275  {
5276  case value_t::null:
5277  {
5278  // null values are empty
5279  return true;
5280  }
5281 
5282  case value_t::array:
5283  {
5284  // delegate call to array_t::empty()
5285  return m_value.array->empty();
5286  }
5287 
5288  case value_t::object:
5289  {
5290  // delegate call to object_t::empty()
5291  return m_value.object->empty();
5292  }
5293 
5294  default:
5295  {
5296  // all other types are nonempty
5297  return false;
5298  }
5299  }
5300  }
5301 
5340  size_type size() const noexcept
5341  {
5342  switch (m_type)
5343  {
5344  case value_t::null:
5345  {
5346  // null values are empty
5347  return 0;
5348  }
5349 
5350  case value_t::array:
5351  {
5352  // delegate call to array_t::size()
5353  return m_value.array->size();
5354  }
5355 
5356  case value_t::object:
5357  {
5358  // delegate call to object_t::size()
5359  return m_value.object->size();
5360  }
5361 
5362  default:
5363  {
5364  // all other types have size 1
5365  return 1;
5366  }
5367  }
5368  }
5369 
5406  size_type max_size() const noexcept
5407  {
5408  switch (m_type)
5409  {
5410  case value_t::array:
5411  {
5412  // delegate call to array_t::max_size()
5413  return m_value.array->max_size();
5414  }
5415 
5416  case value_t::object:
5417  {
5418  // delegate call to object_t::max_size()
5419  return m_value.object->max_size();
5420  }
5421 
5422  default:
5423  {
5424  // all other types have max_size() == size()
5425  return size();
5426  }
5427  }
5428  }
5429 
5431 
5432 
5434  // modifiers //
5436 
5439 
5462  void clear() noexcept
5463  {
5464  switch (m_type)
5465  {
5467  {
5468  m_value.number_integer = 0;
5469  break;
5470  }
5471 
5473  {
5475  break;
5476  }
5477 
5478  case value_t::number_float:
5479  {
5480  m_value.number_float = 0.0;
5481  break;
5482  }
5483 
5484  case value_t::boolean:
5485  {
5486  m_value.boolean = false;
5487  break;
5488  }
5489 
5490  case value_t::string:
5491  {
5492  m_value.string->clear();
5493  break;
5494  }
5495 
5496  case value_t::array:
5497  {
5498  m_value.array->clear();
5499  break;
5500  }
5501 
5502  case value_t::object:
5503  {
5504  m_value.object->clear();
5505  break;
5506  }
5507 
5508  default:
5509  {
5510  break;
5511  }
5512  }
5513  }
5514 
5535  void push_back(basic_json&& val)
5536  {
5537  // push_back only works for null objects or arrays
5538  if (not(is_null() or is_array()))
5539  {
5540  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5541  }
5542 
5543  // transform null object into an array
5544  if (is_null())
5545  {
5548  assert_invariant();
5549  }
5550 
5551  // add element to array (move semantics)
5552  m_value.array->push_back(std::move(val));
5553  // invalidate object
5554  val.m_type = value_t::null;
5555  }
5556 
5562  {
5563  push_back(std::move(val));
5564  return *this;
5565  }
5566 
5571  void push_back(const basic_json& val)
5572  {
5573  // push_back only works for null objects or arrays
5574  if (not(is_null() or is_array()))
5575  {
5576  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5577  }
5578 
5579  // transform null object into an array
5580  if (is_null())
5581  {
5584  assert_invariant();
5585  }
5586 
5587  // add element to array
5588  m_value.array->push_back(val);
5589  }
5590 
5596  {
5597  push_back(val);
5598  return *this;
5599  }
5600 
5621  void push_back(const typename object_t::value_type& val)
5622  {
5623  // push_back only works for null objects or objects
5624  if (not(is_null() or is_object()))
5625  {
5626  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5627  }
5628 
5629  // transform null object into an object
5630  if (is_null())
5631  {
5634  assert_invariant();
5635  }
5636 
5637  // add element to array
5638  m_value.object->insert(val);
5639  }
5640 
5645  reference operator+=(const typename object_t::value_type& val)
5646  {
5647  push_back(val);
5648  return *this;
5649  }
5650 
5676  void push_back(std::initializer_list<basic_json> init)
5677  {
5678  if (is_object() and init.size() == 2 and init.begin()->is_string())
5679  {
5680  const string_t key = *init.begin();
5681  push_back(typename object_t::value_type(key, *(init.begin() + 1)));
5682  }
5683  else
5684  {
5685  push_back(basic_json(init));
5686  }
5687  }
5688 
5693  reference operator+=(std::initializer_list<basic_json> init)
5694  {
5695  push_back(init);
5696  return *this;
5697  }
5698 
5720  template<class... Args>
5721  void emplace_back(Args&& ... args)
5722  {
5723  // emplace_back only works for null objects or arrays
5724  if (not(is_null() or is_array()))
5725  {
5726  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + type_name()));
5727  }
5728 
5729  // transform null object into an array
5730  if (is_null())
5731  {
5734  assert_invariant();
5735  }
5736 
5737  // add element to array (perfect forwarding)
5738  m_value.array->emplace_back(std::forward<Args>(args)...);
5739  }
5740 
5768  template<class... Args>
5769  std::pair<iterator, bool> emplace(Args&& ... args)
5770  {
5771  // emplace only works for null objects or arrays
5772  if (not(is_null() or is_object()))
5773  {
5774  JSON_THROW(type_error::create(311, "cannot use emplace() with " + type_name()));
5775  }
5776 
5777  // transform null object into an object
5778  if (is_null())
5779  {
5782  assert_invariant();
5783  }
5784 
5785  // add element to array (perfect forwarding)
5786  auto res = m_value.object->emplace(std::forward<Args>(args)...);
5787  // create result iterator and set iterator to the result of emplace
5788  auto it = begin();
5789  it.m_it.object_iterator = res.first;
5790 
5791  // return pair of iterator and boolean
5792  return {it, res.second};
5793  }
5794 
5818  {
5819  // insert only works for arrays
5820  if (is_array())
5821  {
5822  // check if iterator pos fits to this JSON value
5823  if (pos.m_object != this)
5824  {
5825  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5826  }
5827 
5828  // insert to array and return iterator
5829  iterator result(this);
5830  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5831  return result;
5832  }
5833 
5834  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5835  }
5836 
5842  {
5843  return insert(pos, val);
5844  }
5845 
5871  {
5872  // insert only works for arrays
5873  if (is_array())
5874  {
5875  // check if iterator pos fits to this JSON value
5876  if (pos.m_object != this)
5877  {
5878  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5879  }
5880 
5881  // insert to array and return iterator
5882  iterator result(this);
5883  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5884  return result;
5885  }
5886 
5887  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5888  }
5889 
5921  {
5922  // insert only works for arrays
5923  if (not is_array())
5924  {
5925  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5926  }
5927 
5928  // check if iterator pos fits to this JSON value
5929  if (pos.m_object != this)
5930  {
5931  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5932  }
5933 
5934  // check if range iterators belong to the same JSON object
5935  if (first.m_object != last.m_object)
5936  {
5937  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
5938  }
5939 
5940  if (first.m_object == this or last.m_object == this)
5941  {
5942  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
5943  }
5944 
5945  // insert to array and return iterator
5946  iterator result(this);
5947  result.m_it.array_iterator = m_value.array->insert(
5948  pos.m_it.array_iterator,
5949  first.m_it.array_iterator,
5950  last.m_it.array_iterator);
5951  return result;
5952  }
5953 
5978  iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
5979  {
5980  // insert only works for arrays
5981  if (not is_array())
5982  {
5983  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5984  }
5985 
5986  // check if iterator pos fits to this JSON value
5987  if (pos.m_object != this)
5988  {
5989  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5990  }
5991 
5992  // insert to array and return iterator
5993  iterator result(this);
5994  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5995  return result;
5996  }
5997 
6022  {
6023  // insert only works for objects
6024  if (not is_object())
6025  {
6026  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
6027  }
6028 
6029  // check if range iterators belong to the same JSON object
6030  if (first.m_object != last.m_object)
6031  {
6032  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
6033  }
6034 
6035  // passed iterators must belong to objects
6036  if (not first.m_object->is_object() or not first.m_object->is_object())
6037  {
6038  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
6039  }
6040 
6041  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
6042  }
6043 
6061  void swap(reference other) noexcept (
6062  std::is_nothrow_move_constructible<value_t>::value and
6063  std::is_nothrow_move_assignable<value_t>::value and
6064  std::is_nothrow_move_constructible<json_value>::value and
6065  std::is_nothrow_move_assignable<json_value>::value
6066  )
6067  {
6068  std::swap(m_type, other.m_type);
6069  std::swap(m_value, other.m_value);
6070  assert_invariant();
6071  }
6072 
6093  void swap(array_t& other)
6094  {
6095  // swap only works for arrays
6096  if (is_array())
6097  {
6098  std::swap(*(m_value.array), other);
6099  }
6100  else
6101  {
6102  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6103  }
6104  }
6105 
6126  void swap(object_t& other)
6127  {
6128  // swap only works for objects
6129  if (is_object())
6130  {
6131  std::swap(*(m_value.object), other);
6132  }
6133  else
6134  {
6135  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6136  }
6137  }
6138 
6159  void swap(string_t& other)
6160  {
6161  // swap only works for strings
6162  if (is_string())
6163  {
6164  std::swap(*(m_value.string), other);
6165  }
6166  else
6167  {
6168  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6169  }
6170  }
6171 
6173 
6174  public:
6176  // lexicographical comparison operators //
6178 
6181 
6209  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
6210  {
6211  const auto lhs_type = lhs.type();
6212  const auto rhs_type = rhs.type();
6213 
6214  if (lhs_type == rhs_type)
6215  {
6216  switch (lhs_type)
6217  {
6218  case value_t::array:
6219  {
6220  return *lhs.m_value.array == *rhs.m_value.array;
6221  }
6222  case value_t::object:
6223  {
6224  return *lhs.m_value.object == *rhs.m_value.object;
6225  }
6226  case value_t::null:
6227  {
6228  return true;
6229  }
6230  case value_t::string:
6231  {
6232  return *lhs.m_value.string == *rhs.m_value.string;
6233  }
6234  case value_t::boolean:
6235  {
6236  return lhs.m_value.boolean == rhs.m_value.boolean;
6237  }
6239  {
6240  return lhs.m_value.number_integer == rhs.m_value.number_integer;
6241  }
6243  {
6244  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
6245  }
6246  case value_t::number_float:
6247  {
6248  return lhs.m_value.number_float == rhs.m_value.number_float;
6249  }
6250  default:
6251  {
6252  return false;
6253  }
6254  }
6255  }
6256  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6257  {
6258  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
6259  }
6260  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6261  {
6262  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
6263  }
6264  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6265  {
6266  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
6267  }
6268  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6269  {
6270  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
6271  }
6272  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6273  {
6274  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
6275  }
6276  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6277  {
6278  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6279  }
6280 
6281  return false;
6282  }
6283 
6288  template<typename ScalarType, typename std::enable_if<
6289  std::is_scalar<ScalarType>::value, int>::type = 0>
6290  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
6291  {
6292  return (lhs == basic_json(rhs));
6293  }
6294 
6299  template<typename ScalarType, typename std::enable_if<
6300  std::is_scalar<ScalarType>::value, int>::type = 0>
6301  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
6302  {
6303  return (basic_json(lhs) == rhs);
6304  }
6305 
6322  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
6323  {
6324  return not (lhs == rhs);
6325  }
6326 
6331  template<typename ScalarType, typename std::enable_if<
6332  std::is_scalar<ScalarType>::value, int>::type = 0>
6333  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
6334  {
6335  return (lhs != basic_json(rhs));
6336  }
6337 
6342  template<typename ScalarType, typename std::enable_if<
6343  std::is_scalar<ScalarType>::value, int>::type = 0>
6344  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
6345  {
6346  return (basic_json(lhs) != rhs);
6347  }
6348 
6373  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6374  {
6375  const auto lhs_type = lhs.type();
6376  const auto rhs_type = rhs.type();
6377 
6378  if (lhs_type == rhs_type)
6379  {
6380  switch (lhs_type)
6381  {
6382  case value_t::array:
6383  {
6384  //return *lhs.m_value.array < *rhs.m_value.array;
6385  //return *lhs.m_value.array.operator<(rhs);
6386  return (*lhs.m_value.array) < *rhs.m_value.array;
6387  // return nlohmann::detail::operator<(lhs, rhs);
6388  }
6389  case value_t::object:
6390  {
6391  return *lhs.m_value.object < *rhs.m_value.object;
6392  }
6393  case value_t::null:
6394  {
6395  return false;
6396  }
6397  case value_t::string:
6398  {
6399  return *lhs.m_value.string < *rhs.m_value.string;
6400  }
6401  case value_t::boolean:
6402  {
6403  return lhs.m_value.boolean < rhs.m_value.boolean;
6404  }
6406  {
6407  return lhs.m_value.number_integer < rhs.m_value.number_integer;
6408  }
6410  {
6411  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6412  }
6413  case value_t::number_float:
6414  {
6415  return lhs.m_value.number_float < rhs.m_value.number_float;
6416  }
6417  default:
6418  {
6419  return false;
6420  }
6421  }
6422  }
6423  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6424  {
6425  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6426  }
6427  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6428  {
6429  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6430  }
6431  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6432  {
6433  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6434  }
6435  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6436  {
6437  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6438  }
6439  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6440  {
6441  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6442  }
6443  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6444  {
6445  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6446  }
6447 
6448  // We only reach this line if we cannot compare values. In that case,
6449  // we compare types. Note we have to call the operator explicitly,
6450  // because MSVC has problems otherwise.
6451  return operator<(lhs_type, rhs_type);
6452  }
6453 
6458  template<typename ScalarType, typename std::enable_if<
6459  std::is_scalar<ScalarType>::value, int>::type = 0>
6460  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
6461  {
6462  return (lhs < basic_json(rhs));
6463  }
6464 
6469  template<typename ScalarType, typename std::enable_if<
6470  std::is_scalar<ScalarType>::value, int>::type = 0>
6471  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
6472  {
6473  return (basic_json(lhs) < rhs);
6474  }
6475 
6493  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6494  {
6495  return not (rhs < lhs);
6496  }
6497 
6502  template<typename ScalarType, typename std::enable_if<
6503  std::is_scalar<ScalarType>::value, int>::type = 0>
6504  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
6505  {
6506  return (lhs <= basic_json(rhs));
6507  }
6508 
6513  template<typename ScalarType, typename std::enable_if<
6514  std::is_scalar<ScalarType>::value, int>::type = 0>
6515  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
6516  {
6517  return (basic_json(lhs) <= rhs);
6518  }
6519 
6537  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6538  {
6539  return not (lhs <= rhs);
6540  }
6541 
6546  template<typename ScalarType, typename std::enable_if<
6547  std::is_scalar<ScalarType>::value, int>::type = 0>
6548  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
6549  {
6550  return (lhs > basic_json(rhs));
6551  }
6552 
6557  template<typename ScalarType, typename std::enable_if<
6558  std::is_scalar<ScalarType>::value, int>::type = 0>
6559  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
6560  {
6561  return (basic_json(lhs) > rhs);
6562  }
6563 
6581  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6582  {
6583  return not (lhs < rhs);
6584  }
6585 
6590  template<typename ScalarType, typename std::enable_if<
6591  std::is_scalar<ScalarType>::value, int>::type = 0>
6592  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
6593  {
6594  return (lhs >= basic_json(rhs));
6595  }
6596 
6601  template<typename ScalarType, typename std::enable_if<
6602  std::is_scalar<ScalarType>::value, int>::type = 0>
6603  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
6604  {
6605  return (basic_json(lhs) >= rhs);
6606  }
6607 
6609 
6610  private:
6612  // output adapters //
6614 
6616  template<typename CharType>
6618  {
6619  public:
6620  virtual void write_character(CharType c) = 0;
6621  virtual void write_characters(const CharType* s, size_t length) = 0;
6622  virtual ~output_adapter() {}
6623 
6624  static std::shared_ptr<output_adapter<CharType>> create(std::vector<CharType>& vec)
6625  {
6626  return std::shared_ptr<output_adapter>(new output_vector_adapter<CharType>(vec));
6627  }
6628 
6629  static std::shared_ptr<output_adapter<CharType>> create(std::ostream& s)
6630  {
6631  return std::shared_ptr<output_adapter>(new output_stream_adapter<CharType>(s));
6632  }
6633 
6634  static std::shared_ptr<output_adapter<CharType>> create(std::string& s)
6635  {
6636  return std::shared_ptr<output_adapter>(new output_string_adapter<CharType>(s));
6637  }
6638  };
6639 
6641  template<typename CharType>
6642  using output_adapter_t = std::shared_ptr<output_adapter<CharType>>;
6643 
6645  template<typename CharType>
6646  class output_vector_adapter : public output_adapter<CharType>
6647  {
6648  public:
6649  output_vector_adapter(std::vector<CharType>& vec)
6650  : v(vec)
6651  {}
6652 
6653  void write_character(CharType c) override
6654  {
6655  v.push_back(c);
6656  }
6657 
6658  void write_characters(const CharType* s, size_t length) override
6659  {
6660  std::copy(s, s + length, std::back_inserter(v));
6661  }
6662 
6663  private:
6664  std::vector<CharType>& v;
6665  };
6666 
6668  template<typename CharType>
6669  class output_stream_adapter : public output_adapter<CharType>
6670  {
6671  public:
6672  output_stream_adapter(std::basic_ostream<CharType>& s)
6673  : stream(s)
6674  {}
6675 
6676  void write_character(CharType c) override
6677  {
6678  stream.put(c);
6679  }
6680 
6681  void write_characters(const CharType* s, size_t length) override
6682  {
6683  stream.write(s, static_cast<std::streamsize>(length));
6684  }
6685 
6686  private:
6687  std::basic_ostream<CharType>& stream;
6688  };
6689 
6691  template<typename CharType>
6692  class output_string_adapter : public output_adapter<CharType>
6693  {
6694  public:
6695  output_string_adapter(std::string& s)
6696  : str(s)
6697  {}
6698 
6699  void write_character(CharType c) override
6700  {
6701  str.push_back(c);
6702  }
6703 
6704  void write_characters(const CharType* s, size_t length) override
6705  {
6706  str.append(s, length);
6707  }
6708 
6709  private:
6710  std::basic_string<CharType>& str;
6711  };
6712 
6713 
6715  // serialization //
6717 
6720 
6721  private:
6726  {
6727  private:
6728  serializer(const serializer&) = delete;
6729  serializer& operator=(const serializer&) = delete;
6730 
6731  public:
6737  : o(s), loc(std::localeconv()),
6740  indent_char(ichar), indent_string(512, indent_char)
6741  {}
6742 
6760  void dump(const basic_json& val,
6761  const bool pretty_print,
6762  const unsigned int indent_step,
6763  const unsigned int current_indent = 0)
6764  {
6765  switch (val.m_type)
6766  {
6767  case value_t::object:
6768  {
6769  if (val.m_value.object->empty())
6770  {
6771  o->write_characters("{}", 2);
6772  return;
6773  }
6774 
6775  if (pretty_print)
6776  {
6777  o->write_characters("{\n", 2);
6778 
6779  // variable to hold indentation for recursive calls
6780  const auto new_indent = current_indent + indent_step;
6781  if (indent_string.size() < new_indent)
6782  {
6783  indent_string.resize(new_indent, ' ');
6784  }
6785 
6786  // first n-1 elements
6787  auto i = val.m_value.object->cbegin();
6788  for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6789  {
6790  o->write_characters(indent_string.c_str(), new_indent);
6791  o->write_character('\"');
6792  dump_escaped(i->first);
6793  o->write_characters("\": ", 3);
6794  dump(i->second, true, indent_step, new_indent);
6795  o->write_characters(",\n", 2);
6796  }
6797 
6798  // last element
6799  assert(i != val.m_value.object->cend());
6800  o->write_characters(indent_string.c_str(), new_indent);
6801  o->write_character('\"');
6802  dump_escaped(i->first);
6803  o->write_characters("\": ", 3);
6804  dump(i->second, true, indent_step, new_indent);
6805 
6806  o->write_character('\n');
6807  o->write_characters(indent_string.c_str(), current_indent);
6808  o->write_character('}');
6809  }
6810  else
6811  {
6812  o->write_character('{');
6813 
6814  // first n-1 elements
6815  auto i = val.m_value.object->cbegin();
6816  for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6817  {
6818  o->write_character('\"');
6819  dump_escaped(i->first);
6820  o->write_characters("\":", 2);
6821  dump(i->second, false, indent_step, current_indent);
6822  o->write_character(',');
6823  }
6824 
6825  // last element
6826  assert(i != val.m_value.object->cend());
6827  o->write_character('\"');
6828  dump_escaped(i->first);
6829  o->write_characters("\":", 2);
6830  dump(i->second, false, indent_step, current_indent);
6831 
6832  o->write_character('}');
6833  }
6834 
6835  return;
6836  }
6837 
6838  case value_t::array:
6839  {
6840  if (val.m_value.array->empty())
6841  {
6842  o->write_characters("[]", 2);
6843  return;
6844  }
6845 
6846  if (pretty_print)
6847  {
6848  o->write_characters("[\n", 2);
6849 
6850  // variable to hold indentation for recursive calls
6851  const auto new_indent = current_indent + indent_step;
6852  if (indent_string.size() < new_indent)
6853  {
6854  indent_string.resize(new_indent, ' ');
6855  }
6856 
6857  // first n-1 elements
6858  for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6859  {
6860  o->write_characters(indent_string.c_str(), new_indent);
6861  dump(*i, true, indent_step, new_indent);
6862  o->write_characters(",\n", 2);
6863  }
6864 
6865  // last element
6866  assert(not val.m_value.array->empty());
6867  o->write_characters(indent_string.c_str(), new_indent);
6868  dump(val.m_value.array->back(), true, indent_step, new_indent);
6869 
6870  o->write_character('\n');
6871  o->write_characters(indent_string.c_str(), current_indent);
6872  o->write_character(']');
6873  }
6874  else
6875  {
6876  o->write_character('[');
6877 
6878  // first n-1 elements
6879  for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6880  {
6881  dump(*i, false, indent_step, current_indent);
6882  o->write_character(',');
6883  }
6884 
6885  // last element
6886  assert(not val.m_value.array->empty());
6887  dump(val.m_value.array->back(), false, indent_step, current_indent);
6888 
6889  o->write_character(']');
6890  }
6891 
6892  return;
6893  }
6894 
6895  case value_t::string:
6896  {
6897  o->write_character('\"');
6898  dump_escaped(*val.m_value.string);
6899  o->write_character('\"');
6900  return;
6901  }
6902 
6903  case value_t::boolean:
6904  {
6905  if (val.m_value.boolean)
6906  {
6907  o->write_characters("true", 4);
6908  }
6909  else
6910  {
6911  o->write_characters("false", 5);
6912  }
6913  return;
6914  }
6915 
6917  {
6919  return;
6920  }
6921 
6923  {
6925  return;
6926  }
6927 
6928  case value_t::number_float:
6929  {
6931  return;
6932  }
6933 
6934  case value_t::discarded:
6935  {
6936  o->write_characters("<discarded>", 11);
6937  return;
6938  }
6939 
6940  case value_t::null:
6941  {
6942  o->write_characters("null", 4);
6943  return;
6944  }
6945  }
6946  }
6947 
6948  private:
6957  static std::size_t extra_space(const string_t& s) noexcept
6958  {
6959  return std::accumulate(s.begin(), s.end(), size_t{},
6960  [](size_t res, typename string_t::value_type c)
6961  {
6962  switch (c)
6963  {
6964  case '"':
6965  case '\\':
6966  case '\b':
6967  case '\f':
6968  case '\n':
6969  case '\r':
6970  case '\t':
6971  {
6972  // from c (1 byte) to \x (2 bytes)
6973  return res + 1;
6974  }
6975 
6976  case 0x00:
6977  case 0x01:
6978  case 0x02:
6979  case 0x03:
6980  case 0x04:
6981  case 0x05:
6982  case 0x06:
6983  case 0x07:
6984  case 0x0b:
6985  case 0x0e:
6986  case 0x0f:
6987  case 0x10:
6988  case 0x11:
6989  case 0x12:
6990  case 0x13:
6991  case 0x14:
6992  case 0x15:
6993  case 0x16:
6994  case 0x17:
6995  case 0x18:
6996  case 0x19:
6997  case 0x1a:
6998  case 0x1b:
6999  case 0x1c:
7000  case 0x1d:
7001  case 0x1e:
7002  case 0x1f:
7003  {
7004  // from c (1 byte) to \uxxxx (6 bytes)
7005  return res + 5;
7006  }
7007 
7008  default:
7009  {
7010  return res;
7011  }
7012  }
7013  });
7014  }
7015 
7028  void dump_escaped(const string_t& s) const
7029  {
7030  const auto space = extra_space(s);
7031  if (space == 0)
7032  {
7033  o->write_characters(s.c_str(), s.size());
7034  return;
7035  }
7036 
7037  // create a result string of necessary size
7038  string_t result(s.size() + space, '\\');
7039  std::size_t pos = 0;
7040 
7041  for (const auto& c : s)
7042  {
7043  switch (c)
7044  {
7045  // quotation mark (0x22)
7046  case '"':
7047  {
7048  result[pos + 1] = '"';
7049  pos += 2;
7050  break;
7051  }
7052 
7053  // reverse solidus (0x5c)
7054  case '\\':
7055  {
7056  // nothing to change
7057  pos += 2;
7058  break;
7059  }
7060 
7061  // backspace (0x08)
7062  case '\b':
7063  {
7064  result[pos + 1] = 'b';
7065  pos += 2;
7066  break;
7067  }
7068 
7069  // formfeed (0x0c)
7070  case '\f':
7071  {
7072  result[pos + 1] = 'f';
7073  pos += 2;
7074  break;
7075  }
7076 
7077  // newline (0x0a)
7078  case '\n':
7079  {
7080  result[pos + 1] = 'n';
7081  pos += 2;
7082  break;
7083  }
7084 
7085  // carriage return (0x0d)
7086  case '\r':
7087  {
7088  result[pos + 1] = 'r';
7089  pos += 2;
7090  break;
7091  }
7092 
7093  // horizontal tab (0x09)
7094  case '\t':
7095  {
7096  result[pos + 1] = 't';
7097  pos += 2;
7098  break;
7099  }
7100 
7101  case 0x00:
7102  case 0x01:
7103  case 0x02:
7104  case 0x03:
7105  case 0x04:
7106  case 0x05:
7107  case 0x06:
7108  case 0x07:
7109  case 0x0b:
7110  case 0x0e:
7111  case 0x0f:
7112  case 0x10:
7113  case 0x11:
7114  case 0x12:
7115  case 0x13:
7116  case 0x14:
7117  case 0x15:
7118  case 0x16:
7119  case 0x17:
7120  case 0x18:
7121  case 0x19:
7122  case 0x1a:
7123  case 0x1b:
7124  case 0x1c:
7125  case 0x1d:
7126  case 0x1e:
7127  case 0x1f:
7128  {
7129  // convert a number 0..15 to its hex representation
7130  // (0..f)
7131  static const char hexify[16] =
7132  {
7133  '0', '1', '2', '3', '4', '5', '6', '7',
7134  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
7135  };
7136 
7137  // print character c as \uxxxx
7138  for (const char m :
7139  { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
7140  })
7141  {
7142  result[++pos] = m;
7143  }
7144 
7145  ++pos;
7146  break;
7147  }
7148 
7149  default:
7150  {
7151  // all other characters are added as-is
7152  result[pos++] = c;
7153  break;
7154  }
7155  }
7156  }
7157 
7158  assert(pos == s.size() + space);
7159  o->write_characters(result.c_str(), result.size());
7160  }
7161 
7171  template<typename NumberType, detail::enable_if_t <
7172  std::is_same<NumberType, number_unsigned_t>::value or
7173  std::is_same<NumberType, number_integer_t>::value, int> = 0>
7174  void dump_integer(NumberType x)
7175  {
7176  // special case for "0"
7177  if (x == 0)
7178  {
7179  o->write_character('0');
7180  return;
7181  }
7182 
7183  const bool is_negative = x < 0;
7184  size_t i = 0;
7185 
7186  // spare 1 byte for '\0'
7187  while (x != 0 and i < number_buffer.size() - 1)
7188  {
7189  const auto digit = std::labs(static_cast<long>(x % 10));
7190  number_buffer[i++] = static_cast<char>('0' + digit);
7191  x /= 10;
7192  }
7193 
7194  // make sure the number has been processed completely
7195  assert(x == 0);
7196 
7197  if (is_negative)
7198  {
7199  // make sure there is capacity for the '-'
7200  assert(i < number_buffer.size() - 2);
7201  number_buffer[i++] = '-';
7202  }
7203 
7204  std::reverse(number_buffer.begin(), number_buffer.begin() + i);
7205  o->write_characters(number_buffer.data(), i);
7206  }
7207 
7217  {
7218  // NaN / inf
7219  if (not std::isfinite(x) or std::isnan(x))
7220  {
7221  o->write_characters("null", 4);
7222  return;
7223  }
7224 
7225  // special case for 0.0 and -0.0
7226  if (x == 0)
7227  {
7228  if (std::signbit(x))
7229  {
7230  o->write_characters("-0.0", 4);
7231  }
7232  else
7233  {
7234  o->write_characters("0.0", 3);
7235  }
7236  return;
7237  }
7238 
7239  // get number of digits for a text -> float -> text round-trip
7240  static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
7241 
7242  // the actual conversion
7243  std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
7244  "%.*g", d, x);
7245 
7246  // negative value indicates an error
7247  assert(len > 0);
7248  // check if buffer was large enough
7249  assert(static_cast<size_t>(len) < number_buffer.size());
7250 
7251  // erase thousands separator
7252  if (thousands_sep != '\0')
7253  {
7254  const auto end = std::remove(number_buffer.begin(),
7255  number_buffer.begin() + len,
7256  thousands_sep);
7257  std::fill(end, number_buffer.end(), '\0');
7258  assert((end - number_buffer.begin()) <= len);
7259  len = (end - number_buffer.begin());
7260  }
7261 
7262  // convert decimal point to '.'
7263  if (decimal_point != '\0' and decimal_point != '.')
7264  {
7265  for (auto& c : number_buffer)
7266  {
7267  if (c == decimal_point)
7268  {
7269  c = '.';
7270  break;
7271  }
7272  }
7273  }
7274 
7275  o->write_characters(number_buffer.data(), static_cast<size_t>(len));
7276 
7277  // determine if need to append ".0"
7278  const bool value_is_int_like = std::none_of(number_buffer.begin(),
7279  number_buffer.begin() + len + 1,
7280  [](char c)
7281  {
7282  return c == '.' or c == 'e';
7283  });
7284 
7285  if (value_is_int_like)
7286  {
7287  o->write_characters(".0", 2);
7288  }
7289  }
7290 
7291  private:
7294 
7296  std::array<char, 64> number_buffer{{}};
7297 
7299  const std::lconv* loc = nullptr;
7301  const char thousands_sep = '\0';
7303  const char decimal_point = '\0';
7304 
7306  const char indent_char;
7307 
7310  };
7311 
7312  public:
7341  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
7342  {
7343  // read width member and use it as indentation parameter if nonzero
7344  const bool pretty_print = (o.width() > 0);
7345  const auto indentation = (pretty_print ? o.width() : 0);
7346 
7347  // reset width to 0 for subsequent calls to this stream
7348  o.width(0);
7349 
7350  // do the actual serialization
7352  s.dump(j, pretty_print, static_cast<unsigned int>(indentation));
7353  return o;
7354  }
7355 
7364  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
7365  {
7366  return o << j;
7367  }
7368 
7370 
7371 
7373  // deserialization //
7375 
7378 
7411  template<class T, std::size_t N>
7412  static basic_json parse(T (&array)[N],
7413  const parser_callback_t cb = nullptr)
7414  {
7415  // delegate the call to the iterator-range parse overload
7416  return parse(std::begin(array), std::end(array), cb);
7417  }
7418 
7450  template<typename CharT, typename std::enable_if<
7451  std::is_pointer<CharT>::value and
7453  sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
7454  static basic_json parse(const CharT s,
7455  const parser_callback_t cb = nullptr)
7456  {
7457  return parser(input_adapter::create(s), cb).parse(true);
7458  }
7459 
7489  static basic_json parse(std::istream& i,
7490  const parser_callback_t cb = nullptr)
7491  {
7492  return parser(input_adapter::create(i), cb).parse(true);
7493  }
7494 
7498  static basic_json parse(std::istream&& i,
7499  const parser_callback_t cb = nullptr)
7500  {
7501  return parser(input_adapter::create(i), cb).parse(true);
7502  }
7503 
7549  template<class IteratorType, typename std::enable_if<
7550  std::is_base_of<
7551  std::random_access_iterator_tag,
7552  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
7553  static basic_json parse(IteratorType first, IteratorType last,
7554  const parser_callback_t cb = nullptr)
7555  {
7556  return parser(input_adapter::create(first, last), cb).parse(true);
7557  }
7558 
7603  template<class ContiguousContainer, typename std::enable_if<
7604  not std::is_pointer<ContiguousContainer>::value and
7605  std::is_base_of<
7606  std::random_access_iterator_tag,
7607  typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
7608  , int>::type = 0>
7609  static basic_json parse(const ContiguousContainer& c,
7610  const parser_callback_t cb = nullptr)
7611  {
7612  // delegate the call to the iterator-range parse overload
7613  return parse(std::begin(c), std::end(c), cb);
7614  }
7615 
7624  friend std::istream& operator<<(basic_json& j, std::istream& i)
7625  {
7626  j = parser(input_adapter::create(i)).parse(false);
7627  return i;
7628  }
7629 
7656  friend std::istream& operator>>(std::istream& i, basic_json& j)
7657  {
7658  j = parser(input_adapter::create(i)).parse(false);
7659  return i;
7660  }
7661 
7663 
7665  // convenience functions //
7667 
7683  std::string type_name() const
7684  {
7685  {
7686  switch (m_type)
7687  {
7688  case value_t::null:
7689  return "null";
7690  case value_t::object:
7691  return "object";
7692  case value_t::array:
7693  return "array";
7694  case value_t::string:
7695  return "string";
7696  case value_t::boolean:
7697  return "boolean";
7698  case value_t::discarded:
7699  return "discarded";
7700  default:
7701  return "number";
7702  }
7703  }
7704  }
7705 
7706 
7707  private:
7709  // member variables //
7711 
7713  value_t m_type = value_t::null;
7714 
7717 
7718 
7719  private:
7721  // iterators //
7723 
7734  {
7735  public:
7736 
7737  difference_type get_value() const noexcept
7738  {
7739  return m_it;
7740  }
7742  void set_begin() noexcept
7743  {
7744  m_it = begin_value;
7745  }
7746 
7748  void set_end() noexcept
7749  {
7750  m_it = end_value;
7751  }
7752 
7754  constexpr bool is_begin() const noexcept
7755  {
7756  return (m_it == begin_value);
7757  }
7758 
7760  constexpr bool is_end() const noexcept
7761  {
7762  return (m_it == end_value);
7763  }
7764 
7765  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7766  {
7767  return lhs.m_it == rhs.m_it;
7768  }
7769 
7770  friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7771  {
7772  return !(lhs == rhs);
7773  }
7774 
7775  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7776  {
7777  return lhs.m_it < rhs.m_it;
7778  }
7779 
7780  friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7781  {
7782  return lhs.m_it <= rhs.m_it;
7783  }
7784 
7785  friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7786  {
7787  return lhs.m_it > rhs.m_it;
7788  }
7789 
7790  friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7791  {
7792  return lhs.m_it >= rhs.m_it;
7793  }
7794 
7796  {
7797  auto result = *this;
7798  result += i;
7799  return result;
7800  }
7801 
7803  {
7804  return lhs.m_it - rhs.m_it;
7805  }
7806 
7807  friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
7808  {
7809  return os << it.m_it;
7810  }
7811 
7813  {
7814  ++m_it;
7815  return *this;
7816  }
7817 
7819  {
7820  auto result = *this;
7821  m_it++;
7822  return result;
7823  }
7824 
7826  {
7827  --m_it;
7828  return *this;
7829  }
7830 
7832  {
7833  auto result = *this;
7834  m_it--;
7835  return result;
7836  }
7837 
7839  {
7840  m_it += n;
7841  return *this;
7842  }
7843 
7845  {
7846  m_it -= n;
7847  return *this;
7848  }
7849 
7850  private:
7851  static constexpr difference_type begin_value = 0;
7852  static constexpr difference_type end_value = begin_value + 1;
7853 
7855  difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
7856  };
7857 
7866  {
7868  typename object_t::iterator object_iterator;
7870  typename array_t::iterator array_iterator;
7873 
7876  : object_iterator(), array_iterator(), primitive_iterator()
7877  {}
7878  };
7879 
7881  template<typename IteratorType>
7882  class iteration_proxy
7883  {
7884  private:
7887  {
7888  private:
7890  IteratorType anchor;
7892  size_t array_index = 0;
7893 
7894  public:
7895  explicit iteration_proxy_internal(IteratorType it) noexcept
7896  : anchor(it)
7897  {}
7898 
7901  {
7902  return *this;
7903  }
7904 
7907  {
7908  ++anchor;
7909  ++array_index;
7910 
7911  return *this;
7912  }
7913 
7916  {
7917  return anchor != o.anchor;
7918  }
7919 
7921  typename basic_json::string_t key() const
7922  {
7923  assert(anchor.m_object != nullptr);
7924 
7925  switch (anchor.m_object->type())
7926  {
7927  // use integer array index as key
7928  case value_t::array:
7929  {
7930  return std::to_string(array_index);
7931  }
7932 
7933  // use key from the object
7934  case value_t::object:
7935  {
7936  return anchor.key();
7937  }
7938 
7939  // use an empty key for all primitive types
7940  default:
7941  {
7942  return "";
7943  }
7944  }
7945  }
7946 
7948  typename IteratorType::reference value() const
7949  {
7950  return anchor.value();
7951  }
7952  };
7953 
7955  typename IteratorType::reference container;
7956 
7957  public:
7959  explicit iteration_proxy(typename IteratorType::reference cont)
7960  : container(cont)
7961  {}
7962 
7965  {
7966  return iteration_proxy_internal(container.begin());
7967  }
7968 
7971  {
7972  return iteration_proxy_internal(container.end());
7973  }
7974  };
7975 
7976  public:
7996  template<typename U>
7997  class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
7998  {
8000  friend class basic_json;
8001 
8002  // make sure U is basic_json or const basic_json
8003  static_assert(std::is_same<U, basic_json>::value
8004  or std::is_same<U, const basic_json>::value,
8005  "iter_impl only accepts (const) basic_json");
8006 
8007  public:
8013  using pointer = typename std::conditional<std::is_const<U>::value,
8014  typename basic_json::const_pointer,
8017  using reference = typename std::conditional<std::is_const<U>::value,
8018  typename basic_json::const_reference,
8021  using iterator_category = std::bidirectional_iterator_tag;
8022 
8024  iter_impl() = default;
8025 
8032  explicit iter_impl(pointer object) noexcept
8033  : m_object(object)
8034  {
8035  assert(m_object != nullptr);
8036 
8037  switch (m_object->m_type)
8038  {
8040  {
8041  m_it.object_iterator = typename object_t::iterator();
8042  break;
8043  }
8044 
8046  {
8047  m_it.array_iterator = typename array_t::iterator();
8048  break;
8049  }
8050 
8051  default:
8052  {
8053  m_it.primitive_iterator = primitive_iterator_t();
8054  break;
8055  }
8056  }
8057  }
8058 
8059  /*
8060  Use operator `const_iterator` instead of `const_iterator(const iterator&
8061  other) noexcept` to avoid two class definitions for @ref iterator and
8062  @ref const_iterator.
8063 
8064  This function is only called if this class is an @ref iterator. If this
8065  class is a @ref const_iterator this function is not called.
8066  */
8067  operator const_iterator() const
8068  {
8069  const_iterator ret;
8070 
8071  if (m_object)
8072  {
8073  ret.m_object = m_object;
8074  ret.m_it = m_it;
8075  }
8076 
8077  return ret;
8078  }
8079 
8085  iter_impl(const iter_impl& other) noexcept
8086  : m_object(other.m_object), m_it(other.m_it)
8087  {}
8088 
8094  iter_impl& operator=(iter_impl other) noexcept(
8095  std::is_nothrow_move_constructible<pointer>::value and
8096  std::is_nothrow_move_assignable<pointer>::value and
8097  std::is_nothrow_move_constructible<internal_iterator>::value and
8098  std::is_nothrow_move_assignable<internal_iterator>::value
8099  )
8100  {
8101  std::swap(m_object, other.m_object);
8102  std::swap(m_it, other.m_it);
8103  return *this;
8104  }
8105 
8106  private:
8111  void set_begin() noexcept
8112  {
8113  assert(m_object != nullptr);
8114 
8115  switch (m_object->m_type)
8116  {
8118  {
8119  m_it.object_iterator = m_object->m_value.object->begin();
8120  break;
8121  }
8122 
8124  {
8125  m_it.array_iterator = m_object->m_value.array->begin();
8126  break;
8127  }
8128 
8129  case basic_json::value_t::null:
8130  {
8131  // set to end so begin()==end() is true: null is empty
8132  m_it.primitive_iterator.set_end();
8133  break;
8134  }
8135 
8136  default:
8137  {
8138  m_it.primitive_iterator.set_begin();
8139  break;
8140  }
8141  }
8142  }
8143 
8148  void set_end() noexcept
8149  {
8150  assert(m_object != nullptr);
8151 
8152  switch (m_object->m_type)
8153  {
8155  {
8156  m_it.object_iterator = m_object->m_value.object->end();
8157  break;
8158  }
8159 
8161  {
8162  m_it.array_iterator = m_object->m_value.array->end();
8163  break;
8164  }
8165 
8166  default:
8167  {
8168  m_it.primitive_iterator.set_end();
8169  break;
8170  }
8171  }
8172  }
8173 
8174  public:
8180  {
8181  assert(m_object != nullptr);
8182 
8183  switch (m_object->m_type)
8184  {
8186  {
8187  assert(m_it.object_iterator != m_object->m_value.object->end());
8188  return m_it.object_iterator->second;
8189  }
8190 
8192  {
8193  assert(m_it.array_iterator != m_object->m_value.array->end());
8194  return *m_it.array_iterator;
8195  }
8196 
8197  case basic_json::value_t::null:
8198  {
8199  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8200  }
8201 
8202  default:
8203  {
8204  if (m_it.primitive_iterator.is_begin())
8205  {
8206  return *m_object;
8207  }
8208 
8209  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8210  }
8211  }
8212  }
8213 
8219  {
8220  assert(m_object != nullptr);
8221 
8222  switch (m_object->m_type)
8223  {
8225  {
8226  assert(m_it.object_iterator != m_object->m_value.object->end());
8227  return &(m_it.object_iterator->second);
8228  }
8229 
8231  {
8232  assert(m_it.array_iterator != m_object->m_value.array->end());
8233  return &*m_it.array_iterator;
8234  }
8235 
8236  default:
8237  {
8238  if (m_it.primitive_iterator.is_begin())
8239  {
8240  return m_object;
8241  }
8242 
8243  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8244  }
8245  }
8246  }
8247 
8253  {
8254  auto result = *this;
8255  ++(*this);
8256  return result;
8257  }
8258 
8264  {
8265  assert(m_object != nullptr);
8266 
8267  switch (m_object->m_type)
8268  {
8270  {
8271  std::advance(m_it.object_iterator, 1);
8272  break;
8273  }
8274 
8276  {
8277  std::advance(m_it.array_iterator, 1);
8278  break;
8279  }
8280 
8281  default:
8282  {
8283  ++m_it.primitive_iterator;
8284  break;
8285  }
8286  }
8287 
8288  return *this;
8289  }
8290 
8296  {
8297  auto result = *this;
8298  --(*this);
8299  return result;
8300  }
8301 
8307  {
8308  assert(m_object != nullptr);
8309 
8310  switch (m_object->m_type)
8311  {
8313  {
8314  std::advance(m_it.object_iterator, -1);
8315  break;
8316  }
8317 
8319  {
8320  std::advance(m_it.array_iterator, -1);
8321  break;
8322  }
8323 
8324  default:
8325  {
8326  --m_it.primitive_iterator;
8327  break;
8328  }
8329  }
8330 
8331  return *this;
8332  }
8333 
8338  bool operator==(const iter_impl& other) const
8339  {
8340  // if objects are not the same, the comparison is undefined
8341  if (m_object != other.m_object)
8342  {
8343  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8344  }
8345 
8346  assert(m_object != nullptr);
8347 
8348  switch (m_object->m_type)
8349  {
8351  {
8352  return (m_it.object_iterator == other.m_it.object_iterator);
8353  }
8354 
8356  {
8357  return (m_it.array_iterator == other.m_it.array_iterator);
8358  }
8359 
8360  default:
8361  {
8362  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8363  }
8364  }
8365  }
8366 
8371  bool operator!=(const iter_impl& other) const
8372  {
8373  return not operator==(other);
8374  }
8375 
8380  bool operator<(const iter_impl& other) const
8381  {
8382  // if objects are not the same, the comparison is undefined
8383  if (m_object != other.m_object)
8384  {
8385  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8386  }
8387 
8388  assert(m_object != nullptr);
8389 
8390  switch (m_object->m_type)
8391  {
8393  {
8394  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
8395  }
8396 
8398  {
8399  return (m_it.array_iterator < other.m_it.array_iterator);
8400  }
8401 
8402  default:
8403  {
8404  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
8405  }
8406  }
8407  }
8408 
8413  bool operator<=(const iter_impl& other) const
8414  {
8415  return not other.operator < (*this);
8416  }
8417 
8422  bool operator>(const iter_impl& other) const
8423  {
8424  return not operator<=(other);
8425  }
8426 
8431  bool operator>=(const iter_impl& other) const
8432  {
8433  return not operator<(other);
8434  }
8435 
8441  {
8442  assert(m_object != nullptr);
8443 
8444  switch (m_object->m_type)
8445  {
8447  {
8448  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8449  }
8450 
8452  {
8453  std::advance(m_it.array_iterator, i);
8454  break;
8455  }
8456 
8457  default:
8458  {
8459  m_it.primitive_iterator += i;
8460  break;
8461  }
8462  }
8463 
8464  return *this;
8465  }
8466 
8472  {
8473  return operator+=(-i);
8474  }
8475 
8481  {
8482  auto result = *this;
8483  result += i;
8484  return result;
8485  }
8486 
8492  {
8493  auto result = *this;
8494  result -= i;
8495  return result;
8496  }
8497 
8503  {
8504  assert(m_object != nullptr);
8505 
8506  switch (m_object->m_type)
8507  {
8509  {
8510  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8511  }
8512 
8514  {
8515  return m_it.array_iterator - other.m_it.array_iterator;
8516  }
8517 
8518  default:
8519  {
8520  return m_it.primitive_iterator - other.m_it.primitive_iterator;
8521  }
8522  }
8523  }
8524 
8530  {
8531  assert(m_object != nullptr);
8532 
8533  switch (m_object->m_type)
8534  {
8536  {
8537  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
8538  }
8539 
8541  {
8542  return *std::next(m_it.array_iterator, n);
8543  }
8544 
8545  case basic_json::value_t::null:
8546  {
8547  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8548  }
8549 
8550  default:
8551  {
8552  if (m_it.primitive_iterator.get_value() == -n)
8553  {
8554  return *m_object;
8555  }
8556 
8557  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8558  }
8559  }
8560  }
8561 
8566  typename object_t::key_type key() const
8567  {
8568  assert(m_object != nullptr);
8569 
8570  if (m_object->is_object())
8571  {
8572  return m_it.object_iterator->first;
8573  }
8574 
8575  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
8576  }
8577 
8583  {
8584  return operator*();
8585  }
8586 
8587  private:
8589  pointer m_object = nullptr;
8592  };
8593 
8611  template<typename Base>
8612  class json_reverse_iterator : public std::reverse_iterator<Base>
8613  {
8614  public:
8616  using base_iterator = std::reverse_iterator<Base>;
8618  using reference = typename Base::reference;
8619 
8621  json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
8622  : base_iterator(it)
8623  {}
8624 
8627  : base_iterator(it)
8628  {}
8629 
8632  {
8633  return base_iterator::operator++(1);
8634  }
8635 
8638  {
8639  base_iterator::operator++();
8640  return *this;
8641  }
8642 
8645  {
8646  return base_iterator::operator--(1);
8647  }
8648 
8651  {
8652  base_iterator::operator--();
8653  return *this;
8654  }
8655 
8658  {
8659  base_iterator::operator+=(i);
8660  return *this;
8661  }
8662 
8665  {
8666  auto result = *this;
8667  result += i;
8668  return result;
8669  }
8670 
8673  {
8674  auto result = *this;
8675  result -= i;
8676  return result;
8677  }
8678 
8681  {
8682  return this->base() - other.base();
8683  }
8684 
8687  {
8688  return *(this->operator+(n));
8689  }
8690 
8692  typename object_t::key_type key() const
8693  {
8694  auto it = --this->base();
8695  return it.key();
8696  }
8697 
8700  {
8701  auto it = --this->base();
8702  return it.operator * ();
8703  }
8704  };
8705 
8706 
8707  private:
8709  // input adapters //
8711 
8714  {
8715  public:
8716  virtual int get_character() = 0;
8717  virtual std::string read(size_t offset, size_t length) = 0;
8718  virtual ~input_adapter() {}
8719 
8720  // native support
8721 
8723  static std::shared_ptr<input_adapter> create(std::istream& i, const size_t buffer_size = 16384)
8724  {
8725  return std::shared_ptr<input_adapter>(new cached_input_stream_adapter(i, buffer_size));
8726  }
8727 
8729  static std::shared_ptr<input_adapter> create(std::istream&& i, const size_t buffer_size = 16384)
8730  {
8731  return std::shared_ptr<input_adapter>(new cached_input_stream_adapter(i, buffer_size));
8732  }
8733 
8735  static std::shared_ptr<input_adapter> create(const char* b, size_t l)
8736  {
8737  return std::shared_ptr<input_adapter>(new input_buffer_adapter(b, l));
8738  }
8739 
8740  // derived support
8741 
8743  template<typename CharT, typename std::enable_if<
8744  std::is_pointer<CharT>::value and
8746  sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
8747  static std::shared_ptr<input_adapter> create(CharT b)
8748  {
8749  return create(reinterpret_cast<const char*>(b),
8750  std::strlen(reinterpret_cast<const char*>(b)));
8751  }
8752 
8754  template<class IteratorType, typename std::enable_if<
8755  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
8756  , int>::type
8757  = 0>
8758  static std::shared_ptr<input_adapter> create(IteratorType first, IteratorType last)
8759  {
8760  // assertion to check that the iterator range is indeed contiguous,
8761  // see http://stackoverflow.com/a/35008842/266378 for more discussion
8762  assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
8763  [&first](std::pair<bool, int> res, decltype(*first) val)
8764  {
8765  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
8766  return res;
8767  }).first);
8768 
8769  // assertion to check that each element is 1 byte long
8770  static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
8771  "each element in the iterator range must have the size of 1 byte");
8772 
8773  return create(reinterpret_cast<const char*>(&(*first)),
8774  static_cast<size_t>(std::distance(first, last)));
8775  }
8776 
8778  template<class T, std::size_t N>
8779  static std::shared_ptr<input_adapter> create(T (&array)[N])
8780  {
8781  // delegate the call to the iterator-range overload
8782  return create(std::begin(array), std::end(array));
8783  }
8784 
8786  template<class ContiguousContainer, typename std::enable_if<
8787  not std::is_pointer<ContiguousContainer>::value and
8788  std::is_base_of<
8789  std::random_access_iterator_tag,
8790  typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
8791  , int>::type = 0>
8792  static std::shared_ptr<input_adapter> create(const ContiguousContainer& c)
8793  {
8794  // delegate the call to the iterator-range overload
8795  return create(std::begin(c), std::end(c));
8796  }
8797  };
8798 
8800  using input_adapter_t = std::shared_ptr<input_adapter>;
8801 
8804  {
8805  public:
8806  cached_input_stream_adapter(std::istream& i, const size_t buffer_size)
8807  : is(i), start_position(is.tellg()), buffer(buffer_size, '\0')
8808  {
8809  // immediately abort if stream is erroneous
8810  if (JSON_UNLIKELY(i.fail()))
8811  {
8812  JSON_THROW(parse_error::create(111, 0, "bad input stream"));
8813  }
8814 
8815  // initial fill
8816  is.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
8817  // store number of bytes in the buffer
8818  fill_size = static_cast<size_t>(is.gcount());
8819 
8820  // skip byte order mark
8821  if (fill_size >= 3 and buffer[0] == '\xEF' and buffer[1] == '\xBB' and buffer[2] == '\xBF')
8822  {
8823  buffer_pos += 3;
8824  processed_chars += 3;
8825  }
8826  }
8827 
8829  {
8830  // clear stream flags
8831  is.clear();
8832  // We initially read a lot of characters into the buffer, and we
8833  // may not have processed all of them. Therefore, we need to
8834  // "rewind" the stream after the last processed char.
8835  is.seekg(start_position + static_cast<std::streamoff>(processed_chars));
8836  // clear stream flags
8837  is.clear();
8838  }
8839 
8840  int get_character() override
8841  {
8842  // check if refilling is necessary and possible
8843  if (buffer_pos == fill_size and not eof)
8844  {
8845  // refill
8846  is.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
8847  // store number of bytes in the buffer
8848  fill_size = static_cast<size_t>(is.gcount());
8849 
8850  // the buffer is ready
8851  buffer_pos = 0;
8852 
8853  // remember that filling did not yield new input
8854  if (fill_size == 0)
8855  {
8856  eof = true;
8857  return std::char_traits<char>::eof();
8858  }
8859  }
8860 
8861  ++processed_chars;
8862  return buffer[buffer_pos++] & 0xFF;;
8863  }
8864 
8865  std::string read(size_t offset, size_t length) override
8866  {
8867  // create buffer
8868  std::string result(length, '\0');
8869 
8870  // save stream position
8871  auto current_pos = is.tellg();
8872  // save stream flags
8873  auto flags = is.rdstate();
8874 
8875  // clear stream flags
8876  is.clear();
8877  // set stream position
8878  is.seekg(static_cast<std::streamoff>(offset));
8879  // read bytes
8880  is.read(&result[0], static_cast<std::streamsize>(length));
8881 
8882  // reset stream position
8883  is.seekg(current_pos);
8884  // reset stream flags
8885  is.setstate(flags);
8886 
8887  return result;
8888  }
8889 
8890  private:
8892  std::istream& is;
8893 
8895  size_t processed_chars = 0;
8897  size_t buffer_pos = 0;
8898 
8900  bool eof = false;
8902  size_t fill_size = 0;
8903 
8905  const std::streampos start_position;
8906 
8908  std::vector<char> buffer;
8909  };
8910 
8913  {
8914  public:
8915  input_buffer_adapter(const char* b, size_t l)
8916  : input_adapter(), cursor(b), limit(b + l), start(b)
8917  {
8918  // skip byte order mark
8919  if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
8920  {
8921  cursor += 3;
8922  }
8923  }
8924 
8925  // delete because of pointer members
8926  input_buffer_adapter(const input_buffer_adapter&) = delete;
8928 
8929  int get_character() override
8930  {
8931  if (JSON_LIKELY(cursor < limit))
8932  {
8933  return *(cursor++) & 0xFF;
8934  }
8935  else
8936  {
8937  return std::char_traits<char>::eof();
8938  }
8939  }
8940 
8941  std::string read(size_t offset, size_t length) override
8942  {
8943  // avoid reading too many characters
8944  const size_t max_length = static_cast<size_t>(limit - start);
8945  return std::string(start + offset, std::min(length, max_length - offset));
8946  }
8947 
8948  private:
8950  const char* cursor;
8952  const char* limit;
8954  const char* start;
8955  };
8956 
8958  // binary serialization/deserialization //
8960 
8963 
8964  private:
8969  {
8970  public:
8976  explicit binary_reader(input_adapter_t adapter)
8977  : ia(adapter), is_little_endian(little_endianess())
8978  {
8979  assert(ia);
8980  }
8981 
8994  basic_json parse_cbor(const bool get_char = true)
8995  {
8996  switch (get_char ? get() : current)
8997  {
8998  // EOF
8999  case std::char_traits<char>::eof():
9000  {
9001  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
9002  }
9003 
9004  // Integer 0x00..0x17 (0..23)
9005  case 0x00:
9006  case 0x01:
9007  case 0x02:
9008  case 0x03:
9009  case 0x04:
9010  case 0x05:
9011  case 0x06:
9012  case 0x07:
9013  case 0x08:
9014  case 0x09:
9015  case 0x0a:
9016  case 0x0b:
9017  case 0x0c:
9018  case 0x0d:
9019  case 0x0e:
9020  case 0x0f:
9021  case 0x10:
9022  case 0x11:
9023  case 0x12:
9024  case 0x13:
9025  case 0x14:
9026  case 0x15:
9027  case 0x16:
9028  case 0x17:
9029  {
9030  return static_cast<number_unsigned_t>(current);
9031  }
9032 
9033  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9034  {
9035  return get_number<uint8_t>();
9036  }
9037 
9038  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9039  {
9040  return get_number<uint16_t>();
9041  }
9042 
9043  case 0x1a: // Unsigned integer (four-byte uint32_t follows)
9044  {
9045  return get_number<uint32_t>();
9046  }
9047 
9048  case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
9049  {
9050  return get_number<uint64_t>();
9051  }
9052 
9053  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9054  case 0x20:
9055  case 0x21:
9056  case 0x22:
9057  case 0x23:
9058  case 0x24:
9059  case 0x25:
9060  case 0x26:
9061  case 0x27:
9062  case 0x28:
9063  case 0x29:
9064  case 0x2a:
9065  case 0x2b:
9066  case 0x2c:
9067  case 0x2d:
9068  case 0x2e:
9069  case 0x2f:
9070  case 0x30:
9071  case 0x31:
9072  case 0x32:
9073  case 0x33:
9074  case 0x34:
9075  case 0x35:
9076  case 0x36:
9077  case 0x37:
9078  {
9079  return static_cast<int8_t>(0x20 - 1 - current);
9080  }
9081 
9082  case 0x38: // Negative integer (one-byte uint8_t follows)
9083  {
9084  // must be uint8_t !
9085  return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
9086  }
9087 
9088  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9089  {
9090  return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
9091  }
9092 
9093  case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
9094  {
9095  return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
9096  }
9097 
9098  case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
9099  {
9100  return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_number<uint64_t>());
9101  }
9102 
9103  // UTF-8 string (0x00..0x17 bytes follow)
9104  case 0x60:
9105  case 0x61:
9106  case 0x62:
9107  case 0x63:
9108  case 0x64:
9109  case 0x65:
9110  case 0x66:
9111  case 0x67:
9112  case 0x68:
9113  case 0x69:
9114  case 0x6a:
9115  case 0x6b:
9116  case 0x6c:
9117  case 0x6d:
9118  case 0x6e:
9119  case 0x6f:
9120  case 0x70:
9121  case 0x71:
9122  case 0x72:
9123  case 0x73:
9124  case 0x74:
9125  case 0x75:
9126  case 0x76:
9127  case 0x77:
9128  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9129  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9130  case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
9131  case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
9132  case 0x7f: // UTF-8 string (indefinite length)
9133  {
9134  return get_cbor_string();
9135  }
9136 
9137  // array (0x00..0x17 data items follow)
9138  case 0x80:
9139  case 0x81:
9140  case 0x82:
9141  case 0x83:
9142  case 0x84:
9143  case 0x85:
9144  case 0x86:
9145  case 0x87:
9146  case 0x88:
9147  case 0x89:
9148  case 0x8a:
9149  case 0x8b:
9150  case 0x8c:
9151  case 0x8d:
9152  case 0x8e:
9153  case 0x8f:
9154  case 0x90:
9155  case 0x91:
9156  case 0x92:
9157  case 0x93:
9158  case 0x94:
9159  case 0x95:
9160  case 0x96:
9161  case 0x97:
9162  {
9163  basic_json result = value_t::array;
9164  const auto len = static_cast<size_t>(current & 0x1f);
9165  for (size_t i = 0; i < len; ++i)
9166  {
9167  result.push_back(parse_cbor());
9168  }
9169  return result;
9170  }
9171 
9172  case 0x98: // array (one-byte uint8_t for n follows)
9173  {
9174  basic_json result = value_t::array;
9175  const auto len = static_cast<size_t>(get_number<uint8_t>());
9176  for (size_t i = 0; i < len; ++i)
9177  {
9178  result.push_back(parse_cbor());
9179  }
9180  return result;
9181  }
9182 
9183  case 0x99: // array (two-byte uint16_t for n follow)
9184  {
9185  basic_json result = value_t::array;
9186  const auto len = static_cast<size_t>(get_number<uint16_t>());
9187  for (size_t i = 0; i < len; ++i)
9188  {
9189  result.push_back(parse_cbor());
9190  }
9191  return result;
9192  }
9193 
9194  case 0x9a: // array (four-byte uint32_t for n follow)
9195  {
9196  basic_json result = value_t::array;
9197  const auto len = static_cast<size_t>(get_number<uint32_t>());
9198  for (size_t i = 0; i < len; ++i)
9199  {
9200  result.push_back(parse_cbor());
9201  }
9202  return result;
9203  }
9204 
9205  case 0x9b: // array (eight-byte uint64_t for n follow)
9206  {
9207  basic_json result = value_t::array;
9208  const auto len = static_cast<size_t>(get_number<uint64_t>());
9209  for (size_t i = 0; i < len; ++i)
9210  {
9211  result.push_back(parse_cbor());
9212  }
9213  return result;
9214  }
9215 
9216  case 0x9f: // array (indefinite length)
9217  {
9218  basic_json result = value_t::array;
9219  while (get() != 0xff)
9220  {
9221  result.push_back(parse_cbor(false));
9222  }
9223  return result;
9224  }
9225 
9226  // map (0x00..0x17 pairs of data items follow)
9227  case 0xa0:
9228  case 0xa1:
9229  case 0xa2:
9230  case 0xa3:
9231  case 0xa4:
9232  case 0xa5:
9233  case 0xa6:
9234  case 0xa7:
9235  case 0xa8:
9236  case 0xa9:
9237  case 0xaa:
9238  case 0xab:
9239  case 0xac:
9240  case 0xad:
9241  case 0xae:
9242  case 0xaf:
9243  case 0xb0:
9244  case 0xb1:
9245  case 0xb2:
9246  case 0xb3:
9247  case 0xb4:
9248  case 0xb5:
9249  case 0xb6:
9250  case 0xb7:
9251  {
9252  basic_json result = value_t::object;
9253  const auto len = static_cast<size_t>(current & 0x1f);
9254  for (size_t i = 0; i < len; ++i)
9255  {
9256  get();
9257  auto key = get_cbor_string();
9258  result[key] = parse_cbor();
9259  }
9260  return result;
9261  }
9262 
9263  case 0xb8: // map (one-byte uint8_t for n follows)
9264  {
9265  basic_json result = value_t::object;
9266  const auto len = static_cast<size_t>(get_number<uint8_t>());
9267  for (size_t i = 0; i < len; ++i)
9268  {
9269  get();
9270  auto key = get_cbor_string();
9271  result[key] = parse_cbor();
9272  }
9273  return result;
9274  }
9275 
9276  case 0xb9: // map (two-byte uint16_t for n follow)
9277  {
9278  basic_json result = value_t::object;
9279  const auto len = static_cast<size_t>(get_number<uint16_t>());
9280  for (size_t i = 0; i < len; ++i)
9281  {
9282  get();
9283  auto key = get_cbor_string();
9284  result[key] = parse_cbor();
9285  }
9286  return result;
9287  }
9288 
9289  case 0xba: // map (four-byte uint32_t for n follow)
9290  {
9291  basic_json result = value_t::object;
9292  const auto len = static_cast<size_t>(get_number<uint32_t>());
9293  for (size_t i = 0; i < len; ++i)
9294  {
9295  get();
9296  auto key = get_cbor_string();
9297  result[key] = parse_cbor();
9298  }
9299  return result;
9300  }
9301 
9302  case 0xbb: // map (eight-byte uint64_t for n follow)
9303  {
9304  basic_json result = value_t::object;
9305  const auto len = static_cast<size_t>(get_number<uint64_t>());
9306  for (size_t i = 0; i < len; ++i)
9307  {
9308  get();
9309  auto key = get_cbor_string();
9310  result[key] = parse_cbor();
9311  }
9312  return result;
9313  }
9314 
9315  case 0xbf: // map (indefinite length)
9316  {
9317  basic_json result = value_t::object;
9318  while (get() != 0xff)
9319  {
9320  auto key = get_cbor_string();
9321  result[key] = parse_cbor();
9322  }
9323  return result;
9324  }
9325 
9326  case 0xf4: // false
9327  {
9328  return false;
9329  }
9330 
9331  case 0xf5: // true
9332  {
9333  return true;
9334  }
9335 
9336  case 0xf6: // null
9337  {
9338  return value_t::null;
9339  }
9340 
9341  case 0xf9: // Half-Precision Float (two-byte IEEE 754)
9342  {
9343  const int byte1 = get();
9344  check_eof();
9345  const int byte2 = get();
9346  check_eof();
9347 
9348  // code from RFC 7049, Appendix D, Figure 3:
9349  // As half-precision floating-point numbers were only added
9350  // to IEEE 754 in 2008, today's programming platforms often
9351  // still only have limited support for them. It is very
9352  // easy to include at least decoding support for them even
9353  // without such support. An example of a small decoder for
9354  // half-precision floating-point numbers in the C language
9355  // is shown in Fig. 3.
9356  const int half = (byte1 << 8) + byte2;
9357  const int exp = (half >> 10) & 0x1f;
9358  const int mant = half & 0x3ff;
9359  double val;
9360  if (exp == 0)
9361  {
9362  val = std::ldexp(mant, -24);
9363  }
9364  else if (exp != 31)
9365  {
9366  val = std::ldexp(mant + 1024, exp - 25);
9367  }
9368  else
9369  {
9370  val = mant == 0
9371  ? std::numeric_limits<double>::infinity()
9372  : std::numeric_limits<double>::quiet_NaN();
9373  }
9374  return (half & 0x8000) != 0 ? -val : val;
9375  }
9376 
9377  case 0xfa: // Single-Precision Float (four-byte IEEE 754)
9378  {
9379  return get_number<float>();
9380  }
9381 
9382  case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
9383  {
9384  return get_number<double>();
9385  }
9386 
9387  default: // anything else (0xFF is handled inside the other types)
9388  {
9389  std::stringstream ss;
9390  ss << std::setw(2) << std::setfill('0') << std::hex << current;
9391  JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
9392  }
9393  }
9394  }
9395 
9405  {
9406  switch (get())
9407  {
9408  // EOF
9409  case std::char_traits<char>::eof():
9410  {
9411  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
9412  }
9413 
9414  // positive fixint
9415  case 0x00:
9416  case 0x01:
9417  case 0x02:
9418  case 0x03:
9419  case 0x04:
9420  case 0x05:
9421  case 0x06:
9422  case 0x07:
9423  case 0x08:
9424  case 0x09:
9425  case 0x0a:
9426  case 0x0b:
9427  case 0x0c:
9428  case 0x0d:
9429  case 0x0e:
9430  case 0x0f:
9431  case 0x10:
9432  case 0x11:
9433  case 0x12:
9434  case 0x13:
9435  case 0x14:
9436  case 0x15:
9437  case 0x16:
9438  case 0x17:
9439  case 0x18:
9440  case 0x19:
9441  case 0x1a:
9442  case 0x1b:
9443  case 0x1c:
9444  case 0x1d:
9445  case 0x1e:
9446  case 0x1f:
9447  case 0x20:
9448  case 0x21:
9449  case 0x22:
9450  case 0x23:
9451  case 0x24:
9452  case 0x25:
9453  case 0x26:
9454  case 0x27:
9455  case 0x28:
9456  case 0x29:
9457  case 0x2a:
9458  case 0x2b:
9459  case 0x2c:
9460  case 0x2d:
9461  case 0x2e:
9462  case 0x2f:
9463  case 0x30:
9464  case 0x31:
9465  case 0x32:
9466  case 0x33:
9467  case 0x34:
9468  case 0x35:
9469  case 0x36:
9470  case 0x37:
9471  case 0x38:
9472  case 0x39:
9473  case 0x3a:
9474  case 0x3b:
9475  case 0x3c:
9476  case 0x3d:
9477  case 0x3e:
9478  case 0x3f:
9479  case 0x40:
9480  case 0x41:
9481  case 0x42:
9482  case 0x43:
9483  case 0x44:
9484  case 0x45:
9485  case 0x46:
9486  case 0x47:
9487  case 0x48:
9488  case 0x49:
9489  case 0x4a:
9490  case 0x4b:
9491  case 0x4c:
9492  case 0x4d:
9493  case 0x4e:
9494  case 0x4f:
9495  case 0x50:
9496  case 0x51:
9497  case 0x52:
9498  case 0x53:
9499  case 0x54:
9500  case 0x55:
9501  case 0x56:
9502  case 0x57:
9503  case 0x58:
9504  case 0x59:
9505  case 0x5a:
9506  case 0x5b:
9507  case 0x5c:
9508  case 0x5d:
9509  case 0x5e:
9510  case 0x5f:
9511  case 0x60:
9512  case 0x61:
9513  case 0x62:
9514  case 0x63:
9515  case 0x64:
9516  case 0x65:
9517  case 0x66:
9518  case 0x67:
9519  case 0x68:
9520  case 0x69:
9521  case 0x6a:
9522  case 0x6b:
9523  case 0x6c:
9524  case 0x6d:
9525  case 0x6e:
9526  case 0x6f:
9527  case 0x70:
9528  case 0x71:
9529  case 0x72:
9530  case 0x73:
9531  case 0x74:
9532  case 0x75:
9533  case 0x76:
9534  case 0x77:
9535  case 0x78:
9536  case 0x79:
9537  case 0x7a:
9538  case 0x7b:
9539  case 0x7c:
9540  case 0x7d:
9541  case 0x7e:
9542  case 0x7f:
9543  {
9544  return static_cast<number_unsigned_t>(current);
9545  }
9546 
9547  // fixmap
9548  case 0x80:
9549  case 0x81:
9550  case 0x82:
9551  case 0x83:
9552  case 0x84:
9553  case 0x85:
9554  case 0x86:
9555  case 0x87:
9556  case 0x88:
9557  case 0x89:
9558  case 0x8a:
9559  case 0x8b:
9560  case 0x8c:
9561  case 0x8d:
9562  case 0x8e:
9563  case 0x8f:
9564  {
9565  basic_json result = value_t::object;
9566  const auto len = static_cast<size_t>(current & 0x0f);
9567  for (size_t i = 0; i < len; ++i)
9568  {
9569  get();
9570  auto key = get_msgpack_string();
9571  result[key] = parse_msgpack();
9572  }
9573  return result;
9574  }
9575 
9576  // fixarray
9577  case 0x90:
9578  case 0x91:
9579  case 0x92:
9580  case 0x93:
9581  case 0x94:
9582  case 0x95:
9583  case 0x96:
9584  case 0x97:
9585  case 0x98:
9586  case 0x99:
9587  case 0x9a:
9588  case 0x9b:
9589  case 0x9c:
9590  case 0x9d:
9591  case 0x9e:
9592  case 0x9f:
9593  {
9594  basic_json result = value_t::array;
9595  const auto len = static_cast<size_t>(current & 0x0f);
9596  for (size_t i = 0; i < len; ++i)
9597  {
9598  result.push_back(parse_msgpack());
9599  }
9600  return result;
9601  }
9602 
9603  // fixstr
9604  case 0xa0:
9605  case 0xa1:
9606  case 0xa2:
9607  case 0xa3:
9608  case 0xa4:
9609  case 0xa5:
9610  case 0xa6:
9611  case 0xa7:
9612  case 0xa8:
9613  case 0xa9:
9614  case 0xaa:
9615  case 0xab:
9616  case 0xac:
9617  case 0xad:
9618  case 0xae:
9619  case 0xaf:
9620  case 0xb0:
9621  case 0xb1:
9622  case 0xb2:
9623  case 0xb3:
9624  case 0xb4:
9625  case 0xb5:
9626  case 0xb6:
9627  case 0xb7:
9628  case 0xb8:
9629  case 0xb9:
9630  case 0xba:
9631  case 0xbb:
9632  case 0xbc:
9633  case 0xbd:
9634  case 0xbe:
9635  case 0xbf:
9636  {
9637  return get_msgpack_string();
9638  }
9639 
9640  case 0xc0: // nil
9641  {
9642  return value_t::null;
9643  }
9644 
9645  case 0xc2: // false
9646  {
9647  return false;
9648  }
9649 
9650  case 0xc3: // true
9651  {
9652  return true;
9653  }
9654 
9655  case 0xca: // float 32
9656  {
9657  return get_number<float>();
9658  }
9659 
9660  case 0xcb: // float 64
9661  {
9662  return get_number<double>();
9663  }
9664 
9665  case 0xcc: // uint 8
9666  {
9667  return get_number<uint8_t>();
9668  }
9669 
9670  case 0xcd: // uint 16
9671  {
9672  return get_number<uint16_t>();
9673  }
9674 
9675  case 0xce: // uint 32
9676  {
9677  return get_number<uint32_t>();
9678  }
9679 
9680  case 0xcf: // uint 64
9681  {
9682  return get_number<uint64_t>();
9683  }
9684 
9685  case 0xd0: // int 8
9686  {
9687  return get_number<int8_t>();
9688  }
9689 
9690  case 0xd1: // int 16
9691  {
9692  return get_number<int16_t>();
9693  }
9694 
9695  case 0xd2: // int 32
9696  {
9697  return get_number<int32_t>();
9698  }
9699 
9700  case 0xd3: // int 64
9701  {
9702  return get_number<int64_t>();
9703  }
9704 
9705  case 0xd9: // str 8
9706  case 0xda: // str 16
9707  case 0xdb: // str 32
9708  {
9709  return get_msgpack_string();
9710  }
9711 
9712  case 0xdc: // array 16
9713  {
9714  basic_json result = value_t::array;
9715  const auto len = static_cast<size_t>(get_number<uint16_t>());
9716  for (size_t i = 0; i < len; ++i)
9717  {
9718  result.push_back(parse_msgpack());
9719  }
9720  return result;
9721  }
9722 
9723  case 0xdd: // array 32
9724  {
9725  basic_json result = value_t::array;
9726  const auto len = static_cast<size_t>(get_number<uint32_t>());
9727  for (size_t i = 0; i < len; ++i)
9728  {
9729  result.push_back(parse_msgpack());
9730  }
9731  return result;
9732  }
9733 
9734  case 0xde: // map 16
9735  {
9736  basic_json result = value_t::object;
9737  const auto len = static_cast<size_t>(get_number<uint16_t>());
9738  for (size_t i = 0; i < len; ++i)
9739  {
9740  get();
9741  auto key = get_msgpack_string();
9742  result[key] = parse_msgpack();
9743  }
9744  return result;
9745  }
9746 
9747  case 0xdf: // map 32
9748  {
9749  basic_json result = value_t::object;
9750  const auto len = static_cast<size_t>(get_number<uint32_t>());
9751  for (size_t i = 0; i < len; ++i)
9752  {
9753  get();
9754  auto key = get_msgpack_string();
9755  result[key] = parse_msgpack();
9756  }
9757  return result;
9758  }
9759 
9760  // positive fixint
9761  case 0xe0:
9762  case 0xe1:
9763  case 0xe2:
9764  case 0xe3:
9765  case 0xe4:
9766  case 0xe5:
9767  case 0xe6:
9768  case 0xe7:
9769  case 0xe8:
9770  case 0xe9:
9771  case 0xea:
9772  case 0xeb:
9773  case 0xec:
9774  case 0xed:
9775  case 0xee:
9776  case 0xef:
9777  case 0xf0:
9778  case 0xf1:
9779  case 0xf2:
9780  case 0xf3:
9781  case 0xf4:
9782  case 0xf5:
9783  case 0xf6:
9784  case 0xf7:
9785  case 0xf8:
9786  case 0xf9:
9787  case 0xfa:
9788  case 0xfb:
9789  case 0xfc:
9790  case 0xfd:
9791  case 0xfe:
9792  case 0xff:
9793  {
9794  return static_cast<int8_t>(current);
9795  }
9796 
9797  default: // anything else
9798  {
9799  std::stringstream ss;
9800  ss << std::setw(2) << std::setfill('0') << std::hex << current;
9801  JSON_THROW(parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + ss.str()));
9802  }
9803  }
9804  }
9805 
9813  static bool little_endianess() noexcept
9814  {
9815  int num = 1;
9816  return (*reinterpret_cast<char*>(&num) == 1);
9817  }
9818 
9819  private:
9829  int get()
9830  {
9831  ++chars_read;
9832  return (current = ia->get_character());
9833  }
9834 
9835  /*
9836  @brief read a number from the input
9837 
9838  @tparam T the type of the number
9839 
9840  @return number of type @a T
9841 
9842  @note This function needs to respect the system's endianess, because
9843  bytes in CBOR and MessagePack are stored in network order (big
9844  endian) and therefore need reordering on little endian systems.
9845 
9846  @throw parse_error.110 if input has less than `sizeof(T)` bytes
9847  */
9848  template<typename T>
9850  {
9851  // step 1: read input into array with system's byte order
9852  std::array<uint8_t, sizeof(T)> vec;
9853  for (size_t i = 0; i < sizeof(T); ++i)
9854  {
9855  get();
9856  check_eof();
9857 
9858  // reverse byte order prior to conversion if necessary
9859  if (is_little_endian)
9860  {
9861  vec[sizeof(T) - i - 1] = static_cast<uint8_t>(current);
9862  }
9863  else
9864  {
9865  vec[i] = static_cast<uint8_t>(current);
9866  }
9867  }
9868 
9869  // step 2: convert array into number of type T and return
9870  T result;
9871  std::memcpy(&result, vec.data(), sizeof(T));
9872  return result;
9873  }
9874 
9884  std::string get_string(const size_t len)
9885  {
9886  std::string result;
9887  for (size_t i = 0; i < len; ++i)
9888  {
9889  get();
9890  check_eof();
9891  result.append(1, static_cast<char>(current));
9892  }
9893  return result;
9894  }
9895 
9908  std::string get_cbor_string()
9909  {
9910  check_eof();
9911 
9912  switch (current)
9913  {
9914  // UTF-8 string (0x00..0x17 bytes follow)
9915  case 0x60:
9916  case 0x61:
9917  case 0x62:
9918  case 0x63:
9919  case 0x64:
9920  case 0x65:
9921  case 0x66:
9922  case 0x67:
9923  case 0x68:
9924  case 0x69:
9925  case 0x6a:
9926  case 0x6b:
9927  case 0x6c:
9928  case 0x6d:
9929  case 0x6e:
9930  case 0x6f:
9931  case 0x70:
9932  case 0x71:
9933  case 0x72:
9934  case 0x73:
9935  case 0x74:
9936  case 0x75:
9937  case 0x76:
9938  case 0x77:
9939  {
9940  const auto len = static_cast<size_t>(current & 0x1f);
9941  return get_string(len);
9942  }
9943 
9944  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9945  {
9946  const auto len = static_cast<size_t>(get_number<uint8_t>());
9947  return get_string(len);
9948  }
9949 
9950  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9951  {
9952  const auto len = static_cast<size_t>(get_number<uint16_t>());
9953  return get_string(len);
9954  }
9955 
9956  case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
9957  {
9958  const auto len = static_cast<size_t>(get_number<uint32_t>());
9959  return get_string(len);
9960  }
9961 
9962  case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
9963  {
9964  const auto len = static_cast<size_t>(get_number<uint64_t>());
9965  return get_string(len);
9966  }
9967 
9968  case 0x7f: // UTF-8 string (indefinite length)
9969  {
9970  std::string result;
9971  while (get() != 0xff)
9972  {
9973  check_eof();
9974  result.append(1, static_cast<char>(current));
9975  }
9976  return result;
9977  }
9978 
9979  default:
9980  {
9981  std::stringstream ss;
9982  ss << std::setw(2) << std::setfill('0') << std::hex << current;
9983  JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
9984  }
9985  }
9986  }
9987 
9999  std::string get_msgpack_string()
10000  {
10001  check_eof();
10002 
10003  switch (current)
10004  {
10005  // fixstr
10006  case 0xa0:
10007  case 0xa1:
10008  case 0xa2:
10009  case 0xa3:
10010  case 0xa4:
10011  case 0xa5:
10012  case 0xa6:
10013  case 0xa7:
10014  case 0xa8:
10015  case 0xa9:
10016  case 0xaa:
10017  case 0xab:
10018  case 0xac:
10019  case 0xad:
10020  case 0xae:
10021  case 0xaf:
10022  case 0xb0:
10023  case 0xb1:
10024  case 0xb2:
10025  case 0xb3:
10026  case 0xb4:
10027  case 0xb5:
10028  case 0xb6:
10029  case 0xb7:
10030  case 0xb8:
10031  case 0xb9:
10032  case 0xba:
10033  case 0xbb:
10034  case 0xbc:
10035  case 0xbd:
10036  case 0xbe:
10037  case 0xbf:
10038  {
10039  const auto len = static_cast<size_t>(current & 0x1f);
10040  return get_string(len);
10041  }
10042 
10043  case 0xd9: // str 8
10044  {
10045  const auto len = static_cast<size_t>(get_number<uint8_t>());
10046  return get_string(len);
10047  }
10048 
10049  case 0xda: // str 16
10050  {
10051  const auto len = static_cast<size_t>(get_number<uint16_t>());
10052  return get_string(len);
10053  }
10054 
10055  case 0xdb: // str 32
10056  {
10057  const auto len = static_cast<size_t>(get_number<uint32_t>());
10058  return get_string(len);
10059  }
10060 
10061  default:
10062  {
10063  std::stringstream ss;
10064  ss << std::setw(2) << std::setfill('0') << std::hex << current;
10065  JSON_THROW(parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + ss.str()));
10066  }
10067  }
10068  }
10069 
10074  void check_eof() const
10075  {
10076  if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
10077  {
10078  JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
10079  }
10080  }
10081 
10082  private:
10084  input_adapter_t ia = nullptr;
10085 
10087  int current = std::char_traits<char>::eof();
10088 
10090  size_t chars_read = 0;
10091 
10093  const bool is_little_endian = true;
10094  };
10095 
10100  {
10101  public:
10108  : is_little_endian(binary_reader::little_endianess()), oa(adapter)
10109  {
10110  assert(oa);
10111  }
10112 
10116  void write_cbor(const basic_json& j)
10117  {
10118  switch (j.type())
10119  {
10120  case value_t::null:
10121  {
10122  oa->write_character(0xf6);
10123  break;
10124  }
10125 
10126  case value_t::boolean:
10127  {
10128  oa->write_character(j.m_value.boolean ? 0xf5 : 0xf4);
10129  break;
10130  }
10131 
10133  {
10134  if (j.m_value.number_integer >= 0)
10135  {
10136  // CBOR does not differentiate between positive signed
10137  // integers and unsigned integers. Therefore, we used the
10138  // code from the value_t::number_unsigned case here.
10139  if (j.m_value.number_integer <= 0x17)
10140  {
10141  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10142  }
10143  else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
10144  {
10145  oa->write_character(0x18);
10146  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10147  }
10148  else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
10149  {
10150  oa->write_character(0x19);
10151  write_number(static_cast<uint16_t>(j.m_value.number_integer));
10152  }
10153  else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
10154  {
10155  oa->write_character(0x1a);
10156  write_number(static_cast<uint32_t>(j.m_value.number_integer));
10157  }
10158  else
10159  {
10160  oa->write_character(0x1b);
10161  write_number(static_cast<uint64_t>(j.m_value.number_integer));
10162  }
10163  }
10164  else
10165  {
10166  // The conversions below encode the sign in the first
10167  // byte, and the value is converted to a positive number.
10168  const auto positive_number = -1 - j.m_value.number_integer;
10169  if (j.m_value.number_integer >= -24)
10170  {
10171  write_number(static_cast<uint8_t>(0x20 + positive_number));
10172  }
10173  else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
10174  {
10175  oa->write_character(0x38);
10176  write_number(static_cast<uint8_t>(positive_number));
10177  }
10178  else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
10179  {
10180  oa->write_character(0x39);
10181  write_number(static_cast<uint16_t>(positive_number));
10182  }
10183  else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
10184  {
10185  oa->write_character(0x3a);
10186  write_number(static_cast<uint32_t>(positive_number));
10187  }
10188  else
10189  {
10190  oa->write_character(0x3b);
10191  write_number(static_cast<uint64_t>(positive_number));
10192  }
10193  }
10194  break;
10195  }
10196 
10198  {
10199  if (j.m_value.number_unsigned <= 0x17)
10200  {
10201  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
10202  }
10203  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
10204  {
10205  oa->write_character(0x18);
10206  write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
10207  }
10208  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
10209  {
10210  oa->write_character(0x19);
10211  write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
10212  }
10213  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
10214  {
10215  oa->write_character(0x1a);
10216  write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
10217  }
10218  else
10219  {
10220  oa->write_character(0x1b);
10221  write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
10222  }
10223  break;
10224  }
10225 
10226  case value_t::number_float:
10227  {
10228  // Double-Precision Float
10229  oa->write_character(0xfb);
10230  write_number(j.m_value.number_float);
10231  break;
10232  }
10233 
10234  case value_t::string:
10235  {
10236  // step 1: write control byte and the string length
10237  const auto N = j.m_value.string->size();
10238  if (N <= 0x17)
10239  {
10240  write_number(static_cast<uint8_t>(0x60 + N));
10241  }
10242  else if (N <= 0xff)
10243  {
10244  oa->write_character(0x78);
10245  write_number(static_cast<uint8_t>(N));
10246  }
10247  else if (N <= 0xffff)
10248  {
10249  oa->write_character(0x79);
10250  write_number(static_cast<uint16_t>(N));
10251  }
10252  else if (N <= 0xffffffff)
10253  {
10254  oa->write_character(0x7a);
10255  write_number(static_cast<uint32_t>(N));
10256  }
10257  // LCOV_EXCL_START
10258  else if (N <= 0xffffffffffffffff)
10259  {
10260  oa->write_character(0x7b);
10261  write_number(static_cast<uint64_t>(N));
10262  }
10263  // LCOV_EXCL_STOP
10264 
10265  // step 2: write the string
10266  oa->write_characters(reinterpret_cast<const uint8_t*>(j.m_value.string->c_str()),
10267  j.m_value.string->size());
10268  break;
10269  }
10270 
10271  case value_t::array:
10272  {
10273  // step 1: write control byte and the array size
10274  const auto N = j.m_value.array->size();
10275  if (N <= 0x17)
10276  {
10277  write_number(static_cast<uint8_t>(0x80 + N));
10278  }
10279  else if (N <= 0xff)
10280  {
10281  oa->write_character(0x98);
10282  write_number(static_cast<uint8_t>(N));
10283  }
10284  else if (N <= 0xffff)
10285  {
10286  oa->write_character(0x99);
10287  write_number(static_cast<uint16_t>(N));
10288  }
10289  else if (N <= 0xffffffff)
10290  {
10291  oa->write_character(0x9a);
10292  write_number(static_cast<uint32_t>(N));
10293  }
10294  // LCOV_EXCL_START
10295  else if (N <= 0xffffffffffffffff)
10296  {
10297  oa->write_character(0x9b);
10298  write_number(static_cast<uint64_t>(N));
10299  }
10300  // LCOV_EXCL_STOP
10301 
10302  // step 2: write each element
10303  for (const auto& el : *j.m_value.array)
10304  {
10305  write_cbor(el);
10306  }
10307  break;
10308  }
10309 
10310  case value_t::object:
10311  {
10312  // step 1: write control byte and the object size
10313  const auto N = j.m_value.object->size();
10314  if (N <= 0x17)
10315  {
10316  write_number(static_cast<uint8_t>(0xa0 + N));
10317  }
10318  else if (N <= 0xff)
10319  {
10320  oa->write_character(0xb8);
10321  write_number(static_cast<uint8_t>(N));
10322  }
10323  else if (N <= 0xffff)
10324  {
10325  oa->write_character(0xb9);
10326  write_number(static_cast<uint16_t>(N));
10327  }
10328  else if (N <= 0xffffffff)
10329  {
10330  oa->write_character(0xba);
10331  write_number(static_cast<uint32_t>(N));
10332  }
10333  // LCOV_EXCL_START
10334  else if (N <= 0xffffffffffffffff)
10335  {
10336  oa->write_character(0xbb);
10337  write_number(static_cast<uint64_t>(N));
10338  }
10339  // LCOV_EXCL_STOP
10340 
10341  // step 2: write each element
10342  for (const auto& el : *j.m_value.object)
10343  {
10344  write_cbor(el.first);
10345  write_cbor(el.second);
10346  }
10347  break;
10348  }
10349 
10350  default:
10351  {
10352  break;
10353  }
10354  }
10355  }
10356 
10360  void write_msgpack(const basic_json& j)
10361  {
10362  switch (j.type())
10363  {
10364  case value_t::null:
10365  {
10366  // nil
10367  oa->write_character(0xc0);
10368  break;
10369  }
10370 
10371  case value_t::boolean:
10372  {
10373  // true and false
10374  oa->write_character(j.m_value.boolean ? 0xc3 : 0xc2);
10375  break;
10376  }
10377 
10379  {
10380  if (j.m_value.number_integer >= 0)
10381  {
10382  // MessagePack does not differentiate between positive
10383  // signed integers and unsigned integers. Therefore, we
10384  // used the code from the value_t::number_unsigned case
10385  // here.
10386  if (j.m_value.number_unsigned < 128)
10387  {
10388  // positive fixnum
10389  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10390  }
10391  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
10392  {
10393  // uint 8
10394  oa->write_character(0xcc);
10395  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10396  }
10397  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
10398  {
10399  // uint 16
10400  oa->write_character(0xcd);
10401  write_number(static_cast<uint16_t>(j.m_value.number_integer));
10402  }
10403  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
10404  {
10405  // uint 32
10406  oa->write_character(0xce);
10407  write_number(static_cast<uint32_t>(j.m_value.number_integer));
10408  }
10409  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
10410  {
10411  // uint 64
10412  oa->write_character(0xcf);
10413  write_number(static_cast<uint64_t>(j.m_value.number_integer));
10414  }
10415  }
10416  else
10417  {
10418  if (j.m_value.number_integer >= -32)
10419  {
10420  // negative fixnum
10421  write_number(static_cast<int8_t>(j.m_value.number_integer));
10422  }
10423  else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
10424  {
10425  // int 8
10426  oa->write_character(0xd0);
10427  write_number(static_cast<int8_t>(j.m_value.number_integer));
10428  }
10429  else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
10430  {
10431  // int 16
10432  oa->write_character(0xd1);
10433  write_number(static_cast<int16_t>(j.m_value.number_integer));
10434  }
10435  else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
10436  {
10437  // int 32
10438  oa->write_character(0xd2);
10439  write_number(static_cast<int32_t>(j.m_value.number_integer));
10440  }
10441  else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
10442  {
10443  // int 64
10444  oa->write_character(0xd3);
10445  write_number(static_cast<int64_t>(j.m_value.number_integer));
10446  }
10447  }
10448  break;
10449  }
10450 
10452  {
10453  if (j.m_value.number_unsigned < 128)
10454  {
10455  // positive fixnum
10456  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10457  }
10458  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
10459  {
10460  // uint 8
10461  oa->write_character(0xcc);
10462  write_number(static_cast<uint8_t>(j.m_value.number_integer));
10463  }
10464  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
10465  {
10466  // uint 16
10467  oa->write_character(0xcd);
10468  write_number(static_cast<uint16_t>(j.m_value.number_integer));
10469  }
10470  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
10471  {
10472  // uint 32
10473  oa->write_character(0xce);
10474  write_number(static_cast<uint32_t>(j.m_value.number_integer));
10475  }
10476  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
10477  {
10478  // uint 64
10479  oa->write_character(0xcf);
10480  write_number(static_cast<uint64_t>(j.m_value.number_integer));
10481  }
10482  break;
10483  }
10484 
10485  case value_t::number_float:
10486  {
10487  // float 64
10488  oa->write_character(0xcb);
10489  write_number(j.m_value.number_float);
10490  break;
10491  }
10492 
10493  case value_t::string:
10494  {
10495  // step 1: write control byte and the string length
10496  const auto N = j.m_value.string->size();
10497  if (N <= 31)
10498  {
10499  // fixstr
10500  write_number(static_cast<uint8_t>(0xa0 | N));
10501  }
10502  else if (N <= 255)
10503  {
10504  // str 8
10505  oa->write_character(0xd9);
10506  write_number(static_cast<uint8_t>(N));
10507  }
10508  else if (N <= 65535)
10509  {
10510  // str 16
10511  oa->write_character(0xda);
10512  write_number(static_cast<uint16_t>(N));
10513  }
10514  else if (N <= 4294967295)
10515  {
10516  // str 32
10517  oa->write_character(0xdb);
10518  write_number(static_cast<uint32_t>(N));
10519  }
10520 
10521  // step 2: write the string
10522  oa->write_characters(reinterpret_cast<const uint8_t*>(j.m_value.string->c_str()),
10523  j.m_value.string->size());
10524  break;
10525  }
10526 
10527  case value_t::array:
10528  {
10529  // step 1: write control byte and the array size
10530  const auto N = j.m_value.array->size();
10531  if (N <= 15)
10532  {
10533  // fixarray
10534  write_number(static_cast<uint8_t>(0x90 | N));
10535  }
10536  else if (N <= 0xffff)
10537  {
10538  // array 16
10539  oa->write_character(0xdc);
10540  write_number(static_cast<uint16_t>(N));
10541  }
10542  else if (N <= 0xffffffff)
10543  {
10544  // array 32
10545  oa->write_character(0xdd);
10546  write_number(static_cast<uint32_t>(N));
10547  }
10548 
10549  // step 2: write each element
10550  for (const auto& el : *j.m_value.array)
10551  {
10552  write_msgpack(el);
10553  }
10554  break;
10555  }
10556 
10557  case value_t::object:
10558  {
10559  // step 1: write control byte and the object size
10560  const auto N = j.m_value.object->size();
10561  if (N <= 15)
10562  {
10563  // fixmap
10564  write_number(static_cast<uint8_t>(0x80 | (N & 0xf)));
10565  }
10566  else if (N <= 65535)
10567  {
10568  // map 16
10569  oa->write_character(0xde);
10570  write_number(static_cast<uint16_t>(N));
10571  }
10572  else if (N <= 4294967295)
10573  {
10574  // map 32
10575  oa->write_character(0xdf);
10576  write_number(static_cast<uint32_t>(N));
10577  }
10578 
10579  // step 2: write each element
10580  for (const auto& el : *j.m_value.object)
10581  {
10582  write_msgpack(el.first);
10583  write_msgpack(el.second);
10584  }
10585  break;
10586  }
10587 
10588  default:
10589  {
10590  break;
10591  }
10592  }
10593  }
10594 
10595  private:
10596  /*
10597  @brief write a number to output input
10598 
10599  @param[in] n number of type @a T
10600  @tparam T the type of the number
10601 
10602  @note This function needs to respect the system's endianess, because
10603  bytes in CBOR and MessagePack are stored in network order (big
10604  endian) and therefore need reordering on little endian systems.
10605  */
10606  template<typename T>
10607  void write_number(T n)
10608  {
10609  // step 1: write number to array of length T
10610  std::array<uint8_t, sizeof(T)> vec;
10611  std::memcpy(vec.data(), &n, sizeof(T));
10612 
10613  // step 2: write array to output (with possible reordering)
10614  for (size_t i = 0; i < sizeof(T); ++i)
10615  {
10616  // reverse byte order prior to conversion if necessary
10617  if (is_little_endian)
10618  {
10619  oa->write_character(vec[sizeof(T) - i - 1]);
10620  }
10621  else
10622  {
10623  oa->write_character(vec[i]);
10624  }
10625  }
10626  }
10627 
10628  private:
10630  const bool is_little_endian = true;
10631 
10634  };
10635 
10636  public:
10719  static std::vector<uint8_t> to_cbor(const basic_json& j)
10720  {
10721  std::vector<uint8_t> result;
10723  bw.write_cbor(j);
10724  return result;
10725  }
10726 
10801  static std::vector<uint8_t> to_msgpack(const basic_json& j)
10802  {
10803  std::vector<uint8_t> result;
10805  bw.write_msgpack(j);
10806  return result;
10807  }
10808 
10896  static basic_json from_cbor(const std::vector<uint8_t>& v,
10897  const size_t start_index = 0)
10898  {
10899  binary_reader br(input_adapter::create(v.begin() + static_cast<difference_type>(start_index), v.end()));
10900  return br.parse_cbor();
10901  }
10902 
10903 
10971  static basic_json from_msgpack(const std::vector<uint8_t>& v,
10972  const size_t start_index = 0)
10973  {
10974  binary_reader br(input_adapter::create(v.begin() + static_cast<difference_type>(start_index), v.end()));
10975  return br.parse_msgpack();
10976  }
10977 
10979 
10981  // lexer and parser //
10983 
10984  private:
10990  class lexer
10991  {
10992  public:
10994  enum class token_type
10995  {
10996  uninitialized,
10997  literal_true,
10998  literal_false,
10999  literal_null,
11000  value_string,
11001  value_unsigned,
11002  value_integer,
11003  value_float,
11004  begin_array,
11005  begin_object,
11006  end_array,
11007  end_object,
11008  name_separator,
11009  value_separator,
11010  parse_error,
11011  end_of_input
11012  };
11013 
11015  static const char* token_type_name(const token_type t) noexcept
11016  {
11017  switch (t)
11018  {
11019  case token_type::uninitialized:
11020  return "<uninitialized>";
11021  case token_type::literal_true:
11022  return "true literal";
11023  case token_type::literal_false:
11024  return "false literal";
11025  case token_type::literal_null:
11026  return "null literal";
11027  case token_type::value_string:
11028  return "string literal";
11032  return "number literal";
11033  case token_type::begin_array:
11034  return "'['";
11035  case token_type::begin_object:
11036  return "'{'";
11037  case token_type::end_array:
11038  return "']'";
11039  case token_type::end_object:
11040  return "'}'";
11041  case token_type::name_separator:
11042  return "':'";
11043  case token_type::value_separator:
11044  return "','";
11045  case token_type::parse_error:
11046  return "<parse error>";
11047  case token_type::end_of_input:
11048  return "end of input";
11049  default:
11050  {
11051  // catch non-enum values
11052  return "unknown token"; // LCOV_EXCL_LINE
11053  }
11054  }
11055  }
11056 
11057  explicit lexer(input_adapter_t adapter)
11058  : ia(adapter), decimal_point_char(get_decimal_point())
11059  {}
11060 
11061  private:
11063  // locales
11065 
11067  static char get_decimal_point() noexcept
11068  {
11069  const auto loc = localeconv();
11070  assert(loc != nullptr);
11071  return (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
11072  }
11073 
11075  // scan functions
11077 
11085  {
11086  // this function only makes sense after reading `\u`
11087  assert(current == 'u');
11088  int codepoint = 0;
11089 
11090  // byte 1: \uXxxx
11091  switch (get())
11092  {
11093  case '0':
11094  break;
11095  case '1':
11096  codepoint += 0x1000;
11097  break;
11098  case '2':
11099  codepoint += 0x2000;
11100  break;
11101  case '3':
11102  codepoint += 0x3000;
11103  break;
11104  case '4':
11105  codepoint += 0x4000;
11106  break;
11107  case '5':
11108  codepoint += 0x5000;
11109  break;
11110  case '6':
11111  codepoint += 0x6000;
11112  break;
11113  case '7':
11114  codepoint += 0x7000;
11115  break;
11116  case '8':
11117  codepoint += 0x8000;
11118  break;
11119  case '9':
11120  codepoint += 0x9000;
11121  break;
11122  case 'A':
11123  case 'a':
11124  codepoint += 0xa000;
11125  break;
11126  case 'B':
11127  case 'b':
11128  codepoint += 0xb000;
11129  break;
11130  case 'C':
11131  case 'c':
11132  codepoint += 0xc000;
11133  break;
11134  case 'D':
11135  case 'd':
11136  codepoint += 0xd000;
11137  break;
11138  case 'E':
11139  case 'e':
11140  codepoint += 0xe000;
11141  break;
11142  case 'F':
11143  case 'f':
11144  codepoint += 0xf000;
11145  break;
11146  default:
11147  return -1;
11148  }
11149 
11150  // byte 2: \uxXxx
11151  switch (get())
11152  {
11153  case '0':
11154  break;
11155  case '1':
11156  codepoint += 0x0100;
11157  break;
11158  case '2':
11159  codepoint += 0x0200;
11160  break;
11161  case '3':
11162  codepoint += 0x0300;
11163  break;
11164  case '4':
11165  codepoint += 0x0400;
11166  break;
11167  case '5':
11168  codepoint += 0x0500;
11169  break;
11170  case '6':
11171  codepoint += 0x0600;
11172  break;
11173  case '7':
11174  codepoint += 0x0700;
11175  break;
11176  case '8':
11177  codepoint += 0x0800;
11178  break;
11179  case '9':
11180  codepoint += 0x0900;
11181  break;
11182  case 'A':
11183  case 'a':
11184  codepoint += 0x0a00;
11185  break;
11186  case 'B':
11187  case 'b':
11188  codepoint += 0x0b00;
11189  break;
11190  case 'C':
11191  case 'c':
11192  codepoint += 0x0c00;
11193  break;
11194  case 'D':
11195  case 'd':
11196  codepoint += 0x0d00;
11197  break;
11198  case 'E':
11199  case 'e':
11200  codepoint += 0x0e00;
11201  break;
11202  case 'F':
11203  case 'f':
11204  codepoint += 0x0f00;
11205  break;
11206  default:
11207  return -1;
11208  }
11209 
11210  // byte 3: \uxxXx
11211  switch (get())
11212  {
11213  case '0':
11214  break;
11215  case '1':
11216  codepoint += 0x0010;
11217  break;
11218  case '2':
11219  codepoint += 0x0020;
11220  break;
11221  case '3':
11222  codepoint += 0x0030;
11223  break;
11224  case '4':
11225  codepoint += 0x0040;
11226  break;
11227  case '5':
11228  codepoint += 0x0050;
11229  break;
11230  case '6':
11231  codepoint += 0x0060;
11232  break;
11233  case '7':
11234  codepoint += 0x0070;
11235  break;
11236  case '8':
11237  codepoint += 0x0080;
11238  break;
11239  case '9':
11240  codepoint += 0x0090;
11241  break;
11242  case 'A':
11243  case 'a':
11244  codepoint += 0x00a0;
11245  break;
11246  case 'B':
11247  case 'b':
11248  codepoint += 0x00b0;
11249  break;
11250  case 'C':
11251  case 'c':
11252  codepoint += 0x00c0;
11253  break;
11254  case 'D':
11255  case 'd':
11256  codepoint += 0x00d0;
11257  break;
11258  case 'E':
11259  case 'e':
11260  codepoint += 0x00e0;
11261  break;
11262  case 'F':
11263  case 'f':
11264  codepoint += 0x00f0;
11265  break;
11266  default:
11267  return -1;
11268  }
11269 
11270  // byte 4: \uxxxX
11271  switch (get())
11272  {
11273  case '0':
11274  break;
11275  case '1':
11276  codepoint += 0x0001;
11277  break;
11278  case '2':
11279  codepoint += 0x0002;
11280  break;
11281  case '3':
11282  codepoint += 0x0003;
11283  break;
11284  case '4':
11285  codepoint += 0x0004;
11286  break;
11287  case '5':
11288  codepoint += 0x0005;
11289  break;
11290  case '6':
11291  codepoint += 0x0006;
11292  break;
11293  case '7':
11294  codepoint += 0x0007;
11295  break;
11296  case '8':
11297  codepoint += 0x0008;
11298  break;
11299  case '9':
11300  codepoint += 0x0009;
11301  break;
11302  case 'A':
11303  case 'a':
11304  codepoint += 0x000a;
11305  break;
11306  case 'B':
11307  case 'b':
11308  codepoint += 0x000b;
11309  break;
11310  case 'C':
11311  case 'c':
11312  codepoint += 0x000c;
11313  break;
11314  case 'D':
11315  case 'd':
11316  codepoint += 0x000d;
11317  break;
11318  case 'E':
11319  case 'e':
11320  codepoint += 0x000e;
11321  break;
11322  case 'F':
11323  case 'f':
11324  codepoint += 0x000f;
11325  break;
11326  default:
11327  return -1;
11328  }
11329 
11330  return codepoint;
11331  }
11332 
11337  static std::string codepoint_to_string(int codepoint)
11338  {
11339  std::stringstream ss;
11340  ss << "U+" << std::setw(4) << std::uppercase << std::setfill('0') << std::hex << codepoint;
11341  return ss.str();
11342  }
11343 
11359  {
11360  // reset yytext (ignore opening quote)
11361  reset();
11362 
11363  // we entered the function by reading an open quote
11364  assert(current == '\"');
11365 
11366  while (true)
11367  {
11368  // get next character
11369  get();
11370 
11371  switch (current)
11372  {
11373  // end of file while parsing string
11374  case std::char_traits<char>::eof():
11375  {
11376  error_message = "invalid string: missing closing quote";
11377  return token_type::parse_error;
11378  }
11379 
11380  // closing quote
11381  case '\"':
11382  {
11383  // terminate yytext
11384  add('\0');
11385  --yylen;
11386  return token_type::value_string;
11387  }
11388 
11389  // escapes
11390  case '\\':
11391  {
11392  switch (get())
11393  {
11394  // quotation mark
11395  case '\"':
11396  add('\"');
11397  break;
11398  // reverse solidus
11399  case '\\':
11400  add('\\');
11401  break;
11402  // solidus
11403  case '/':
11404  add('/');
11405  break;
11406  // backspace
11407  case 'b':
11408  add('\b');
11409  break;
11410  // form feed
11411  case 'f':
11412  add('\f');
11413  break;
11414  // line feed
11415  case 'n':
11416  add('\n');
11417  break;
11418  // carriage return
11419  case 'r':
11420  add('\r');
11421  break;
11422  // tab
11423  case 't':
11424  add('\t');
11425  break;
11426 
11427  // unicode escapes
11428  case 'u':
11429  {
11430  int codepoint;
11431  int codepoint1 = get_codepoint();
11432 
11433  if (JSON_UNLIKELY(codepoint1 == -1))
11434  {
11435  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
11436  return token_type::parse_error;
11437  }
11438 
11439  // check if code point is a high surrogate
11440  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
11441  {
11442  // expect next \uxxxx entry
11443  if (JSON_LIKELY(get() == '\\' and get() == 'u'))
11444  {
11445  const int codepoint2 = get_codepoint();
11446 
11447  if (JSON_UNLIKELY(codepoint2 == -1))
11448  {
11449  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
11450  return token_type::parse_error;
11451  }
11452 
11453  // check if codepoint2 is a low surrogate
11454  if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
11455  {
11456  codepoint =
11457  // high surrogate occupies the most significant 22 bits
11458  (codepoint1 << 10)
11459  // low surrogate occupies the least significant 15 bits
11460  + codepoint2
11461  // there is still the 0xD800, 0xDC00 and 0x10000 noise
11462  // in the result so we have to subtract with:
11463  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
11464  - 0x35FDC00;
11465  }
11466  else
11467  {
11468  error_message = "invalid string: surrogate " + codepoint_to_string(codepoint1) + " must be followed by U+DC00..U+DFFF instead of " + codepoint_to_string(codepoint2);
11469  return token_type::parse_error;
11470  }
11471  }
11472  else
11473  {
11474  error_message = "invalid string: surrogate " + codepoint_to_string(codepoint1) + " must be followed by U+DC00..U+DFFF";
11475  return token_type::parse_error;
11476  }
11477  }
11478  else
11479  {
11480  if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
11481  {
11482  error_message = "invalid string: surrogate " + codepoint_to_string(codepoint1) + " must follow U+D800..U+DBFF";
11483  return token_type::parse_error;
11484  }
11485 
11486  // only work with first code point
11487  codepoint = codepoint1;
11488  }
11489 
11490  // result of the above calculation yields a proper codepoint
11491  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
11492 
11493  // translate code point to bytes
11494  if (codepoint < 0x80)
11495  {
11496  // 1-byte characters: 0xxxxxxx (ASCII)
11497  add(codepoint);
11498  }
11499  else if (codepoint <= 0x7ff)
11500  {
11501  // 2-byte characters: 110xxxxx 10xxxxxx
11502  add(0xC0 | (codepoint >> 6));
11503  add(0x80 | (codepoint & 0x3F));
11504  }
11505  else if (codepoint <= 0xffff)
11506  {
11507  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
11508  add(0xE0 | (codepoint >> 12));
11509  add(0x80 | ((codepoint >> 6) & 0x3F));
11510  add(0x80 | (codepoint & 0x3F));
11511  }
11512  else
11513  {
11514  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
11515  add(0xF0 | (codepoint >> 18));
11516  add(0x80 | ((codepoint >> 12) & 0x3F));
11517  add(0x80 | ((codepoint >> 6) & 0x3F));
11518  add(0x80 | (codepoint & 0x3F));
11519  }
11520 
11521  break;
11522  }
11523 
11524  // other characters after escape
11525  default:
11526  error_message = "invalid string: forbidden character after backslash";
11527  return token_type::parse_error;
11528  }
11529 
11530  break;
11531  }
11532 
11533  // invalid control characters
11534  case 0x00:
11535  case 0x01:
11536  case 0x02:
11537  case 0x03:
11538  case 0x04:
11539  case 0x05:
11540  case 0x06:
11541  case 0x07:
11542  case 0x08:
11543  case 0x09:
11544  case 0x0a:
11545  case 0x0b:
11546  case 0x0c:
11547  case 0x0d:
11548  case 0x0e:
11549  case 0x0f:
11550  case 0x10:
11551  case 0x11:
11552  case 0x12:
11553  case 0x13:
11554  case 0x14:
11555  case 0x15:
11556  case 0x16:
11557  case 0x17:
11558  case 0x18:
11559  case 0x19:
11560  case 0x1a:
11561  case 0x1b:
11562  case 0x1c:
11563  case 0x1d:
11564  case 0x1e:
11565  case 0x1f:
11566  {
11567  error_message = "invalid string: control character " + codepoint_to_string(current) + " must be escaped";
11568  return token_type::parse_error;
11569  }
11570 
11571  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
11572  case 0x20:
11573  case 0x21:
11574  case 0x23:
11575  case 0x24:
11576  case 0x25:
11577  case 0x26:
11578  case 0x27:
11579  case 0x28:
11580  case 0x29:
11581  case 0x2a:
11582  case 0x2b:
11583  case 0x2c:
11584  case 0x2d:
11585  case 0x2e:
11586  case 0x2f:
11587  case 0x30:
11588  case 0x31:
11589  case 0x32:
11590  case 0x33:
11591  case 0x34:
11592  case 0x35:
11593  case 0x36:
11594  case 0x37:
11595  case 0x38:
11596  case 0x39:
11597  case 0x3a:
11598  case 0x3b:
11599  case 0x3c:
11600  case 0x3d:
11601  case 0x3e:
11602  case 0x3f:
11603  case 0x40:
11604  case 0x41:
11605  case 0x42:
11606  case 0x43:
11607  case 0x44:
11608  case 0x45:
11609  case 0x46:
11610  case 0x47:
11611  case 0x48:
11612  case 0x49:
11613  case 0x4a:
11614  case 0x4b:
11615  case 0x4c:
11616  case 0x4d:
11617  case 0x4e:
11618  case 0x4f:
11619  case 0x50:
11620  case 0x51:
11621  case 0x52:
11622  case 0x53:
11623  case 0x54:
11624  case 0x55:
11625  case 0x56:
11626  case 0x57:
11627  case 0x58:
11628  case 0x59:
11629  case 0x5a:
11630  case 0x5b:
11631  case 0x5d:
11632  case 0x5e:
11633  case 0x5f:
11634  case 0x60:
11635  case 0x61:
11636  case 0x62:
11637  case 0x63:
11638  case 0x64:
11639  case 0x65:
11640  case 0x66:
11641  case 0x67:
11642  case 0x68:
11643  case 0x69:
11644  case 0x6a:
11645  case 0x6b:
11646  case 0x6c:
11647  case 0x6d:
11648  case 0x6e:
11649  case 0x6f:
11650  case 0x70:
11651  case 0x71:
11652  case 0x72:
11653  case 0x73:
11654  case 0x74:
11655  case 0x75:
11656  case 0x76:
11657  case 0x77:
11658  case 0x78:
11659  case 0x79:
11660  case 0x7a:
11661  case 0x7b:
11662  case 0x7c:
11663  case 0x7d:
11664  case 0x7e:
11665  case 0x7f:
11666  {
11667  add(current);
11668  break;
11669  }
11670 
11671  // U+0080..U+07FF: bytes C2..DF 80..BF
11672  case 0xc2:
11673  case 0xc3:
11674  case 0xc4:
11675  case 0xc5:
11676  case 0xc6:
11677  case 0xc7:
11678  case 0xc8:
11679  case 0xc9:
11680  case 0xca:
11681  case 0xcb:
11682  case 0xcc:
11683  case 0xcd:
11684  case 0xce:
11685  case 0xcf:
11686  case 0xd0:
11687  case 0xd1:
11688  case 0xd2:
11689  case 0xd3:
11690  case 0xd4:
11691  case 0xd5:
11692  case 0xd6:
11693  case 0xd7:
11694  case 0xd8:
11695  case 0xd9:
11696  case 0xda:
11697  case 0xdb:
11698  case 0xdc:
11699  case 0xdd:
11700  case 0xde:
11701  case 0xdf:
11702  {
11703  add(current);
11704  get();
11705  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11706  {
11707  add(current);
11708  continue;
11709  }
11710 
11711  error_message = "invalid string: ill-formed UTF-8 byte";
11712  return token_type::parse_error;
11713  }
11714 
11715  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
11716  case 0xe0:
11717  {
11718  add(current);
11719  get();
11720  if (JSON_LIKELY(0xa0 <= current and current <= 0xbf))
11721  {
11722  add(current);
11723  get();
11724  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11725  {
11726  add(current);
11727  continue;
11728  }
11729  }
11730 
11731  error_message = "invalid string: ill-formed UTF-8 byte";
11732  return token_type::parse_error;
11733  }
11734 
11735  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
11736  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
11737  case 0xe1:
11738  case 0xe2:
11739  case 0xe3:
11740  case 0xe4:
11741  case 0xe5:
11742  case 0xe6:
11743  case 0xe7:
11744  case 0xe8:
11745  case 0xe9:
11746  case 0xea:
11747  case 0xeb:
11748  case 0xec:
11749  case 0xee:
11750  case 0xef:
11751  {
11752  add(current);
11753  get();
11754  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11755  {
11756  add(current);
11757  get();
11758  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11759  {
11760  add(current);
11761  continue;
11762  }
11763  }
11764 
11765  error_message = "invalid string: ill-formed UTF-8 byte";
11766  return token_type::parse_error;
11767  }
11768 
11769  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
11770  case 0xed:
11771  {
11772  add(current);
11773  get();
11774  if (JSON_LIKELY(0x80 <= current and current <= 0x9f))
11775  {
11776  add(current);
11777  get();
11778  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11779  {
11780  add(current);
11781  continue;
11782  }
11783  }
11784 
11785  error_message = "invalid string: ill-formed UTF-8 byte";
11786  return token_type::parse_error;
11787  }
11788 
11789  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
11790  case 0xf0:
11791  {
11792  add(current);
11793  get();
11794  if (JSON_LIKELY(0x90 <= current and current <= 0xbf))
11795  {
11796  add(current);
11797  get();
11798  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11799  {
11800  add(current);
11801  get();
11802  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11803  {
11804  add(current);
11805  continue;
11806  }
11807  }
11808  }
11809 
11810  error_message = "invalid string: ill-formed UTF-8 byte";
11811  return token_type::parse_error;
11812  }
11813 
11814  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
11815  case 0xf1:
11816  case 0xf2:
11817  case 0xf3:
11818  {
11819  add(current);
11820  get();
11821  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11822  {
11823  add(current);
11824  get();
11825  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11826  {
11827  add(current);
11828  get();
11829  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11830  {
11831  add(current);
11832  continue;
11833  }
11834  }
11835  }
11836 
11837  error_message = "invalid string: ill-formed UTF-8 byte";
11838  return token_type::parse_error;
11839  }
11840 
11841  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
11842  case 0xf4:
11843  {
11844  add(current);
11845  get();
11846  if (JSON_LIKELY(0x80 <= current and current <= 0x8f))
11847  {
11848  add(current);
11849  get();
11850  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11851  {
11852  add(current);
11853  get();
11854  if (JSON_LIKELY(0x80 <= current and current <= 0xbf))
11855  {
11856  add(current);
11857  continue;
11858  }
11859  }
11860  }
11861 
11862  error_message = "invalid string: ill-formed UTF-8 byte";
11863  return token_type::parse_error;
11864  }
11865 
11866  // remaining bytes (80..C1 and F5..FF) are ill-formed
11867  default:
11868  {
11869  error_message = "invalid string: ill-formed UTF-8 byte";
11870  return token_type::parse_error;
11871  }
11872  }
11873  }
11874  }
11875 
11876  static void strtof(float& f, const char* str, char** endptr) noexcept
11877  {
11878  f = std::strtof(str, endptr);
11879  }
11880 
11881  static void strtof(double& f, const char* str, char** endptr) noexcept
11882  {
11883  f = std::strtod(str, endptr);
11884  }
11885 
11886  static void strtof(long double& f, const char* str, char** endptr) noexcept
11887  {
11888  f = std::strtold(str, endptr);
11889  }
11890 
11933  {
11934  // reset yytext to store the number's bytes
11935  reset();
11936 
11937  // the type of the parsed number; initially set to unsigned; will be
11938  // changed if minus sign, decimal point or exponent is read
11939  token_type number_type = token_type::value_unsigned;
11940 
11941  // state (init): we just found out we need to scan a number
11942  switch (current)
11943  {
11944  case '-':
11945  {
11946  add(current);
11947  goto scan_number_minus;
11948  }
11949 
11950  case '0':
11951  {
11952  add(current);
11953  goto scan_number_zero;
11954  }
11955 
11956  case '1':
11957  case '2':
11958  case '3':
11959  case '4':
11960  case '5':
11961  case '6':
11962  case '7':
11963  case '8':
11964  case '9':
11965  {
11966  add(current);
11967  goto scan_number_any1;
11968  }
11969 
11970  default:
11971  {
11972  // all other characters are rejected outside scan_number()
11973  assert(false); // LCOV_EXCL_LINE
11974  }
11975  }
11976 
11977 scan_number_minus:
11978  // state: we just parsed a leading minus sign
11979  number_type = token_type::value_integer;
11980  switch (get())
11981  {
11982  case '0':
11983  {
11984  add(current);
11985  goto scan_number_zero;
11986  }
11987 
11988  case '1':
11989  case '2':
11990  case '3':
11991  case '4':
11992  case '5':
11993  case '6':
11994  case '7':
11995  case '8':
11996  case '9':
11997  {
11998  add(current);
11999  goto scan_number_any1;
12000  }
12001 
12002  default:
12003  {
12004  error_message = "invalid number; expected digit after '-'";
12005  return token_type::parse_error;
12006  }
12007  }
12008 
12009 scan_number_zero:
12010  // state: we just parse a zero (maybe with a leading minus sign)
12011  switch (get())
12012  {
12013  case '.':
12014  {
12015  add(decimal_point_char);
12016  goto scan_number_decimal1;
12017  }
12018 
12019  case 'e':
12020  case 'E':
12021  {
12022  add(current);
12023  goto scan_number_exponent;
12024  }
12025 
12026  default:
12027  {
12028  goto scan_number_done;
12029  }
12030  }
12031 
12032 scan_number_any1:
12033  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
12034  switch (get())
12035  {
12036  case '0':
12037  case '1':
12038  case '2':
12039  case '3':
12040  case '4':
12041  case '5':
12042  case '6':
12043  case '7':
12044  case '8':
12045  case '9':
12046  {
12047  add(current);
12048  goto scan_number_any1;
12049  }
12050 
12051  case '.':
12052  {
12053  add(decimal_point_char);
12054  goto scan_number_decimal1;
12055  }
12056 
12057  case 'e':
12058  case 'E':
12059  {
12060  add(current);
12061  goto scan_number_exponent;
12062  }
12063 
12064  default:
12065  {
12066  goto scan_number_done;
12067  }
12068  }
12069 
12070 scan_number_decimal1:
12071  // state: we just parsed a decimal point
12072  number_type = token_type::value_float;
12073  switch (get())
12074  {
12075  case '0':
12076  case '1':
12077  case '2':
12078  case '3':
12079  case '4':
12080  case '5':
12081  case '6':
12082  case '7':
12083  case '8':
12084  case '9':
12085  {
12086  add(current);
12087  goto scan_number_decimal2;
12088  }
12089 
12090  default:
12091  {
12092  error_message = "invalid number; expected digit after '.'";
12093  return token_type::parse_error;
12094  }
12095  }
12096 
12097 scan_number_decimal2:
12098  // we just parsed at least one number after a decimal point
12099  switch (get())
12100  {
12101  case '0':
12102  case '1':
12103  case '2':
12104  case '3':
12105  case '4':
12106  case '5':
12107  case '6':
12108  case '7':
12109  case '8':
12110  case '9':
12111  {
12112  add(current);
12113  goto scan_number_decimal2;
12114  }
12115 
12116  case 'e':
12117  case 'E':
12118  {
12119  add(current);
12120  goto scan_number_exponent;
12121  }
12122 
12123  default:
12124  {
12125  goto scan_number_done;
12126  }
12127  }
12128 
12129 scan_number_exponent:
12130  // we just parsed an exponent
12131  number_type = token_type::value_float;
12132  switch (get())
12133  {
12134  case '+':
12135  case '-':
12136  {
12137  add(current);
12138  goto scan_number_sign;
12139  }
12140 
12141  case '0':
12142  case '1':
12143  case '2':
12144  case '3':
12145  case '4':
12146  case '5':
12147  case '6':
12148  case '7':
12149  case '8':
12150  case '9':
12151  {
12152  add(current);
12153  goto scan_number_any2;
12154  }
12155 
12156  default:
12157  {
12158  error_message = "invalid number; expected '+', '-', or digit after exponent";
12159  return token_type::parse_error;
12160  }
12161  }
12162 
12163 scan_number_sign:
12164  // we just parsed an exponent sign
12165  switch (get())
12166  {
12167  case '0':
12168  case '1':
12169  case '2':
12170  case '3':
12171  case '4':
12172  case '5':
12173  case '6':
12174  case '7':
12175  case '8':
12176  case '9':
12177  {
12178  add(current);
12179  goto scan_number_any2;
12180  }
12181 
12182  default:
12183  {
12184  error_message = "invalid number; expected digit after exponent sign";
12185  return token_type::parse_error;
12186  }
12187  }
12188 
12189 scan_number_any2:
12190  // we just parsed a number after the exponent or exponent sign
12191  switch (get())
12192  {
12193  case '0':
12194  case '1':
12195  case '2':
12196  case '3':
12197  case '4':
12198  case '5':
12199  case '6':
12200  case '7':
12201  case '8':
12202  case '9':
12203  {
12204  add(current);
12205  goto scan_number_any2;
12206  }
12207 
12208  default:
12209  {
12210  goto scan_number_done;
12211  }
12212  }
12213 
12214 scan_number_done:
12215  // unget the character after the number (we only read it to know
12216  // that we are done scanning a number)
12217  --chars_read;
12218  next_unget = true;
12219 
12220  // terminate token
12221  add('\0');
12222  --yylen;
12223 
12224  // try to parse integers first and fall back to floats
12225  if (number_type == token_type::value_unsigned)
12226  {
12227  char* endptr = nullptr;
12228  errno = 0;
12229  const auto x = std::strtoull(yytext.data(), &endptr, 10);
12230 
12231  // we checked the number format before
12232  assert(endptr == yytext.data() + yylen);
12233 
12234  if (errno == 0)
12235  {
12236  value_unsigned = static_cast<number_unsigned_t>(x);
12237  if (value_unsigned == x)
12238  {
12239  return token_type::value_unsigned;
12240  }
12241  }
12242  }
12243  else if (number_type == token_type::value_integer)
12244  {
12245  char* endptr = nullptr;
12246  errno = 0;
12247  const auto x = std::strtoll(yytext.data(), &endptr, 10);
12248 
12249  // we checked the number format before
12250  assert(endptr == yytext.data() + yylen);
12251 
12252  if (errno == 0)
12253  {
12254  value_integer = static_cast<number_integer_t>(x);
12255  if (value_integer == x)
12256  {
12257  return token_type::value_integer;
12258  }
12259  }
12260  }
12261 
12262  // this code is reached if we parse a floating-point number or if
12263  // an integer conversion above failed
12264  strtof(value_float, yytext.data(), nullptr);
12265  return token_type::value_float;
12266  }
12267 
12269  {
12270  assert(current == 't');
12271  if (JSON_LIKELY((get() == 'r' and get() == 'u' and get() == 'e')))
12272  {
12273  return token_type::literal_true;
12274  }
12275 
12276  error_message = "invalid literal; expected 'true'";
12277  return token_type::parse_error;
12278  }
12279 
12281  {
12282  assert(current == 'f');
12283  if (JSON_LIKELY((get() == 'a' and get() == 'l' and get() == 's' and get() == 'e')))
12284  {
12285  return token_type::literal_false;
12286  }
12287 
12288  error_message = "invalid literal; expected 'false'";
12289  return token_type::parse_error;
12290  }
12291 
12293  {
12294  assert(current == 'n');
12295  if (JSON_LIKELY((get() == 'u' and get() == 'l' and get() == 'l')))
12296  {
12297  return token_type::literal_null;
12298  }
12299 
12300  error_message = "invalid literal; expected 'null'";
12301  return token_type::parse_error;
12302  }
12303 
12305  // input management
12307 
12309  void reset() noexcept
12310  {
12311  yylen = 0;
12312  start_pos = chars_read - 1;
12313  }
12314 
12316  int get()
12317  {
12318  ++chars_read;
12319  return next_unget
12320  ? (next_unget = false, current)
12321  : (current = ia->get_character());
12322  }
12323 
12325  void add(int c)
12326  {
12327  // resize yytext if necessary; this condition is deemed unlikely,
12328  // because we start with a 1024-byte buffer
12329  if (JSON_UNLIKELY((yylen + 1 > yytext.capacity())))
12330  {
12331  yytext.resize(2 * yytext.capacity(), '\0');
12332  }
12333  yytext[yylen++] = static_cast<char>(c);
12334  }
12335 
12336  public:
12338  // value getters
12340 
12342  constexpr number_integer_t get_number_integer() const noexcept
12343  {
12344  return value_integer;
12345  }
12346 
12348  constexpr number_unsigned_t get_number_unsigned() const noexcept
12349  {
12350  return value_unsigned;
12351  }
12352 
12354  constexpr number_float_t get_number_float() const noexcept
12355  {
12356  return value_float;
12357  }
12358 
12360  const std::string get_string()
12361  {
12362  // yytext cannot be returned as char*, because it may contain a
12363  // null byte (parsed as "\u0000")
12364  return std::string(yytext.data(), yylen);
12365  }
12366 
12368  // diagnostics
12370 
12372  constexpr size_t get_position() const noexcept
12373  {
12374  return chars_read;
12375  }
12376 
12378  std::string get_token_string() const
12379  {
12380  // get the raw byte sequence of the last token
12381  std::string s = ia->read(start_pos, chars_read - start_pos);
12382 
12383  // escape control characters
12384  std::string result;
12385  for (auto c : s)
12386  {
12387  if (c == '\0' or c == std::char_traits<char>::eof())
12388  {
12389  // ignore EOF
12390  continue;
12391  }
12392  else if ('\x00' <= c and c <= '\x1f')
12393  {
12394  // escape control characters
12395  result += "<" + codepoint_to_string(c) + ">";
12396  }
12397  else
12398  {
12399  // add character as is
12400  result.append(1, c);
12401  }
12402  }
12403 
12404  return result;
12405  }
12406 
12408  const std::string& get_error_message() const noexcept
12409  {
12410  return error_message;
12411  }
12412 
12414  // actual scanner
12416 
12418  {
12419  // read next character and ignore whitespace
12420  do
12421  {
12422  get();
12423  }
12424  while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
12425 
12426  switch (current)
12427  {
12428  // structural characters
12429  case '[':
12430  return token_type::begin_array;
12431  case ']':
12432  return token_type::end_array;
12433  case '{':
12434  return token_type::begin_object;
12435  case '}':
12436  return token_type::end_object;
12437  case ':':
12438  return token_type::name_separator;
12439  case ',':
12440  return token_type::value_separator;
12441 
12442  // literals
12443  case 't':
12444  return scan_true();
12445  case 'f':
12446  return scan_false();
12447  case 'n':
12448  return scan_null();
12449 
12450  // string
12451  case '\"':
12452  return scan_string();
12453 
12454  // number
12455  case '-':
12456  case '0':
12457  case '1':
12458  case '2':
12459  case '3':
12460  case '4':
12461  case '5':
12462  case '6':
12463  case '7':
12464  case '8':
12465  case '9':
12466  return scan_number();
12467 
12468  // end of input (the null byte is needed when parsing from
12469  // string literals)
12470  case '\0':
12471  case std::char_traits<char>::eof():
12472  return token_type::end_of_input;
12473 
12474  // error
12475  default:
12476  error_message = "invalid literal";
12477  return token_type::parse_error;
12478  }
12479  }
12480 
12481  private:
12483  input_adapter_t ia = nullptr;
12484 
12486  int current = std::char_traits<char>::eof();
12487 
12489  bool next_unget = false;
12490 
12492  size_t chars_read = 0;
12494  size_t start_pos = 0;
12495 
12497  std::vector<char> yytext = std::vector<char>(1024, '\0');
12499  size_t yylen = 0;
12500 
12502  std::string error_message = "";
12503 
12504  // number values
12505  number_integer_t value_integer = 0;
12506  number_unsigned_t value_unsigned = 0;
12507  number_float_t value_float = 0;
12508 
12510  const char decimal_point_char = '.';
12511  };
12512 
12518  class parser
12519  {
12520  public:
12522  explicit parser(input_adapter_t adapter,
12523  const parser_callback_t cb = nullptr)
12524  : callback(cb), m_lexer(adapter)
12525  {}
12526 
12537  basic_json parse(const bool strict = true)
12538  {
12539  // read first token
12540  get_token();
12541 
12542  basic_json result = parse_internal(true);
12543  result.assert_invariant();
12544 
12545  if (strict)
12546  {
12547  get_token();
12549  }
12550 
12551  // return parser result and replace it with null in case the
12552  // top-level value was discarded by the callback function
12553  return result.is_discarded() ? basic_json() : std::move(result);
12554  }
12555 
12562  bool accept(const bool strict = true)
12563  {
12564  // read first token
12565  get_token();
12566 
12567  if (not accept_internal())
12568  {
12569  return false;
12570  }
12571 
12572  if (strict and get_token() != lexer::token_type::end_of_input)
12573  {
12574  return false;
12575  }
12576 
12577  return true;
12578  }
12579 
12580  private:
12588  {
12589  auto result = basic_json(value_t::discarded);
12590 
12591  switch (last_token)
12592  {
12594  {
12595  if (keep and (not callback
12596  or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
12597  {
12598  // explicitly set result to object to cope with {}
12599  result.m_type = value_t::object;
12600  result.m_value = value_t::object;
12601  }
12602 
12603  // read next token
12604  get_token();
12605 
12606  // closing } -> we are done
12607  if (last_token == lexer::token_type::end_object)
12608  {
12609  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12610  {
12611  result = basic_json(value_t::discarded);
12612  }
12613  return result;
12614  }
12615 
12616  // parse values
12617  while (true)
12618  {
12619  // store key
12621  const auto key = m_lexer.get_string();
12622 
12623  bool keep_tag = false;
12624  if (keep)
12625  {
12626  if (callback)
12627  {
12628  basic_json k(key);
12629  keep_tag = callback(depth, parse_event_t::key, k);
12630  }
12631  else
12632  {
12633  keep_tag = true;
12634  }
12635  }
12636 
12637  // parse separator (:)
12638  get_token();
12640 
12641  // parse and add value
12642  get_token();
12643  auto value = parse_internal(keep);
12644  if (keep and keep_tag and not value.is_discarded())
12645  {
12646  result[key] = std::move(value);
12647  }
12648 
12649  // comma -> next value
12650  get_token();
12651  if (last_token == lexer::token_type::value_separator)
12652  {
12653  get_token();
12654  continue;
12655  }
12656 
12657  // closing }
12659  break;
12660  }
12661 
12662  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12663  {
12664  result = basic_json(value_t::discarded);
12665  }
12666 
12667  return result;
12668  }
12669 
12671  {
12672  if (keep and (not callback
12673  or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
12674  {
12675  // explicitly set result to object to cope with []
12676  result.m_type = value_t::array;
12677  result.m_value = value_t::array;
12678  }
12679 
12680  // read next token
12681  get_token();
12682 
12683  // closing ] -> we are done
12684  if (last_token == lexer::token_type::end_array)
12685  {
12686  if (callback and not callback(--depth, parse_event_t::array_end, result))
12687  {
12688  result = basic_json(value_t::discarded);
12689  }
12690  return result;
12691  }
12692 
12693  // parse values
12694  while (true)
12695  {
12696  // parse value
12697  auto value = parse_internal(keep);
12698  if (keep and not value.is_discarded())
12699  {
12700  result.push_back(std::move(value));
12701  }
12702 
12703  // comma -> next value
12704  get_token();
12705  if (last_token == lexer::token_type::value_separator)
12706  {
12707  get_token();
12708  continue;
12709  }
12710 
12711  // closing ]
12713  break;
12714  }
12715 
12716  if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
12717  {
12718  result = basic_json(value_t::discarded);
12719  }
12720 
12721  return result;
12722  }
12723 
12725  {
12726  result.m_type = value_t::null;
12727  break;
12728  }
12729 
12731  {
12732  result = basic_json(m_lexer.get_string());
12733  break;
12734  }
12735 
12737  {
12738  result.m_type = value_t::boolean;
12739  result.m_value = true;
12740  break;
12741  }
12742 
12744  {
12745  result.m_type = value_t::boolean;
12746  result.m_value = false;
12747  break;
12748  }
12749 
12751  {
12752  result.m_type = value_t::number_unsigned;
12753  result.m_value = m_lexer.get_number_unsigned();
12754  break;
12755  }
12756 
12758  {
12759  result.m_type = value_t::number_integer;
12760  result.m_value = m_lexer.get_number_integer();
12761  break;
12762  }
12763 
12765  {
12766  result.m_type = value_t::number_float;
12767  result.m_value = m_lexer.get_number_float();
12768 
12769  // throw in case of infinity or NAN
12770  if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
12771  {
12772  JSON_THROW(out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
12773  }
12774 
12775  break;
12776  }
12777 
12778  default:
12779  {
12780  // the last token was unexpected
12781  unexpect(last_token);
12782  }
12783  }
12784 
12785  if (keep and callback and not callback(depth, parse_event_t::value, result))
12786  {
12787  result = basic_json(value_t::discarded);
12788  }
12789  return result;
12790  }
12791 
12804  {
12805  switch (last_token)
12806  {
12808  {
12809  // read next token
12810  get_token();
12811 
12812  // closing } -> we are done
12813  if (last_token == lexer::token_type::end_object)
12814  {
12815  return true;
12816  }
12817 
12818  // parse values
12819  while (true)
12820  {
12821  // parse key
12822  if (last_token != lexer::token_type::value_string)
12823  {
12824  return false;
12825  }
12826 
12827  // parse separator (:)
12828  get_token();
12829  if (last_token != lexer::token_type::name_separator)
12830  {
12831  return false;
12832  }
12833 
12834  // parse value
12835  get_token();
12836  if (not accept_internal())
12837  {
12838  return false;
12839  }
12840 
12841  // comma -> next value
12842  get_token();
12843  if (last_token == lexer::token_type::value_separator)
12844  {
12845  get_token();
12846  continue;
12847  }
12848 
12849  // closing }
12850  if (last_token != lexer::token_type::end_object)
12851  {
12852  return false;
12853  }
12854 
12855  return true;
12856  }
12857  }
12858 
12860  {
12861  // read next token
12862  get_token();
12863 
12864  // closing ] -> we are done
12865  if (last_token == lexer::token_type::end_array)
12866  {
12867  return true;
12868  }
12869 
12870  // parse values
12871  while (true)
12872  {
12873  // parse value
12874  if (not accept_internal())
12875  {
12876  return false;
12877  }
12878 
12879  // comma -> next value
12880  get_token();
12881  if (last_token == lexer::token_type::value_separator)
12882  {
12883  get_token();
12884  continue;
12885  }
12886 
12887  // closing ]
12888  if (last_token != lexer::token_type::end_array)
12889  {
12890  return false;
12891  }
12892 
12893  return true;
12894  }
12895  }
12896 
12904  {
12905  return true;
12906  }
12907 
12908  default:
12909  {
12910  // the last token was unexpected
12911  return false;
12912  }
12913  }
12914  }
12915 
12918  {
12919  last_token = m_lexer.scan();
12920  return last_token;
12921  }
12922 
12926  void expect(typename lexer::token_type t) const
12927  {
12928  if (JSON_UNLIKELY(t != last_token))
12929  {
12930  std::string error_msg = "syntax error - ";
12931  if (last_token == lexer::token_type::parse_error)
12932  {
12933  error_msg += m_lexer.get_error_message() + "; last read: '" + m_lexer.get_token_string() + "'";
12934  }
12935  else
12936  {
12937  error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
12938  }
12939 
12940  error_msg += "; expected " + std::string(lexer::token_type_name(t));
12941  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12942  }
12943  }
12944 
12948  void unexpect(typename lexer::token_type t) const
12949  {
12950  if (JSON_UNLIKELY(t == last_token))
12951  {
12952  std::string error_msg = "syntax error - ";
12953  if (last_token == lexer::token_type::parse_error)
12954  {
12955  error_msg += m_lexer.get_error_message() + "; last read '" + m_lexer.get_token_string() + "'";
12956  }
12957  else
12958  {
12959  error_msg += "unexpected " + std::string(lexer::token_type_name(last_token));
12960  }
12961 
12962  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12963  }
12964  }
12965 
12966  private:
12968  int depth = 0;
12970  const parser_callback_t callback = nullptr;
12975  };
12976 
12977  public:
12990  {
12992  friend class basic_json;
12993 
12994  public:
13017  explicit json_pointer(const std::string& s = "")
13018  : reference_tokens(split(s))
13019  {}
13020 
13036  std::string to_string() const noexcept
13037  {
13038  return std::accumulate(reference_tokens.begin(),
13039  reference_tokens.end(), std::string{},
13040  [](const std::string & a, const std::string & b)
13041  {
13042  return a + "/" + escape(b);
13043  });
13044  }
13045 
13047  operator std::string() const
13048  {
13049  return to_string();
13050  }
13051 
13052  private:
13057  std::string pop_back()
13058  {
13059  if (is_root())
13060  {
13061  JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
13062  }
13063 
13064  auto last = reference_tokens.back();
13065  reference_tokens.pop_back();
13066  return last;
13067  }
13068 
13070  bool is_root() const
13071  {
13072  return reference_tokens.empty();
13073  }
13074 
13076  {
13077  if (is_root())
13078  {
13079  JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
13080  }
13081 
13082  json_pointer result = *this;
13083  result.reference_tokens = {reference_tokens[0]};
13084  return result;
13085  }
13086 
13096  {
13097  pointer result = &j;
13098 
13099  // in case no reference tokens exist, return a reference to the
13100  // JSON value j which will be overwritten by a primitive value
13101  for (const auto& reference_token : reference_tokens)
13102  {
13103  switch (result->m_type)
13104  {
13105  case value_t::null:
13106  {
13107  if (reference_token == "0")
13108  {
13109  // start a new array if reference token is 0
13110  result = &result->operator[](0);
13111  }
13112  else
13113  {
13114  // start a new object otherwise
13115  result = &result->operator[](reference_token);
13116  }
13117  break;
13118  }
13119 
13120  case value_t::object:
13121  {
13122  // create an entry in the object
13123  result = &result->operator[](reference_token);
13124  break;
13125  }
13126 
13127  case value_t::array:
13128  {
13129  // create an entry in the array
13130  JSON_TRY
13131  {
13132  result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
13133  }
13134  JSON_CATCH (std::invalid_argument&)
13135  {
13136  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13137  }
13138  break;
13139  }
13140 
13141  /*
13142  The following code is only reached if there exists a
13143  reference token _and_ the current value is primitive. In
13144  this case, we have an error situation, because primitive
13145  values may only occur as single value; that is, with an
13146  empty list of reference tokens.
13147  */
13148  default:
13149  {
13150  JSON_THROW(type_error::create(313, "invalid value to unflatten"));
13151  }
13152  }
13153  }
13154 
13155  return *result;
13156  }
13157 
13178  {
13179  for (const auto& reference_token : reference_tokens)
13180  {
13181  // convert null values to arrays or objects before continuing
13182  if (ptr->m_type == value_t::null)
13183  {
13184  // check if reference token is a number
13185  const bool nums = std::all_of(reference_token.begin(),
13186  reference_token.end(),
13187  [](const char x)
13188  {
13189  return (x >= '0' and x <= '9');
13190  });
13191 
13192  // change value to array for numbers or "-" or to object
13193  // otherwise
13194  if (nums or reference_token == "-")
13195  {
13196  *ptr = value_t::array;
13197  }
13198  else
13199  {
13200  *ptr = value_t::object;
13201  }
13202  }
13203 
13204  switch (ptr->m_type)
13205  {
13206  case value_t::object:
13207  {
13208  // use unchecked object access
13209  ptr = &ptr->operator[](reference_token);
13210  break;
13211  }
13212 
13213  case value_t::array:
13214  {
13215  // error condition (cf. RFC 6901, Sect. 4)
13216  if (reference_token.size() > 1 and reference_token[0] == '0')
13217  {
13218  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
13219  }
13220 
13221  if (reference_token == "-")
13222  {
13223  // explicitly treat "-" as index beyond the end
13224  ptr = &ptr->operator[](ptr->m_value.array->size());
13225  }
13226  else
13227  {
13228  // convert array index to number; unchecked access
13229  JSON_TRY
13230  {
13231  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
13232  }
13233  JSON_CATCH (std::invalid_argument&)
13234  {
13235  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13236  }
13237  }
13238  break;
13239  }
13240 
13241  default:
13242  {
13243  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13244  }
13245  }
13246  }
13247 
13248  return *ptr;
13249  }
13250 
13258  {
13259  for (const auto& reference_token : reference_tokens)
13260  {
13261  switch (ptr->m_type)
13262  {
13263  case value_t::object:
13264  {
13265  // note: at performs range check
13266  ptr = &ptr->at(reference_token);
13267  break;
13268  }
13269 
13270  case value_t::array:
13271  {
13272  if (reference_token == "-")
13273  {
13274  // "-" always fails the range check
13275  JSON_THROW(out_of_range::create(402, "array index '-' (" +
13276  std::to_string(ptr->m_value.array->size()) +
13277  ") is out of range"));
13278  }
13279 
13280  // error condition (cf. RFC 6901, Sect. 4)
13281  if (reference_token.size() > 1 and reference_token[0] == '0')
13282  {
13283  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
13284  }
13285 
13286  // note: at performs range check
13287  JSON_TRY
13288  {
13289  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13290  }
13291  JSON_CATCH (std::invalid_argument&)
13292  {
13293  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13294  }
13295  break;
13296  }
13297 
13298  default:
13299  {
13300  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13301  }
13302  }
13303  }
13304 
13305  return *ptr;
13306  }
13307 
13322  {
13323  for (const auto& reference_token : reference_tokens)
13324  {
13325  switch (ptr->m_type)
13326  {
13327  case value_t::object:
13328  {
13329  // use unchecked object access
13330  ptr = &ptr->operator[](reference_token);
13331  break;
13332  }
13333 
13334  case value_t::array:
13335  {
13336  if (reference_token == "-")
13337  {
13338  // "-" cannot be used for const access
13339  JSON_THROW(out_of_range::create(402, "array index '-' (" +
13340  std::to_string(ptr->m_value.array->size()) +
13341  ") is out of range"));
13342  }
13343 
13344  // error condition (cf. RFC 6901, Sect. 4)
13345  if (reference_token.size() > 1 and reference_token[0] == '0')
13346  {
13347  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
13348  }
13349 
13350  // use unchecked array access
13351  JSON_TRY
13352  {
13353  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
13354  }
13355  JSON_CATCH (std::invalid_argument&)
13356  {
13357  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13358  }
13359  break;
13360  }
13361 
13362  default:
13363  {
13364  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13365  }
13366  }
13367  }
13368 
13369  return *ptr;
13370  }
13371 
13379  {
13380  for (const auto& reference_token : reference_tokens)
13381  {
13382  switch (ptr->m_type)
13383  {
13384  case value_t::object:
13385  {
13386  // note: at performs range check
13387  ptr = &ptr->at(reference_token);
13388  break;
13389  }
13390 
13391  case value_t::array:
13392  {
13393  if (reference_token == "-")
13394  {
13395  // "-" always fails the range check
13396  JSON_THROW(out_of_range::create(402, "array index '-' (" +
13397  std::to_string(ptr->m_value.array->size()) +
13398  ") is out of range"));
13399  }
13400 
13401  // error condition (cf. RFC 6901, Sect. 4)
13402  if (reference_token.size() > 1 and reference_token[0] == '0')
13403  {
13404  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
13405  }
13406 
13407  // note: at performs range check
13408  JSON_TRY
13409  {
13410  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13411  }
13412  JSON_CATCH (std::invalid_argument&)
13413  {
13414  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13415  }
13416  break;
13417  }
13418 
13419  default:
13420  {
13421  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13422  }
13423  }
13424  }
13425 
13426  return *ptr;
13427  }
13428 
13438  static std::vector<std::string> split(const std::string& reference_string)
13439  {
13440  std::vector<std::string> result;
13441 
13442  // special case: empty reference string -> no reference tokens
13443  if (reference_string.empty())
13444  {
13445  return result;
13446  }
13447 
13448  // check if nonempty reference string begins with slash
13449  if (reference_string[0] != '/')
13450  {
13451  JSON_THROW(parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'"));
13452  }
13453 
13454  // extract the reference tokens:
13455  // - slash: position of the last read slash (or end of string)
13456  // - start: position after the previous slash
13457  for (
13458  // search for the first slash after the first character
13459  size_t slash = reference_string.find_first_of('/', 1),
13460  // set the beginning of the first reference token
13461  start = 1;
13462  // we can stop if start == string::npos+1 = 0
13463  start != 0;
13464  // set the beginning of the next reference token
13465  // (will eventually be 0 if slash == std::string::npos)
13466  start = slash + 1,
13467  // find next slash
13468  slash = reference_string.find_first_of('/', start))
13469  {
13470  // use the text between the beginning of the reference token
13471  // (start) and the last slash (slash).
13472  auto reference_token = reference_string.substr(start, slash - start);
13473 
13474  // check reference tokens are properly escaped
13475  for (size_t pos = reference_token.find_first_of('~');
13476  pos != std::string::npos;
13477  pos = reference_token.find_first_of('~', pos + 1))
13478  {
13479  assert(reference_token[pos] == '~');
13480 
13481  // ~ must be followed by 0 or 1
13482  if (pos == reference_token.size() - 1 or
13483  (reference_token[pos + 1] != '0' and
13484  reference_token[pos + 1] != '1'))
13485  {
13486  JSON_THROW(parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
13487  }
13488  }
13489 
13490  // finally, store the reference token
13491  unescape(reference_token);
13492  result.push_back(reference_token);
13493  }
13494 
13495  return result;
13496  }
13497 
13511  static void replace_substring(std::string& s,
13512  const std::string& f,
13513  const std::string& t)
13514  {
13515  assert(not f.empty());
13516 
13517  for (
13518  size_t pos = s.find(f); // find first occurrence of f
13519  pos != std::string::npos; // make sure f was found
13520  s.replace(pos, f.size(), t), // replace with t
13521  pos = s.find(f, pos + t.size()) // find next occurrence of f
13522  );
13523  }
13524 
13526  static std::string escape(std::string s)
13527  {
13528  // escape "~"" to "~0" and "/" to "~1"
13529  replace_substring(s, "~", "~0");
13530  replace_substring(s, "/", "~1");
13531  return s;
13532  }
13533 
13535  static void unescape(std::string& s)
13536  {
13537  // first transform any occurrence of the sequence '~1' to '/'
13538  replace_substring(s, "~1", "/");
13539  // then transform any occurrence of the sequence '~0' to '~'
13540  replace_substring(s, "~0", "~");
13541  }
13542 
13550  static void flatten(const std::string& reference_string,
13551  const basic_json& value,
13552  basic_json& result)
13553  {
13554  switch (value.m_type)
13555  {
13556  case value_t::array:
13557  {
13558  if (value.m_value.array->empty())
13559  {
13560  // flatten empty array as null
13561  result[reference_string] = nullptr;
13562  }
13563  else
13564  {
13565  // iterate array and use index as reference string
13566  for (size_t i = 0; i < value.m_value.array->size(); ++i)
13567  {
13568  flatten(reference_string + "/" + std::to_string(i),
13569  value.m_value.array->operator[](i), result);
13570  }
13571  }
13572  break;
13573  }
13574 
13575  case value_t::object:
13576  {
13577  if (value.m_value.object->empty())
13578  {
13579  // flatten empty object as null
13580  result[reference_string] = nullptr;
13581  }
13582  else
13583  {
13584  // iterate object and use keys as reference string
13585  for (const auto& element : *value.m_value.object)
13586  {
13587  flatten(reference_string + "/" + escape(element.first),
13588  element.second, result);
13589  }
13590  }
13591  break;
13592  }
13593 
13594  default:
13595  {
13596  // add primitive value with its reference string
13597  result[reference_string] = value;
13598  break;
13599  }
13600  }
13601  }
13602 
13614  {
13615  if (not value.is_object())
13616  {
13617  JSON_THROW(type_error::create(314, "only objects can be unflattened"));
13618  }
13619 
13620  basic_json result;
13621 
13622  // iterate the JSON object values
13623  for (const auto& element : *value.m_value.object)
13624  {
13625  if (not element.second.is_primitive())
13626  {
13627  JSON_THROW(type_error::create(315, "values in object must be primitive"));
13628  }
13629 
13630  // assign value to reference pointed to by JSON pointer; Note
13631  // that if the JSON pointer is "" (i.e., points to the whole
13632  // value), function get_and_create returns a reference to
13633  // result itself. An assignment will then create a primitive
13634  // value.
13635  json_pointer(element.first).get_and_create(result) = element.second;
13636  }
13637 
13638  return result;
13639  }
13640 
13641  friend bool operator==(json_pointer const& lhs,
13642  json_pointer const& rhs) noexcept
13643  {
13644  return lhs.reference_tokens == rhs.reference_tokens;
13645  }
13646 
13647  friend bool operator!=(json_pointer const& lhs,
13648  json_pointer const& rhs) noexcept
13649  {
13650  return !(lhs == rhs);
13651  }
13652 
13654  std::vector<std::string> reference_tokens {};
13655  };
13656 
13658  // JSON Pointer support //
13660 
13663 
13698  {
13699  return ptr.get_unchecked(this);
13700  }
13701 
13726  {
13727  return ptr.get_unchecked(this);
13728  }
13729 
13766  {
13767  return ptr.get_checked(this);
13768  }
13769 
13805  const_reference at(const json_pointer& ptr) const
13806  {
13807  return ptr.get_checked(this);
13808  }
13809 
13833  {
13834  basic_json result(value_t::object);
13835  json_pointer::flatten("", *this, result);
13836  return result;
13837  }
13838 
13870  {
13871  return json_pointer::unflatten(*this);
13872  }
13873 
13875 
13877  // JSON Patch functions //
13879 
13882 
13930  basic_json patch(const basic_json& json_patch) const
13931  {
13932  // make a working copy to apply the patch to
13933  basic_json result = *this;
13934 
13935  // the valid JSON Patch operations
13936  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13937 
13938  const auto get_op = [](const std::string & op)
13939  {
13940  if (op == "add")
13941  {
13942  return patch_operations::add;
13943  }
13944  if (op == "remove")
13945  {
13946  return patch_operations::remove;
13947  }
13948  if (op == "replace")
13949  {
13951  }
13952  if (op == "move")
13953  {
13954  return patch_operations::move;
13955  }
13956  if (op == "copy")
13957  {
13958  return patch_operations::copy;
13959  }
13960  if (op == "test")
13961  {
13962  return patch_operations::test;
13963  }
13964 
13965  return patch_operations::invalid;
13966  };
13967 
13968  // wrapper for "add" operation; add value at ptr
13969  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
13970  {
13971  // adding to the root of the target document means replacing it
13972  if (ptr.is_root())
13973  {
13974  result = val;
13975  }
13976  else
13977  {
13978  // make sure the top element of the pointer exists
13979  json_pointer top_pointer = ptr.top();
13980  if (top_pointer != ptr)
13981  {
13982  result.at(top_pointer);
13983  }
13984 
13985  // get reference to parent of JSON pointer ptr
13986  const auto last_path = ptr.pop_back();
13987  basic_json& parent = result[ptr];
13988 
13989  switch (parent.m_type)
13990  {
13991  case value_t::null:
13992  case value_t::object:
13993  {
13994  // use operator[] to add value
13995  parent[last_path] = val;
13996  break;
13997  }
13998 
13999  case value_t::array:
14000  {
14001  if (last_path == "-")
14002  {
14003  // special case: append to back
14004  parent.push_back(val);
14005  }
14006  else
14007  {
14008  const auto idx = std::stoi(last_path);
14009  if (static_cast<size_type>(idx) > parent.size())
14010  {
14011  // avoid undefined behavior
14012  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
14013  }
14014  else
14015  {
14016  // default case: insert add offset
14017  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
14018  }
14019  }
14020  break;
14021  }
14022 
14023  default:
14024  {
14025  // if there exists a parent it cannot be primitive
14026  assert(false); // LCOV_EXCL_LINE
14027  }
14028  }
14029  }
14030  };
14031 
14032  // wrapper for "remove" operation; remove value at ptr
14033  const auto operation_remove = [&result](json_pointer & ptr)
14034  {
14035  // get reference to parent of JSON pointer ptr
14036  const auto last_path = ptr.pop_back();
14037  basic_json& parent = result.at(ptr);
14038 
14039  // remove child
14040  if (parent.is_object())
14041  {
14042  // perform range check
14043  auto it = parent.find(last_path);
14044  if (it != parent.end())
14045  {
14046  parent.erase(it);
14047  }
14048  else
14049  {
14050  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
14051  }
14052  }
14053  else if (parent.is_array())
14054  {
14055  // note erase performs range check
14056  parent.erase(static_cast<size_type>(std::stoi(last_path)));
14057  }
14058  };
14059 
14060  // type check: top level value must be an array
14061  if (not json_patch.is_array())
14062  {
14063  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
14064  }
14065 
14066  // iterate and apply the operations
14067  for (const auto& val : json_patch)
14068  {
14069  // wrapper to get a value for an operation
14070  const auto get_value = [&val](const std::string & op,
14071  const std::string & member,
14072  bool string_type) -> basic_json&
14073  {
14074  // find value
14075  auto it = val.m_value.object->find(member);
14076 
14077  // context-sensitive error message
14078  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
14079 
14080  // check if desired value is present
14081  if (it == val.m_value.object->end())
14082  {
14083  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
14084  }
14085 
14086  // check if result is of type string
14087  if (string_type and not it->second.is_string())
14088  {
14089  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
14090  }
14091 
14092  // no error: return value
14093  return it->second;
14094  };
14095 
14096  // type check: every element of the array must be an object
14097  if (not val.is_object())
14098  {
14099  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
14100  }
14101 
14102  // collect mandatory members
14103  const std::string op = get_value("op", "op", true);
14104  const std::string path = get_value(op, "path", true);
14105  json_pointer ptr(path);
14106 
14107  switch (get_op(op))
14108  {
14109  case patch_operations::add:
14110  {
14111  operation_add(ptr, get_value("add", "value", false));
14112  break;
14113  }
14114 
14115  case patch_operations::remove:
14116  {
14117  operation_remove(ptr);
14118  break;
14119  }
14120 
14122  {
14123  // the "path" location must exist - use at()
14124  result.at(ptr) = get_value("replace", "value", false);
14125  break;
14126  }
14127 
14128  case patch_operations::move:
14129  {
14130  const std::string from_path = get_value("move", "from", true);
14131  json_pointer from_ptr(from_path);
14132 
14133  // the "from" location must exist - use at()
14134  basic_json v = result.at(from_ptr);
14135 
14136  // The move operation is functionally identical to a
14137  // "remove" operation on the "from" location, followed
14138  // immediately by an "add" operation at the target
14139  // location with the value that was just removed.
14140  operation_remove(from_ptr);
14141  operation_add(ptr, v);
14142  break;
14143  }
14144 
14146  {
14147  const std::string from_path = get_value("copy", "from", true);;
14148  const json_pointer from_ptr(from_path);
14149 
14150  // the "from" location must exist - use at()
14151  result[ptr] = result.at(from_ptr);
14152  break;
14153  }
14154 
14155  case patch_operations::test:
14156  {
14157  bool success = false;
14158  JSON_TRY
14159  {
14160  // check if "value" matches the one at "path"
14161  // the "path" location must exist - use at()
14162  success = (result.at(ptr) == get_value("test", "value", false));
14163  }
14165  {
14166  // ignore out of range errors: success remains false
14167  }
14168 
14169  // throw an exception if test fails
14170  if (not success)
14171  {
14172  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
14173  }
14174 
14175  break;
14176  }
14177 
14178  case patch_operations::invalid:
14179  {
14180  // op must be "add", "remove", "replace", "move", "copy", or
14181  // "test"
14182  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
14183  }
14184  }
14185  }
14186 
14187  return result;
14188  }
14189 
14222  static basic_json diff(const basic_json& source,
14223  const basic_json& target,
14224  const std::string& path = "")
14225  {
14226  // the patch
14227  basic_json result(value_t::array);
14228 
14229  // if the values are the same, return empty patch
14230  if (source == target)
14231  {
14232  return result;
14233  }
14234 
14235  if (source.type() != target.type())
14236  {
14237  // different types: replace value
14238  result.push_back(
14239  {
14240  {"op", "replace"},
14241  {"path", path},
14242  {"value", target}
14243  });
14244  }
14245  else
14246  {
14247  switch (source.type())
14248  {
14249  case value_t::array:
14250  {
14251  // first pass: traverse common elements
14252  size_t i = 0;
14253  while (i < source.size() and i < target.size())
14254  {
14255  // recursive call to compare array values at index i
14256  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
14257  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14258  ++i;
14259  }
14260 
14261  // i now reached the end of at least one array
14262  // in a second pass, traverse the remaining elements
14263 
14264  // remove my remaining elements
14265  const auto end_index = static_cast<difference_type>(result.size());
14266  while (i < source.size())
14267  {
14268  // add operations in reverse order to avoid invalid
14269  // indices
14270  result.insert(result.begin() + end_index, object(
14271  {
14272  {"op", "remove"},
14273  {"path", path + "/" + std::to_string(i)}
14274  }));
14275  ++i;
14276  }
14277 
14278  // add other remaining elements
14279  while (i < target.size())
14280  {
14281  result.push_back(
14282  {
14283  {"op", "add"},
14284  {"path", path + "/" + std::to_string(i)},
14285  {"value", target[i]}
14286  });
14287  ++i;
14288  }
14289 
14290  break;
14291  }
14292 
14293  case value_t::object:
14294  {
14295  // first pass: traverse this object's elements
14296  for (auto it = source.begin(); it != source.end(); ++it)
14297  {
14298  // escape the key name to be used in a JSON patch
14299  const auto key = json_pointer::escape(it.key());
14300 
14301  if (target.find(it.key()) != target.end())
14302  {
14303  // recursive call to compare object values at key it
14304  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
14305  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14306  }
14307  else
14308  {
14309  // found a key that is not in o -> remove it
14310  result.push_back(object(
14311  {
14312  {"op", "remove"},
14313  {"path", path + "/" + key}
14314  }));
14315  }
14316  }
14317 
14318  // second pass: traverse other object's elements
14319  for (auto it = target.begin(); it != target.end(); ++it)
14320  {
14321  if (source.find(it.key()) == source.end())
14322  {
14323  // found a key that is not in this -> add it
14324  const auto key = json_pointer::escape(it.key());
14325  result.push_back(
14326  {
14327  {"op", "add"},
14328  {"path", path + "/" + key},
14329  {"value", it.value()}
14330  });
14331  }
14332  }
14333 
14334  break;
14335  }
14336 
14337  default:
14338  {
14339  // both primitive type: replace value
14340  result.push_back(
14341  {
14342  {"op", "replace"},
14343  {"path", path},
14344  {"value", target}
14345  });
14346  break;
14347  }
14348  }
14349  }
14350 
14351  return result;
14352  }
14353 
14355 };
14356 
14358 // presets //
14360 
14370 } // namespace nlohmann
14371 
14372 
14374 // nonmember support //
14376 
14377 // specialization of std::swap, and std::hash
14378 namespace std
14379 {
14385 template<>
14386 inline void swap(nlohmann::json& j1,
14387  nlohmann::json& j2) noexcept(
14388  is_nothrow_move_constructible<nlohmann::json>::value and
14389  is_nothrow_move_assignable<nlohmann::json>::value
14390  )
14391 {
14392  j1.swap(j2);
14393 }
14394 
14396 template<>
14398 {
14404  std::size_t operator()(const nlohmann::json& j) const
14405  {
14406  // a naive hashing via the string representation
14407  const auto& h = hash<nlohmann::json::string_t>();
14408  return h(j.dump());
14409  }
14410 };
14411 
14413 template <>
14415 {
14421  nlohmann::detail::value_t rhs) const noexcept
14422  {
14423  return nlohmann::detail::operator<(lhs, rhs);
14424  }
14425 };
14426 
14427 } // namespace std
14428 
14442 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
14443 {
14444  return nlohmann::json::parse(s, s + n);
14445 }
14446 
14460 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
14461 {
14462  return nlohmann::json::json_pointer(std::string(s, n));
14463 }
14464 
14465 // restore GCC/clang diagnostic settings
14466 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
14467  #pragma GCC diagnostic pop
14468 #endif
14469 #if defined(__clang__)
14470  #pragma GCC diagnostic pop
14471 #endif
14472 
14473 // clean up
14474 #undef JSON_CATCH
14475 #undef JSON_THROW
14476 #undef JSON_TRY
14477 #undef JSON_LIKELY
14478 #undef JSON_UNLIKELY
14479 #undef JSON_DEPRECATED
14480 
14481 #endif
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7775
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:1609
the parser read ] and finished processing a JSON array
object_t * object
object (stored with pointer to save storage)
Definition: json.hpp:1951
static std::shared_ptr< input_adapter > create(const ContiguousContainer &c)
input adapter for contiguous container
Definition: json.hpp:8792
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:5595
int d
Definition: base.py:14
lexer(input_adapter_t adapter)
Definition: json.hpp:11057
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:2562
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:4120
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:1374
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:3315
const char * start
pointer to the first character
Definition: json.hpp:8954
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:573
json_reverse_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:8631
const int id
the id of the exception
Definition: json.hpp:155
const uint32_t T[512]
Definition: groestl_tables.h:34
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:3297
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:5721
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:7906
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:7748
Definition: json.hpp:1115
basic_json parse(const bool strict=true)
public parser interface
Definition: json.hpp:12537
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:8111
friend std::ostream & operator<<(std::ostream &os, primitive_iterator_t it)
Definition: json.hpp:7807
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:3351
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:5406
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6373
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:2756
#define JSON_CATCH(exception)
Definition: json.hpp:99
bool is_negative(T value)
Definition: format.h:906
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:1899
basic_json parse_internal(bool keep)
the actual parser
Definition: json.hpp:12587
input adapter for buffer input
Definition: json.hpp:8912
iter_impl operator--(int)
post-decrement (it–)
Definition: json.hpp:8295
void dump_escaped(const string_t &s) const
dump escaped string
Definition: json.hpp:7028
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:8502
an iterator for primitive JSON types
Definition: json.hpp:7733
specialization for std::less<value_t>
Definition: json.hpp:14414
token_type scan_null()
Definition: json.hpp:12292
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:7872
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:13641
void expect(typename lexer::token_type t) const
Definition: json.hpp:12926
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12562
reference get_checked(pointer ptr) const
Definition: json.hpp:13257
number value (unsigned integer)
static constexpr auto value
Definition: json.hpp:723
void check_eof() const
check if input ended
Definition: json.hpp:10074
std::vector< char > buffer
internal buffer
Definition: json.hpp:8908
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:8626
static auto constexpr value
Definition: json.hpp:682
iter_impl operator+(difference_type i)
add to iterator
Definition: json.hpp:8480
void dump_float(number_float_t x)
dump a floating-point number
Definition: json.hpp:7216
static basic_json parse(std::istream &&i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:7498
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:4576
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:12354
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:526
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 > {})))
Definition: json.hpp:1135
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:1953
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:13725
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:1955
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:465
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:2039
IntFormatSpec< int, TypeSpec< 'x'> > hex(int value)
int get_character() override
Definition: json.hpp:8929
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:13647
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:7970
primitive_iterator_t & operator+=(difference_type n)
Definition: json.hpp:7838
token_type scan_number()
scan a number literal
Definition: json.hpp:11932
basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer > basic_json_t
workaround type for MSVC
Definition: json.hpp:1305
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:1831
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2935
static basic_json parse(std::istream &i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:7489
boolean_t boolean
boolean
Definition: json.hpp:1957
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:13036
token_type scan()
Definition: json.hpp:12417
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6504
helper class for iteration
Definition: json.hpp:7886
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:1974
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:1976
serializer(output_adapter_t< char > s, const char ichar)
Definition: json.hpp:6736
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:1760
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:4071
bool accept_internal()
the acutal acceptor
Definition: json.hpp:12803
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2965
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:13511
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:169
a class to store JSON values
Definition: json.hpp:1298
abstract input adapter interface
Definition: json.hpp:8713
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:1367
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
Definition: json.hpp:981
typename std::conditional< std::is_const< U >::value, typename basic_json::const_reference, typename basic_json::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:8019
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:13765
const char thousands_sep
the locale&#39;s thousand separator character
Definition: json.hpp:7301
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:5841
Definition: test.py:1
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
Definition: json.hpp:711
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:4905
an floating point number – use get_number_float() for actual value
default JSONSerializer template argument
Definition: json.hpp:1170
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:6021
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:3303
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:8011
static std::shared_ptr< output_adapter< CharType > > create(std::string &s)
Definition: json.hpp:6634
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:3327
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2992
Definition: json.hpp:489
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:7341
type_error(int id_, const char *what_arg)
Definition: json.hpp:317
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:1386
StringType string_t
a type for a string
Definition: json.hpp:1662
JSON_DEPRECATED friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:7624
friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7785
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:14386
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:5016
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:8148
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:7296
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:2510
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:5212
reference operator[](T *(&key)[n])
access specified object element
Definition: json.hpp:4160
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:13832
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:1328
Definition: block_queue.cpp:41
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4945
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:8306
const char * limit
pointer past the last character
Definition: json.hpp:8952
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:514
static void strtof(double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:11881
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:8021
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:1359
static void unescape(std::string &s)
unescape tilde and slash
Definition: json.hpp:13535
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5645
static std::string codepoint_to_string(int codepoint)
create diagnostic representation of a codepoint
Definition: json.hpp:11337
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:5920
reference value() const
return the value of an iterator
Definition: json.hpp:8582
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
Definition: json.hpp:4340
lexical analysis
Definition: json.hpp:10990
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:6344
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
Definition: json.hpp:4872
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:6548
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:5094
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:1961
number_float_t number_float
number (floating-point)
Definition: json.hpp:1963
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:5220
static basic_json from_cbor(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in CBOR format
Definition: json.hpp:10896
const char indent_char
the indentation character
Definition: json.hpp:7306
static std::size_t extra_space(const string_t &s) noexcept
calculates the extra space to escape a JSON string
Definition: json.hpp:6957
static basic_json parse(const CharT s, const parser_callback_t cb=nullptr)
deserialize from string literal
Definition: json.hpp:7454
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:6301
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:878
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:1356
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:3173
input adapter for cached stream input
Definition: json.hpp:8803
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:5769
#define JSON_UNLIKELY(x)
Definition: json.hpp:108
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:538
std::shared_ptr< input_adapter > input_adapter_t
a type to simplify interfaces
Definition: json.hpp:8800
virtual std::string read(size_t offset, size_t length)=0
virtual ~output_adapter()
Definition: json.hpp:6622
friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7770
array (ordered collection of values)
indicating the end of the input buffer
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:8664
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6559
Definition: d.py:1
Definition: json.hpp:733
typename std::conditional< std::is_const< U >::value, typename basic_json::const_pointer, typename basic_json::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:8015
void write_msgpack(const basic_json &j)
[in] j JSON value to serialize
Definition: json.hpp:10360
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:3321
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:8637
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:7948
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:13438
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:8032
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:1970
void copy(key &AA, const key &A)
Definition: rctOps.h:81
serialization to CBOR and MessagePack values
Definition: json.hpp:10099
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6592
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:787
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.hpp:1198
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:4278
const std::lconv * loc
the locale
Definition: json.hpp:7299
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:2793
static std::string escape(std::string s)
escape tilde and slash
Definition: json.hpp:13526
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:8618
static basic_json parse(const ContiguousContainer &c, const parser_callback_t cb=nullptr)
deserialize from a container with contiguous storage
Definition: json.hpp:7609
NLOHMANN_JSON_HAS_HELPER(mapped_type)
flags
Definition: http_parser_merged.h:136
putput adatpter for output streams
Definition: json.hpp:6669
exception indicating access out of the defined range
Definition: json.hpp:338
static out_of_range create(int id, const std::string &what_arg)
Definition: json.hpp:341
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:3014
iteration_proxy_internal(IteratorType it) noexcept
Definition: json.hpp:7895
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:3151
Definition: json.hpp:488
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:8371
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:1314
const_reference get_checked(const_pointer ptr) const
Definition: json.hpp:13378
const std::string get_string()
return string value
Definition: json.hpp:12360
static basic_json unflatten(const basic_json &value)
Definition: json.hpp:13613
discarded by the the parser callback function
virtual void write_characters(const CharType *s, size_t length)=0
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3792
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:2218
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:8471
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:3941
const size_t byte
byte index of the parse error
Definition: json.hpp:236
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:4771
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:6460
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:2679
output adapter for basic_string
Definition: json.hpp:6692
static constexpr bool value
Definition: json.hpp:743
T get_number()
Definition: json.hpp:9849
ValueType value(const json_pointer &ptr, ValueType default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:4412
output_vector_adapter(std::vector< CharType > &vec)
Definition: json.hpp:6649
void push_back(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5676
void add(int c)
add a character to yytext
Definition: json.hpp:12325
json_value()=default
default constructor (for null values)
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:600
void clear() noexcept
clears the contents
Definition: json.hpp:5462
std::vector< node > array
Definition: mstch.hpp:120
void to_json(BasicJsonType &j, T(&arr)[N])
Definition: json.hpp:863
primitive_iterator_t & operator--()
Definition: json.hpp:7825
static std::shared_ptr< input_adapter > create(std::istream &&i, const size_t buffer_size=16384)
input adapter for input stream
Definition: json.hpp:8729
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:5870
~basic_json()
destructor
Definition: json.hpp:2826
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:13654
std::string type_name() const
return the type as string
Definition: json.hpp:7683
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:3066
internal::map< const std::string, node > map
Definition: mstch.hpp:119
int get_character() override
Definition: json.hpp:8840
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:14222
exception indicating a parse error
Definition: json.hpp:207
basic_json parse_msgpack()
create a JSON value from MessagePack input
Definition: json.hpp:9404
static type_error create(int id, const std::string &what_arg)
Definition: json.hpp:310
reference operator[](T *key)
access specified object element
Definition: json.hpp:4228
friend class basic_json
allow basic_json to access private members
Definition: json.hpp:8000
internal_iterator m_it
the actual iterator of the associated instance
Definition: json.hpp:8591
#define JSON_THROW(exception)
Definition: json.hpp:97
an unsigned integer – use get_number_unsigned() for actual value
basic_json::string_t key() const
return key of the iterator
Definition: json.hpp:7921
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:13697
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:8621
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:562
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:3890
reference get_and_create(reference j) const
create and return a reference to the pointed to value
Definition: json.hpp:13095
string_t indent_string
the indentation string
Definition: json.hpp:7309
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:8657
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:8672
#define JSON_DEPRECATED
Definition: json.hpp:88
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:8179
general exception of the basic_json class
Definition: json.hpp:145
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:5340
static std::shared_ptr< input_adapter > create(CharT b)
input adapter for string literal
Definition: json.hpp:8747
difference_type get_value() const noexcept
Definition: json.hpp:7737
out_of_range(int id_, const char *what_arg)
Definition: json.hpp:348
const std::streampos start_position
position of the stream when we started
Definition: json.hpp:8905
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:3642
declaration and default definition for the functions used the API
void escape(const std::string &str, std::string &ret)
Definition: json.h:33
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:10719
void write_characters(const CharType *s, size_t length) override
Definition: json.hpp:6681
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:12342
auto call(const BasicJsonType &j, T &val, priority_tag< 1 >) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
Definition: json.hpp:1119
reference back()
access the last element
Definition: json.hpp:4509
binary_writer(output_adapter_t< uint8_t > adapter)
create a binary writer
Definition: json.hpp:10107
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:550
syntax analysis
Definition: json.hpp:12518
DummyInt isnan(...)
Definition: format.h:372
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:8380
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:6290
a string – use get_string() for actual value
iter_impl(const iter_impl &other) noexcept
copy constructor
Definition: json.hpp:8085
static std::shared_ptr< output_adapter< CharType > > create(std::vector< CharType > &vec)
Definition: json.hpp:6624
iter_impl operator++(int)
post-increment (it++)
Definition: json.hpp:8252
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:11876
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:8686
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4955
exception indicating errors with iterators
Definition: json.hpp:268
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:5123
static std::string name(const std::string &ename, int id)
Definition: json.hpp:162
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:3036
wrapper around the serialization functions
Definition: json.hpp:6725
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:431
json_pointer top() const
Definition: json.hpp:13075
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:3339
namespace for Niels Lohmann
Definition: json.hpp:116
serializer & operator=(const serializer &)=delete
parse_event_t
JSON callback events.
Definition: json.hpp:2088
hash value for JSON objects
Definition: json.hpp:14397
serializer(const serializer &)=delete
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:4683
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:3333
static void flatten(const std::string &reference_string, const basic_json &value, basic_json &result)
Definition: json.hpp:13550
object (unordered set of name/value pairs)
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:3217
parser(input_adapter_t adapter, const parser_callback_t cb=nullptr)
a parser reading from an input adapter
Definition: json.hpp:12522
static other_error create(int id, const std::string &what_arg)
Definition: json.hpp:367
void write_cbor(const basic_json &j)
[in] j JSON value to serialize
Definition: json.hpp:10116
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:11015
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:3386
const char * cursor
pointer to the current character
Definition: json.hpp:8950
const char decimal_point
the locale&#39;s decimal point character
Definition: json.hpp:7303
Definition: json.hpp:1089
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:3691
static constexpr bool value
Definition: json.hpp:761
Definition: json.hpp:1144
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:7964
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:462
string_t dump(const int indent=-1, const char indent_char=' ') const
serialization
Definition: json.hpp:2900
#define min(a, b)
Definition: oaes_lib.c:71
the parser read } and finished processing a JSON object
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7802
primitive_iterator_t operator--(int)
Definition: json.hpp:7831
an iterator value
Definition: json.hpp:7865
int b
Definition: base.py:1
exception indicating executing a member function with a wrong type
Definition: json.hpp:307
value_t m_type
the type of the current element
Definition: json.hpp:7713
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:1972
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6515
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:8616
object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:7868
static basic_json from_msgpack(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in MessagePack format
Definition: json.hpp:10971
void write_character(CharType c) override
Definition: json.hpp:6699
std::shared_ptr< output_adapter< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:6642
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
Definition: json.hpp:2445
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:3614
value_t
the JSON type enumeration
Definition: json.hpp:409
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:7656
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:8650
output_string_adapter(std::string &s)
Definition: json.hpp:6695
DummyInt signbit(...)
Definition: format.h:368
#define JSON_LIKELY(x)
Definition: json.hpp:107
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:6209
JSON Pointer.
Definition: json.hpp:12989
static std::shared_ptr< input_adapter > create(const char *b, size_t l)
input adapter for buffer
Definition: json.hpp:8735
type
Definition: json.h:74
void write_character(CharType c) override
Definition: json.hpp:6653
void reset() noexcept
reset yytext
Definition: json.hpp:12309
cached_input_stream_adapter(std::istream &i, const size_t buffer_size)
Definition: json.hpp:8806
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:4435
std::string read(size_t offset, size_t length) override
Definition: json.hpp:8941
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:5571
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:8413
a signed integer – use get_number_integer() for actual value
internal::object_t< node > object
Definition: mstch.hpp:117
primitive_iterator_t & operator-=(difference_type n)
Definition: json.hpp:7844
static constexpr T value
Definition: json.hpp:1146
deserialization of CBOR and MessagePack values
Definition: json.hpp:8968
difference_type m_it
iterator as signed integer type
Definition: json.hpp:7855
int l
Definition: base.py:3
iter_impl & operator=(iter_impl other) noexcept(std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
Definition: json.hpp:8094
output_stream_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:6672
static T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:1907
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:14404
token_type
token types for the parser
Definition: json.hpp:10994
#define JSON_TRY
Definition: json.hpp:98
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:8692
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
Definition: json.hpp:4195
const_reference back() const
access the last element
Definition: json.hpp:4519
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:1378
token_type scan_false()
Definition: json.hpp:12280
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:3244
output_adapter_t< char > o
the output of the serializer
Definition: json.hpp:7293
void write_characters(const CharType *s, size_t length) override
Definition: json.hpp:6658
array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:7870
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:1688
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6537
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:8431
a JSON value
Definition: json.hpp:1948
void from_json(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:1058
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:8338
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
Definition: json.hpp:7412
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:5561
static char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:11067
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:8422
void unexpect(typename lexer::token_type t) const
Definition: json.hpp:12948
basic_json(std::initializer_list< basic_json > 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:2362
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:3095
static std::shared_ptr< output_adapter< CharType > > create(std::ostream &s)
Definition: json.hpp:6629
exception indicating other errors
Definition: json.hpp:364
static std::shared_ptr< input_adapter > create(std::istream &i, const size_t buffer_size=16384)
input adapter for input stream
Definition: json.hpp:8723
Definition: json.hpp:485
output adapter for byte vectors
Definition: json.hpp:6646
lexer::token_type get_token()
get next token from lexer
Definition: json.hpp:12917
the parser finished reading a JSON value
invalid_iterator(int id_, const char *what_arg)
Definition: json.hpp:278
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:7900
primitive_iterator_t operator++(int)
Definition: json.hpp:7818
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:7742
std::string get_cbor_string()
reads a CBOR string
Definition: json.hpp:9908
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4985
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6603
void write_character(CharType c) override
Definition: json.hpp:6676
void swap(array_t &other)
exchanges the values
Definition: json.hpp:6093
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:3839
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:3291
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:1369
iteration_proxy(typename IteratorType::reference cont)
construct iteration proxy from a container
Definition: json.hpp:7959
basic_json(const value_t value_type)
create an empty value with a given type
Definition: json.hpp:2194
static constexpr bool value
Definition: json.hpp:776
static auto constexpr value
Definition: json.hpp:692
std::istream & is
the associated input stream
Definition: json.hpp:8892
primitive_iterator_t operator+(difference_type i)
Definition: json.hpp:7795
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:8529
void write_characters(const CharType *s, size_t length) override
Definition: json.hpp:6704
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:14420
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
Definition: json.hpp:2486
token_type scan_string()
scan a string literal
Definition: json.hpp:11358
void dump(const basic_json &val, const bool pretty_print, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:6760
friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7790
Definition: json.hpp:767
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:3123
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:3309
static invalid_iterator create(int id, const std::string &what_arg)
Definition: json.hpp:271
proxy class for the iterator_wrapper functions
Definition: json.hpp:5196
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:583
number_integer_t number_integer
number (integer)
Definition: json.hpp:1959
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:1563
string a
Definition: MakeCryptoOps.py:15
std::string const & replace(std::string &src, std::string const &to_find, std::string const &to_replace)
Definition: minicsv.h:41
void swap(string_t &other)
exchanges the values
Definition: json.hpp:6159
internal_iterator() noexcept
create an uninitialized internal_iterator
Definition: json.hpp:7875
exception(int id_, const char *what_arg)
Definition: json.hpp:158
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:7760
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:2051
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:8009
parse_error(int id_, size_t byte_, const char *what_arg)
Definition: json.hpp:239
const_reference get_unchecked(const_pointer ptr) const
return a const reference to the pointed to value
Definition: json.hpp:13321
int bool
Definition: stdbool.h:36
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:5817
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:3195
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:5026
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:5160
lexer m_lexer
the lexer
Definition: json.hpp:12974
static auto constexpr value
Definition: json.hpp:672
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:1376
detail::value_t value_t
Definition: json.hpp:1308
std::string get_string(const size_t len)
create a string by reading characters from the input
Definition: json.hpp:9884
friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7780
the parser read { and started to process a JSON object
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:611
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:1968
friend class basic_json
allow basic_json to access private members
Definition: json.hpp:12992
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:2284
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
deserialize from an iterator range with contiguous storage
Definition: json.hpp:7553
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:3987
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:4364
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:5535
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6471
reference front()
access the first element
Definition: json.hpp:4465
Definition: json.hpp:480
IteratorType::reference container
the container to iterate
Definition: json.hpp:7955
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:5086
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:3704
~cached_input_stream_adapter() override
Definition: json.hpp:8828
static parse_error create(int id, size_t byte_, const std::string &what_arg)
create a parse error exception
Definition: json.hpp:218
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:1361
reference value() const
return the value of an iterator
Definition: json.hpp:8699
indicating the scanner is uninitialized
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:5189
json_reverse_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:8644
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:8440
the parser read a key of a value in an object
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:13930
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:4033
void assert_invariant() const
checks the class invariants
Definition: json.hpp:2066
void call(BasicJsonType &, T &&, priority_tag< 0 >) const noexcept
Definition: json.hpp:1100
iter_impl operator-(difference_type i)
subtract from iterator
Definition: json.hpp:8491
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 > {})))
Definition: json.hpp:1108
virtual ~input_adapter()
Definition: json.hpp:8718
std::string to_string(t_connection_type type)
Definition: connection_basic.cpp:96
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:8263
criter reverse(citer it)
Definition: utils.cpp:16
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:3280
token_type scan_true()
Definition: json.hpp:12268
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:6333
pointer operator->() const
dereference the iterator
Definition: json.hpp:8218
static bool little_endianess() noexcept
determine system byte order
Definition: json.hpp:9813
std::basic_string< CharType > & str
Definition: json.hpp:6710
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:13017
void swap(object_t &other)
exchanges the values
Definition: json.hpp:6126
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:2045
void dump_integer(NumberType x)
dump an integer
Definition: json.hpp:7174
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:10801
a template for a reverse iterator class
Definition: json.hpp:1311
virtual void write_character(CharType c)=0
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:12348
void call(const BasicJsonType &, T &, priority_tag< 0 >) const noexcept
Definition: json.hpp:1127
constexpr size_t get_position() const noexcept
return position of last read token
Definition: json.hpp:12372
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:11084
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
Definition: json.hpp:908
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:5056
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:3363
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:1351
abstract output adapter interface
Definition: json.hpp:6617
static void strtof(long double &f, const char *str, char **endptr) noexcept
Definition: json.hpp:11886
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5621
binary_reader(input_adapter_t adapter)
create a binary reader
Definition: json.hpp:8976
other_error(int id_, const char *what_arg)
Definition: json.hpp:374
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:3357
JSON_DEPRECATED friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:7364
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:4856
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:7754
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:13869
std::string get_msgpack_string()
reads a MessagePack string
Definition: json.hpp:9999
static ge_precomp base[32][8]
Definition: ge_scalarmult_base.c:30
input_buffer_adapter(const char *b, size_t l)
Definition: json.hpp:8915
auto call(BasicJsonType &j, T &&val, priority_tag< 1 >) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:1093
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6493
basic_json parse_cbor(const bool get_char=true)
create a JSON value from CBOR input
Definition: json.hpp:8994
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:4806
number value (signed integer)
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6581
pointer m_object
associated JSON instance
Definition: json.hpp:8589
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:6322
reference get_unchecked(pointer ptr) const
return a reference to the pointed to value
Definition: json.hpp:13177
bool is_root() const
return whether pointer points to the root document
Definition: json.hpp:13070
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:502
reference operator+=(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5693
primitive_iterator_t & operator++()
Definition: json.hpp:7812
#define true
Definition: stdbool.h:37
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:3369
virtual const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:149
std::basic_ostream< CharType > & stream
Definition: json.hpp:6687
#define s(x, c)
Definition: aesb.c:46
std::string pop_back()
remove and return last reference pointer
Definition: json.hpp:13057
IteratorType anchor
the iterator
Definition: json.hpp:7890
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:2158
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
Definition: json.hpp:5978
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:8566
Definition: json.hpp:481
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:1364
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:6061
const_reference front() const
access the first element
Definition: json.hpp:4473
a template for a random access iterator for the basic_json class
Definition: json.hpp:1310
the parser read [ and started to process a JSON array
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:8680
number value (floating-point)
const std::string & get_error_message() const noexcept
return syntax error message
Definition: json.hpp:12408
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:7765
json_value m_value
the value of the current element
Definition: json.hpp:7716
std::vector< CharType > & v
Definition: json.hpp:6664
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:13805
static std::shared_ptr< input_adapter > create(T(&array)[N])
input adapter for array
Definition: json.hpp:8779
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:5131
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:5272
std::string get_token_string() const
return the last read token (for errors only)
Definition: json.hpp:12378
static std::shared_ptr< input_adapter > create(IteratorType first, IteratorType last)
input adapter for iterator range with contiguous storage
Definition: json.hpp:8758
void write_number(T n)
Definition: json.hpp:10607
std::string read(size_t offset, size_t length) override
Definition: json.hpp:8865
static basic_json meta()
returns version information on the library
Definition: json.hpp:1414
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:3345
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.hpp:1182