JSON for Modern C++  2.1.1
json.hpp
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> // strlen
42 #include <forward_list> // forward_list
43 #include <functional> // function, hash, less
44 #include <initializer_list> // initializer_list
45 #include <iostream> // istream, ostream
46 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
47 #include <limits> // numeric_limits
48 #include <locale> // locale
49 #include <map> // map
50 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
51 #include <numeric> // accumulate
52 #include <sstream> // stringstream
53 #include <string> // getline, stoi, string, to_string
54 #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
55 #include <utility> // declval, forward, make_pair, move, pair, swap
56 #include <vector> // vector
57 
58 // exclude unsupported compilers
59 #if defined(__clang__)
60  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
61  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
62  #endif
63 #elif defined(__GNUC__)
64  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
65  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
66  #endif
67 #endif
68 
69 // disable float-equal warnings on GCC/clang
70 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
71  #pragma GCC diagnostic push
72  #pragma GCC diagnostic ignored "-Wfloat-equal"
73 #endif
74 
75 // disable documentation warnings on clang
76 #if defined(__clang__)
77  #pragma GCC diagnostic push
78  #pragma GCC diagnostic ignored "-Wdocumentation"
79 #endif
80 
81 // allow for portable deprecation warnings
82 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
83  #define JSON_DEPRECATED __attribute__((deprecated))
84 #elif defined(_MSC_VER)
85  #define JSON_DEPRECATED __declspec(deprecated)
86 #else
87  #define JSON_DEPRECATED
88 #endif
89 
90 // allow to disable exceptions
91 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
92  #define JSON_THROW(exception) throw exception
93  #define JSON_TRY try
94  #define JSON_CATCH(exception) catch(exception)
95 #else
96  #define JSON_THROW(exception) std::abort()
97  #define JSON_TRY if(true)
98  #define JSON_CATCH(exception) if(false)
99 #endif
100 
106 namespace nlohmann
107 {
108 
117 namespace detail
118 {
120 // exceptions //
122 
135 class exception : public std::exception
136 {
137  public:
139  virtual const char* what() const noexcept override
140  {
141  return m.what();
142  }
143 
145  const int id;
146 
147  protected:
148  exception(int id_, const char* what_arg)
149  : id(id_), m(what_arg)
150  {}
151 
152  static std::string name(const std::string& ename, int id)
153  {
154  return "[json.exception." + ename + "." + std::to_string(id) + "] ";
155  }
156 
157  private:
159  std::runtime_error m;
160 };
161 
197 class parse_error : public exception
198 {
199  public:
208  static parse_error create(int id, size_t byte_, const std::string& what_arg)
209  {
210  std::string w = exception::name("parse_error", id) + "parse error" +
211  (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
212  ": " + what_arg;
213  return parse_error(id, byte_, w.c_str());
214  }
215 
226  const size_t byte;
227 
228  private:
229  parse_error(int id_, size_t byte_, const char* what_arg)
230  : exception(id_, what_arg), byte(byte_)
231  {}
232 };
233 
258 class invalid_iterator : public exception
259 {
260  public:
261  static invalid_iterator create(int id, const std::string& what_arg)
262  {
263  std::string w = exception::name("invalid_iterator", id) + what_arg;
264  return invalid_iterator(id, w.c_str());
265  }
266 
267  private:
268  invalid_iterator(int id_, const char* what_arg)
269  : exception(id_, what_arg)
270  {}
271 };
272 
297 class type_error : public exception
298 {
299  public:
300  static type_error create(int id, const std::string& what_arg)
301  {
302  std::string w = exception::name("type_error", id) + what_arg;
303  return type_error(id, w.c_str());
304  }
305 
306  private:
307  type_error(int id_, const char* what_arg)
308  : exception(id_, what_arg)
309  {}
310 };
311 
328 class out_of_range : public exception
329 {
330  public:
331  static out_of_range create(int id, const std::string& what_arg)
332  {
333  std::string w = exception::name("out_of_range", id) + what_arg;
334  return out_of_range(id, w.c_str());
335  }
336 
337  private:
338  out_of_range(int id_, const char* what_arg)
339  : exception(id_, what_arg)
340  {}
341 };
342 
354 class other_error : public exception
355 {
356  public:
357  static other_error create(int id, const std::string& what_arg)
358  {
359  std::string w = exception::name("other_error", id) + what_arg;
360  return other_error(id, w.c_str());
361  }
362 
363  private:
364  other_error(int id_, const char* what_arg)
365  : exception(id_, what_arg)
366  {}
367 };
368 
369 
370 
372 // JSON type enumeration //
374 
399 enum class value_t : uint8_t
400 {
401  null,
402  object,
403  array,
404  string,
405  boolean,
406  number_integer,
407  number_unsigned,
408  number_float,
409  discarded
410 };
411 
421 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
422 {
423  static constexpr std::array<uint8_t, 8> order = {{
424  0, // null
425  3, // object
426  4, // array
427  5, // string
428  1, // boolean
429  2, // integer
430  2, // unsigned
431  2, // float
432  }
433  };
434 
435  // discarded values are not comparable
436  if (lhs == value_t::discarded or rhs == value_t::discarded)
437  {
438  return false;
439  }
440 
441  return order[static_cast<std::size_t>(lhs)] <
442  order[static_cast<std::size_t>(rhs)];
443 }
444 
445 
447 // helpers //
449 
450 // alias templates to reduce boilerplate
451 template<bool B, typename T = void>
452 using enable_if_t = typename std::enable_if<B, T>::type;
453 
454 template<typename T>
455 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
456 
457 /*
458 Implementation of two C++17 constructs: conjunction, negation. This is needed
459 to avoid evaluating all the traits in a condition
460 
461 For example: not std::is_same<void, T>::value and has_value_type<T>::value
462 will not compile when T = void (on MSVC at least). Whereas
463 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
464 stop evaluating if negation<...>::value == false
465 
466 Please note that those constructs must be used with caution, since symbols can
467 become very long quickly (which can slow down compilation and cause MSVC
468 internal compiler errors). Only use it when you have to (see example ahead).
469 */
470 template<class...> struct conjunction : std::true_type {};
471 template<class B1> struct conjunction<B1> : B1 {};
472 template<class B1, class... Bn>
473 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
474 
475 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
476 
477 // dispatch utility (taken from ranges-v3)
478 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
479 template<> struct priority_tag<0> {};
480 
481 
483 // constructors //
485 
486 template<value_t> struct external_constructor;
487 
488 template<>
489 struct external_constructor<value_t::boolean>
490 {
491  template<typename BasicJsonType>
492  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
493  {
494  j.m_type = value_t::boolean;
495  j.m_value = b;
496  j.assert_invariant();
497  }
498 };
499 
500 template<>
501 struct external_constructor<value_t::string>
502 {
503  template<typename BasicJsonType>
504  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
505  {
506  j.m_type = value_t::string;
507  j.m_value = s;
508  j.assert_invariant();
509  }
510 };
511 
512 template<>
513 struct external_constructor<value_t::number_float>
514 {
515  template<typename BasicJsonType>
516  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
517  {
518  j.m_type = value_t::number_float;
519  j.m_value = val;
520  j.assert_invariant();
521  }
522 };
523 
524 template<>
525 struct external_constructor<value_t::number_unsigned>
526 {
527  template<typename BasicJsonType>
528  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
529  {
530  j.m_type = value_t::number_unsigned;
531  j.m_value = val;
532  j.assert_invariant();
533  }
534 };
535 
536 template<>
537 struct external_constructor<value_t::number_integer>
538 {
539  template<typename BasicJsonType>
540  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
541  {
542  j.m_type = value_t::number_integer;
543  j.m_value = val;
544  j.assert_invariant();
545  }
546 };
547 
548 template<>
549 struct external_constructor<value_t::array>
550 {
551  template<typename BasicJsonType>
552  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
553  {
554  j.m_type = value_t::array;
555  j.m_value = arr;
556  j.assert_invariant();
557  }
558 
559  template<typename BasicJsonType, typename CompatibleArrayType,
560  enable_if_t<not std::is_same<CompatibleArrayType,
561  typename BasicJsonType::array_t>::value,
562  int> = 0>
563  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
564  {
565  using std::begin;
566  using std::end;
567  j.m_type = value_t::array;
568  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
569  j.assert_invariant();
570  }
571 
572  template<typename BasicJsonType>
573  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
574  {
575  j.m_type = value_t::array;
576  j.m_value = value_t::array;
577  j.m_value.array->reserve(arr.size());
578  for (bool x : arr)
579  {
580  j.m_value.array->push_back(x);
581  }
582  j.assert_invariant();
583  }
584 };
585 
586 template<>
587 struct external_constructor<value_t::object>
588 {
589  template<typename BasicJsonType>
590  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
591  {
592  j.m_type = value_t::object;
593  j.m_value = obj;
594  j.assert_invariant();
595  }
596 
597  template<typename BasicJsonType, typename CompatibleObjectType,
598  enable_if_t<not std::is_same<CompatibleObjectType,
599  typename BasicJsonType::object_t>::value,
600  int> = 0>
601  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
602  {
603  using std::begin;
604  using std::end;
605 
606  j.m_type = value_t::object;
607  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
608  j.assert_invariant();
609  }
610 };
611 
612 
614 // has_/is_ functions //
616 
627 #define NLOHMANN_JSON_HAS_HELPER(type) \
628  template<typename T> struct has_##type { \
629  private: \
630  template<typename U, typename = typename U::type> \
631  static int detect(U &&); \
632  static void detect(...); \
633  public: \
634  static constexpr bool value = \
635  std::is_integral<decltype(detect(std::declval<T>()))>::value; \
636  }
637 
638 NLOHMANN_JSON_HAS_HELPER(mapped_type);
639 NLOHMANN_JSON_HAS_HELPER(key_type);
640 NLOHMANN_JSON_HAS_HELPER(value_type);
641 NLOHMANN_JSON_HAS_HELPER(iterator);
642 
643 #undef NLOHMANN_JSON_HAS_HELPER
644 
645 
646 template<bool B, class RealType, class CompatibleObjectType>
647 struct is_compatible_object_type_impl : std::false_type {};
648 
649 template<class RealType, class CompatibleObjectType>
650 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
651 {
652  static constexpr auto value =
653  std::is_constructible<typename RealType::key_type,
654  typename CompatibleObjectType::key_type>::value and
655  std::is_constructible<typename RealType::mapped_type,
656  typename CompatibleObjectType::mapped_type>::value;
657 };
658 
659 template<class BasicJsonType, class CompatibleObjectType>
660 struct is_compatible_object_type
661 {
662  static auto constexpr value = is_compatible_object_type_impl <
663  conjunction<negation<std::is_same<void, CompatibleObjectType>>,
664  has_mapped_type<CompatibleObjectType>,
665  has_key_type<CompatibleObjectType>>::value,
666  typename BasicJsonType::object_t, CompatibleObjectType >::value;
667 };
668 
669 template<typename BasicJsonType, typename T>
670 struct is_basic_json_nested_type
671 {
672  static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
673  std::is_same<T, typename BasicJsonType::const_iterator>::value or
674  std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
675  std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
676  std::is_same<T, typename BasicJsonType::json_pointer>::value;
677 };
678 
679 template<class BasicJsonType, class CompatibleArrayType>
680 struct is_compatible_array_type
681 {
682  static auto constexpr value =
683  conjunction<negation<std::is_same<void, CompatibleArrayType>>,
684  negation<is_compatible_object_type<
685  BasicJsonType, CompatibleArrayType>>,
686  negation<std::is_constructible<typename BasicJsonType::string_t,
687  CompatibleArrayType>>,
688  negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
689  has_value_type<CompatibleArrayType>,
690  has_iterator<CompatibleArrayType>>::value;
691 };
692 
693 template<bool, typename, typename>
694 struct is_compatible_integer_type_impl : std::false_type {};
695 
696 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
697 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
698 {
699  // is there an assert somewhere on overflows?
700  using RealLimits = std::numeric_limits<RealIntegerType>;
701  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
702 
703  static constexpr auto value =
704  std::is_constructible<RealIntegerType,
705  CompatibleNumberIntegerType>::value and
706  CompatibleLimits::is_integer and
707  RealLimits::is_signed == CompatibleLimits::is_signed;
708 };
709 
710 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
711 struct is_compatible_integer_type
712 {
713  static constexpr auto value =
714  is_compatible_integer_type_impl <
715  std::is_integral<CompatibleNumberIntegerType>::value and
716  not std::is_same<bool, CompatibleNumberIntegerType>::value,
717  RealIntegerType, CompatibleNumberIntegerType > ::value;
718 };
719 
720 
721 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
722 template<typename BasicJsonType, typename T>
723 struct has_from_json
724 {
725  private:
726  // also check the return type of from_json
727  template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
728  std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
729  static int detect(U&&);
730  static void detect(...);
731 
732  public:
733  static constexpr bool value = std::is_integral<decltype(
734  detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
735 };
736 
737 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
738 // this overload is used for non-default-constructible user-defined-types
739 template<typename BasicJsonType, typename T>
740 struct has_non_default_from_json
741 {
742  private:
743  template <
744  typename U,
745  typename = enable_if_t<std::is_same<
746  T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
747  static int detect(U&&);
748  static void detect(...);
749 
750  public:
751  static constexpr bool value = std::is_integral<decltype(detect(
752  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
753 };
754 
755 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
756 template<typename BasicJsonType, typename T>
757 struct has_to_json
758 {
759  private:
760  template<typename U, typename = decltype(uncvref_t<U>::to_json(
761  std::declval<BasicJsonType&>(), std::declval<T>()))>
762  static int detect(U&&);
763  static void detect(...);
764 
765  public:
766  static constexpr bool value = std::is_integral<decltype(detect(
767  std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
768 };
769 
770 
772 // to_json //
774 
775 template<typename BasicJsonType, typename T, enable_if_t<
776  std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
777 void to_json(BasicJsonType& j, T b) noexcept
778 {
779  external_constructor<value_t::boolean>::construct(j, b);
780 }
781 
782 template<typename BasicJsonType, typename CompatibleString,
783  enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
784  CompatibleString>::value, int> = 0>
785 void to_json(BasicJsonType& j, const CompatibleString& s)
786 {
787  external_constructor<value_t::string>::construct(j, s);
788 }
789 
790 template<typename BasicJsonType, typename FloatType,
791  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
792 void to_json(BasicJsonType& j, FloatType val) noexcept
793 {
794  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
795 }
796 
797 template <
798  typename BasicJsonType, typename CompatibleNumberUnsignedType,
799  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
800  CompatibleNumberUnsignedType>::value, int> = 0 >
801 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
802 {
803  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
804 }
805 
806 template <
807  typename BasicJsonType, typename CompatibleNumberIntegerType,
808  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
809  CompatibleNumberIntegerType>::value, int> = 0 >
810 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
811 {
812  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
813 }
814 
815 template<typename BasicJsonType, typename EnumType,
816  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
817 void to_json(BasicJsonType& j, EnumType e) noexcept
818 {
819  using underlying_type = typename std::underlying_type<EnumType>::type;
820  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
821 }
822 
823 template<typename BasicJsonType>
824 void to_json(BasicJsonType& j, const std::vector<bool>& e)
825 {
826  external_constructor<value_t::array>::construct(j, e);
827 }
828 
829 template <
830  typename BasicJsonType, typename CompatibleArrayType,
831  enable_if_t <
832  is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
833  std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
834  int > = 0 >
835 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
836 {
837  external_constructor<value_t::array>::construct(j, arr);
838 }
839 
840 template <
841  typename BasicJsonType, typename CompatibleObjectType,
842  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
843  int> = 0 >
844 void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
845 {
846  external_constructor<value_t::object>::construct(j, arr);
847 }
848 
849 template <typename BasicJsonType, typename T, std::size_t N,
850  enable_if_t<not std::is_constructible<
851  typename BasicJsonType::string_t, T (&)[N]>::value,
852  int> = 0>
853 void to_json(BasicJsonType& j, T (&arr)[N])
854 {
855  external_constructor<value_t::array>::construct(j, arr);
856 }
857 
859 // from_json //
861 
862 // overloads for basic_json template parameters
863 template<typename BasicJsonType, typename ArithmeticType,
864  enable_if_t<std::is_arithmetic<ArithmeticType>::value and
865  not std::is_same<ArithmeticType,
866  typename BasicJsonType::boolean_t>::value,
867  int> = 0>
868 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
869 {
870  switch (static_cast<value_t>(j))
871  {
872  case value_t::number_unsigned:
873  {
874  val = static_cast<ArithmeticType>(
875  *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
876  break;
877  }
878  case value_t::number_integer:
879  {
880  val = static_cast<ArithmeticType>(
881  *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
882  break;
883  }
884  case value_t::number_float:
885  {
886  val = static_cast<ArithmeticType>(
887  *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
888  break;
889  }
890  default:
891  {
892  JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
893  }
894  }
895 }
896 
897 template<typename BasicJsonType>
898 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
899 {
900  if (not j.is_boolean())
901  {
902  JSON_THROW(type_error::create(302, "type must be boolean, but is " + j.type_name()));
903  }
904  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
905 }
906 
907 template<typename BasicJsonType>
908 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
909 {
910  if (not j.is_string())
911  {
912  JSON_THROW(type_error::create(302, "type must be string, but is " + j.type_name()));
913  }
914  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
915 }
916 
917 template<typename BasicJsonType>
918 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
919 {
920  get_arithmetic_value(j, val);
921 }
922 
923 template<typename BasicJsonType>
924 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
925 {
926  get_arithmetic_value(j, val);
927 }
928 
929 template<typename BasicJsonType>
930 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
931 {
932  get_arithmetic_value(j, val);
933 }
934 
935 template<typename BasicJsonType, typename EnumType,
936  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
937 void from_json(const BasicJsonType& j, EnumType& e)
938 {
939  typename std::underlying_type<EnumType>::type val;
940  get_arithmetic_value(j, val);
941  e = static_cast<EnumType>(val);
942 }
943 
944 template<typename BasicJsonType>
945 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
946 {
947  if (not j.is_array())
948  {
949  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
950  }
951  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
952 }
953 
954 // forward_list doesn't have an insert method
955 template<typename BasicJsonType, typename T, typename Allocator,
956  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
957 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
958 {
959  if (not j.is_array())
960  {
961  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
962  }
963 
964  for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
965  {
966  l.push_front(it->template get<T>());
967  }
968 }
969 
970 template<typename BasicJsonType, typename CompatibleArrayType>
971 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
972 {
973  using std::begin;
974  using std::end;
975 
976  std::transform(j.begin(), j.end(),
977  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
978  {
979  // get<BasicJsonType>() returns *this, this won't call a from_json
980  // method when value_type is BasicJsonType
981  return i.template get<typename CompatibleArrayType::value_type>();
982  });
983 }
984 
985 template<typename BasicJsonType, typename CompatibleArrayType>
986 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
987 -> decltype(
988  arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
989  void())
990 {
991  using std::begin;
992  using std::end;
993 
994  arr.reserve(j.size());
995  std::transform(j.begin(), j.end(),
996  std::inserter(arr, end(arr)), [](const BasicJsonType & i)
997  {
998  // get<BasicJsonType>() returns *this, this won't call a from_json
999  // method when value_type is BasicJsonType
1000  return i.template get<typename CompatibleArrayType::value_type>();
1001  });
1002 }
1003 
1004 template<typename BasicJsonType, typename CompatibleArrayType,
1005  enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1006  std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1007  not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
1008 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1009 {
1010  if (not j.is_array())
1011  {
1012  JSON_THROW(type_error::create(302, "type must be array, but is " + j.type_name()));
1013  }
1014 
1015  from_json_array_impl(j, arr, priority_tag<1> {});
1016 }
1017 
1018 template<typename BasicJsonType, typename CompatibleObjectType,
1019  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
1020 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1021 {
1022  if (not j.is_object())
1023  {
1024  JSON_THROW(type_error::create(302, "type must be object, but is " + j.type_name()));
1025  }
1026 
1027  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1028  using std::begin;
1029  using std::end;
1030  // we could avoid the assignment, but this might require a for loop, which
1031  // might be less efficient than the container constructor for some
1032  // containers (would it?)
1033  obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
1034 }
1035 
1036 // overload for arithmetic types, not chosen for basic_json template arguments
1037 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1038 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1039 // an arithmetic type?
1040 template<typename BasicJsonType, typename ArithmeticType,
1041  enable_if_t <
1042  std::is_arithmetic<ArithmeticType>::value and
1043  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1044  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1045  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1046  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1047  int> = 0>
1048 void from_json(const BasicJsonType& j, ArithmeticType& val)
1049 {
1050  switch (static_cast<value_t>(j))
1051  {
1052  case value_t::number_unsigned:
1053  {
1054  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1055  break;
1056  }
1057  case value_t::number_integer:
1058  {
1059  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1060  break;
1061  }
1062  case value_t::number_float:
1063  {
1064  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1065  break;
1066  }
1067  case value_t::boolean:
1068  {
1069  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1070  break;
1071  }
1072  default:
1073  {
1074  JSON_THROW(type_error::create(302, "type must be number, but is " + j.type_name()));
1075  }
1076  }
1077 }
1078 
1079 struct to_json_fn
1080 {
1081  private:
1082  template<typename BasicJsonType, typename T>
1083  auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1084  -> decltype(to_json(j, std::forward<T>(val)), void())
1085  {
1086  return to_json(j, std::forward<T>(val));
1087  }
1088 
1089  template<typename BasicJsonType, typename T>
1090  void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
1091  {
1092  static_assert(sizeof(BasicJsonType) == 0,
1093  "could not find to_json() method in T's namespace");
1094  }
1095 
1096  public:
1097  template<typename BasicJsonType, typename T>
1098  void operator()(BasicJsonType& j, T&& val) const
1099  noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1100  {
1101  return call(j, std::forward<T>(val), priority_tag<1> {});
1102  }
1103 };
1104 
1105 struct from_json_fn
1106 {
1107  private:
1108  template<typename BasicJsonType, typename T>
1109  auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
1110  noexcept(noexcept(from_json(j, val)))
1111  -> decltype(from_json(j, val), void())
1112  {
1113  return from_json(j, val);
1114  }
1115 
1116  template<typename BasicJsonType, typename T>
1117  void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
1118  {
1119  static_assert(sizeof(BasicJsonType) == 0,
1120  "could not find from_json() method in T's namespace");
1121  }
1122 
1123  public:
1124  template<typename BasicJsonType, typename T>
1125  void operator()(const BasicJsonType& j, T& val) const
1126  noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1127  {
1128  return call(j, val, priority_tag<1> {});
1129  }
1130 };
1131 
1132 // taken from ranges-v3
1133 template<typename T>
1134 struct static_const
1135 {
1136  static constexpr T value{};
1137 };
1138 
1139 template<typename T>
1140 constexpr T static_const<T>::value;
1141 } // namespace detail
1142 
1143 
1145 namespace
1146 {
1147 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
1148 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1149 }
1150 
1151 
1159 template<typename = void, typename = void>
1161 {
1171  template<typename BasicJsonType, typename ValueType>
1172  static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
1173  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
1174  {
1175  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
1176  }
1177 
1187  template<typename BasicJsonType, typename ValueType>
1188  static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
1189  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
1190  {
1191  ::nlohmann::to_json(j, std::forward<ValueType>(val));
1192  }
1193 };
1194 
1195 
1277 template <
1278  template<typename U, typename V, typename... Args> class ObjectType = std::map,
1279  template<typename U, typename... Args> class ArrayType = std::vector,
1280  class StringType = std::string,
1281  class BooleanType = bool,
1282  class NumberIntegerType = std::int64_t,
1283  class NumberUnsignedType = std::uint64_t,
1284  class NumberFloatType = double,
1285  template<typename U> class AllocatorType = std::allocator,
1286  template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
1287  >
1289 {
1290  private:
1291  template<detail::value_t> friend struct detail::external_constructor;
1293  using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
1294  BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1295  AllocatorType, JSONSerializer>;
1296 
1297  public:
1298  using value_t = detail::value_t;
1299  // forward declarations
1300  template<typename U> class iter_impl;
1301  template<typename Base> class json_reverse_iterator;
1302  class json_pointer;
1303  template<typename T, typename SFINAE>
1304  using json_serializer = JSONSerializer<T, SFINAE>;
1305 
1306 
1308  // exceptions //
1310 
1314 
1316  using exception = detail::exception;
1318  using parse_error = detail::parse_error;
1320  using invalid_iterator = detail::invalid_iterator;
1322  using type_error = detail::type_error;
1324  using out_of_range = detail::out_of_range;
1326  using other_error = detail::other_error;
1327 
1329 
1330 
1332  // container types //
1334 
1339 
1342 
1346  using const_reference = const value_type&;
1347 
1349  using difference_type = std::ptrdiff_t;
1351  using size_type = std::size_t;
1352 
1354  using allocator_type = AllocatorType<basic_json>;
1355 
1357  using pointer = typename std::allocator_traits<allocator_type>::pointer;
1359  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
1360 
1369 
1371 
1372 
1377  {
1378  return allocator_type();
1379  }
1380 
1404  static basic_json meta()
1405  {
1406  basic_json result;
1407 
1408  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
1409  result["name"] = "JSON for Modern C++";
1410  result["url"] = "https://github.com/nlohmann/json";
1411  result["version"] =
1412  {
1413  {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
1414  };
1415 
1416 #ifdef _WIN32
1417  result["platform"] = "win32";
1418 #elif defined __linux__
1419  result["platform"] = "linux";
1420 #elif defined __APPLE__
1421  result["platform"] = "apple";
1422 #elif defined __unix__
1423  result["platform"] = "unix";
1424 #else
1425  result["platform"] = "unknown";
1426 #endif
1427 
1428 #if defined(__clang__)
1429  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
1430 #elif defined(__ICC) || defined(__INTEL_COMPILER)
1431  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
1432 #elif defined(__GNUC__) || defined(__GNUG__)
1433  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
1434 #elif defined(__HP_cc) || defined(__HP_aCC)
1435  result["compiler"] = "hp"
1436 #elif defined(__IBMCPP__)
1437  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
1438 #elif defined(_MSC_VER)
1439  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
1440 #elif defined(__PGI)
1441  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
1442 #elif defined(__SUNPRO_CC)
1443  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
1444 #else
1445  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
1446 #endif
1447 
1448 #ifdef __cplusplus
1449  result["compiler"]["c++"] = std::to_string(__cplusplus);
1450 #else
1451  result["compiler"]["c++"] = "unknown";
1452 #endif
1453  return result;
1454  }
1455 
1456 
1458  // JSON value data types //
1460 
1465 
1549  using object_t = ObjectType<StringType,
1550  basic_json,
1551  std::less<StringType>,
1552  AllocatorType<std::pair<const StringType,
1553  basic_json>>>;
1554 
1599  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1600 
1652  using string_t = StringType;
1653 
1678  using boolean_t = BooleanType;
1679 
1750  using number_integer_t = NumberIntegerType;
1751 
1821  using number_unsigned_t = NumberUnsignedType;
1822 
1889  using number_float_t = NumberFloatType;
1890 
1892 
1893  private:
1894 
1896  template<typename T, typename... Args>
1897  static T* create(Args&& ... args)
1898  {
1899  AllocatorType<T> alloc;
1900  auto deleter = [&](T * object)
1901  {
1902  alloc.deallocate(object, 1);
1903  };
1904  std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1905  alloc.construct(object.get(), std::forward<Args>(args)...);
1906  assert(object != nullptr);
1907  return object.release();
1908  }
1909 
1911  // JSON value storage //
1913 
1938  union json_value
1939  {
1941  object_t* object;
1943  array_t* array;
1945  string_t* string;
1947  boolean_t boolean;
1949  number_integer_t number_integer;
1951  number_unsigned_t number_unsigned;
1953  number_float_t number_float;
1954 
1956  json_value() = default;
1958  json_value(boolean_t v) noexcept : boolean(v) {}
1960  json_value(number_integer_t v) noexcept : number_integer(v) {}
1962  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
1964  json_value(number_float_t v) noexcept : number_float(v) {}
1966  json_value(value_t t)
1967  {
1968  switch (t)
1969  {
1970  case value_t::object:
1971  {
1972  object = create<object_t>();
1973  break;
1974  }
1975 
1976  case value_t::array:
1977  {
1978  array = create<array_t>();
1979  break;
1980  }
1981 
1982  case value_t::string:
1983  {
1984  string = create<string_t>("");
1985  break;
1986  }
1987 
1988  case value_t::boolean:
1989  {
1990  boolean = boolean_t(false);
1991  break;
1992  }
1993 
1994  case value_t::number_integer:
1995  {
1996  number_integer = number_integer_t(0);
1997  break;
1998  }
1999 
2000  case value_t::number_unsigned:
2001  {
2002  number_unsigned = number_unsigned_t(0);
2003  break;
2004  }
2005 
2006  case value_t::number_float:
2007  {
2008  number_float = number_float_t(0.0);
2009  break;
2010  }
2011 
2012  case value_t::null:
2013  {
2014  break;
2015  }
2016 
2017  default:
2018  {
2019  if (t == value_t::null)
2020  {
2021  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
2022  }
2023  break;
2024  }
2025  }
2026  }
2027 
2029  json_value(const string_t& value)
2030  {
2031  string = create<string_t>(value);
2032  }
2033 
2035  json_value(const object_t& value)
2036  {
2037  object = create<object_t>(value);
2038  }
2039 
2041  json_value(const array_t& value)
2042  {
2043  array = create<array_t>(value);
2044  }
2045  };
2046 
2056  void assert_invariant() const
2057  {
2058  assert(m_type != value_t::object or m_value.object != nullptr);
2059  assert(m_type != value_t::array or m_value.array != nullptr);
2060  assert(m_type != value_t::string or m_value.string != nullptr);
2061  }
2062 
2063  public:
2065  // JSON parser callback //
2067 
2078  enum class parse_event_t : uint8_t
2079  {
2081  object_start,
2083  object_end,
2085  array_start,
2087  array_end,
2089  key,
2091  value
2092  };
2093 
2146  using parser_callback_t = std::function<bool(int depth,
2147  parse_event_t event,
2148  basic_json& parsed)>;
2149 
2150 
2152  // constructors //
2154 
2159 
2184  basic_json(const value_t value_type)
2185  : m_type(value_type), m_value(value_type)
2186  {
2187  assert_invariant();
2188  }
2189 
2208  basic_json(std::nullptr_t = nullptr) noexcept
2209  : basic_json(value_t::null)
2210  {
2211  assert_invariant();
2212  }
2213 
2267  template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
2268  detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
2269  not std::is_same<U, basic_json_t>::value and
2270  not detail::is_basic_json_nested_type<
2271  basic_json_t, U>::value and
2272  detail::has_to_json<basic_json, U>::value,
2273  int> = 0>
2274  basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
2275  std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
2276  {
2277  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
2278  assert_invariant();
2279  }
2280 
2352  basic_json(std::initializer_list<basic_json> init,
2353  bool type_deduction = true,
2354  value_t manual_type = value_t::array)
2355  {
2356  // check if each element is an array with two elements whose first
2357  // element is a string
2358  bool is_an_object = std::all_of(init.begin(), init.end(),
2359  [](const basic_json & element)
2360  {
2361  return element.is_array() and element.size() == 2 and element[0].is_string();
2362  });
2363 
2364  // adjust type if type deduction is not wanted
2365  if (not type_deduction)
2366  {
2367  // if array is wanted, do not create an object though possible
2368  if (manual_type == value_t::array)
2369  {
2370  is_an_object = false;
2371  }
2372 
2373  // if object is wanted but impossible, throw an exception
2374  if (manual_type == value_t::object and not is_an_object)
2375  {
2376  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
2377  }
2378  }
2379 
2380  if (is_an_object)
2381  {
2382  // the initializer list is a list of pairs -> create object
2383  m_type = value_t::object;
2384  m_value = value_t::object;
2385 
2386  std::for_each(init.begin(), init.end(), [this](const basic_json & element)
2387  {
2388  m_value.object->emplace(*(element[0].m_value.string), element[1]);
2389  });
2390  }
2391  else
2392  {
2393  // the initializer list describes an array -> create array
2394  m_type = value_t::array;
2395  m_value.array = create<array_t>(init);
2396  }
2397 
2398  assert_invariant();
2399  }
2400 
2435  static basic_json array(std::initializer_list<basic_json> init =
2436  std::initializer_list<basic_json>())
2437  {
2438  return basic_json(init, false, value_t::array);
2439  }
2440 
2476  static basic_json object(std::initializer_list<basic_json> init =
2477  std::initializer_list<basic_json>())
2478  {
2479  return basic_json(init, false, value_t::object);
2480  }
2481 
2501  : m_type(value_t::array)
2502  {
2503  m_value.array = create<array_t>(cnt, val);
2504  assert_invariant();
2505  }
2506 
2549  template<class InputIT, typename std::enable_if<
2550  std::is_same<InputIT, typename basic_json_t::iterator>::value or
2551  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
2552  basic_json(InputIT first, InputIT last)
2553  {
2554  assert(first.m_object != nullptr);
2555  assert(last.m_object != nullptr);
2556 
2557  // make sure iterator fits the current value
2558  if (first.m_object != last.m_object)
2559  {
2560  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
2561  }
2562 
2563  // copy type from first iterator
2564  m_type = first.m_object->m_type;
2565 
2566  // check if iterator range is complete for primitive values
2567  switch (m_type)
2568  {
2569  case value_t::boolean:
2570  case value_t::number_float:
2571  case value_t::number_integer:
2572  case value_t::number_unsigned:
2573  case value_t::string:
2574  {
2575  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2576  {
2577  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
2578  }
2579  break;
2580  }
2581 
2582  default:
2583  {
2584  break;
2585  }
2586  }
2587 
2588  switch (m_type)
2589  {
2590  case value_t::number_integer:
2591  {
2592  m_value.number_integer = first.m_object->m_value.number_integer;
2593  break;
2594  }
2595 
2596  case value_t::number_unsigned:
2597  {
2598  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2599  break;
2600  }
2601 
2602  case value_t::number_float:
2603  {
2604  m_value.number_float = first.m_object->m_value.number_float;
2605  break;
2606  }
2607 
2608  case value_t::boolean:
2609  {
2610  m_value.boolean = first.m_object->m_value.boolean;
2611  break;
2612  }
2613 
2614  case value_t::string:
2615  {
2616  m_value = *first.m_object->m_value.string;
2617  break;
2618  }
2619 
2620  case value_t::object:
2621  {
2622  m_value.object = create<object_t>(first.m_it.object_iterator,
2623  last.m_it.object_iterator);
2624  break;
2625  }
2626 
2627  case value_t::array:
2628  {
2629  m_value.array = create<array_t>(first.m_it.array_iterator,
2630  last.m_it.array_iterator);
2631  break;
2632  }
2633 
2634  default:
2635  {
2636  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
2637  first.m_object->type_name()));
2638  }
2639  }
2640 
2641  assert_invariant();
2642  }
2643 
2644 
2646  // other constructors and destructor //
2648 
2669  basic_json(const basic_json& other)
2670  : m_type(other.m_type)
2671  {
2672  // check of passed value is valid
2673  other.assert_invariant();
2674 
2675  switch (m_type)
2676  {
2677  case value_t::object:
2678  {
2679  m_value = *other.m_value.object;
2680  break;
2681  }
2682 
2683  case value_t::array:
2684  {
2685  m_value = *other.m_value.array;
2686  break;
2687  }
2688 
2689  case value_t::string:
2690  {
2691  m_value = *other.m_value.string;
2692  break;
2693  }
2694 
2695  case value_t::boolean:
2696  {
2697  m_value = other.m_value.boolean;
2698  break;
2699  }
2700 
2701  case value_t::number_integer:
2702  {
2703  m_value = other.m_value.number_integer;
2704  break;
2705  }
2706 
2707  case value_t::number_unsigned:
2708  {
2709  m_value = other.m_value.number_unsigned;
2710  break;
2711  }
2712 
2713  case value_t::number_float:
2714  {
2715  m_value = other.m_value.number_float;
2716  break;
2717  }
2718 
2719  default:
2720  {
2721  break;
2722  }
2723  }
2724 
2725  assert_invariant();
2726  }
2727 
2746  basic_json(basic_json&& other) noexcept
2747  : m_type(std::move(other.m_type)),
2748  m_value(std::move(other.m_value))
2749  {
2750  // check that passed value is valid
2751  other.assert_invariant();
2752 
2753  // invalidate payload
2754  other.m_type = value_t::null;
2755  other.m_value = {};
2756 
2757  assert_invariant();
2758  }
2759 
2783  reference& operator=(basic_json other) noexcept (
2784  std::is_nothrow_move_constructible<value_t>::value and
2785  std::is_nothrow_move_assignable<value_t>::value and
2786  std::is_nothrow_move_constructible<json_value>::value and
2787  std::is_nothrow_move_assignable<json_value>::value
2788  )
2789  {
2790  // check that passed value is valid
2791  other.assert_invariant();
2792 
2793  using std::swap;
2794  swap(m_type, other.m_type);
2795  swap(m_value, other.m_value);
2796 
2797  assert_invariant();
2798  return *this;
2799  }
2800 
2817  {
2818  assert_invariant();
2819 
2820  switch (m_type)
2821  {
2822  case value_t::object:
2823  {
2824  AllocatorType<object_t> alloc;
2825  alloc.destroy(m_value.object);
2826  alloc.deallocate(m_value.object, 1);
2827  break;
2828  }
2829 
2830  case value_t::array:
2831  {
2832  AllocatorType<array_t> alloc;
2833  alloc.destroy(m_value.array);
2834  alloc.deallocate(m_value.array, 1);
2835  break;
2836  }
2837 
2838  case value_t::string:
2839  {
2840  AllocatorType<string_t> alloc;
2841  alloc.destroy(m_value.string);
2842  alloc.deallocate(m_value.string, 1);
2843  break;
2844  }
2845 
2846  default:
2847  {
2848  // all other types need no specific destructor
2849  break;
2850  }
2851  }
2852  }
2853 
2855 
2856  public:
2858  // object inspection //
2860 
2864 
2888  string_t dump(const int indent = -1) const
2889  {
2890  std::stringstream ss;
2891  serializer s(ss);
2892 
2893  if (indent >= 0)
2894  {
2895  s.dump(*this, true, static_cast<unsigned int>(indent));
2896  }
2897  else
2898  {
2899  s.dump(*this, false, 0);
2900  }
2901 
2902  return ss.str();
2903  }
2904 
2923  constexpr value_t type() const noexcept
2924  {
2925  return m_type;
2926  }
2927 
2953  constexpr bool is_primitive() const noexcept
2954  {
2955  return is_null() or is_string() or is_boolean() or is_number();
2956  }
2957 
2980  constexpr bool is_structured() const noexcept
2981  {
2982  return is_array() or is_object();
2983  }
2984 
3002  constexpr bool is_null() const noexcept
3003  {
3004  return m_type == value_t::null;
3005  }
3006 
3024  constexpr bool is_boolean() const noexcept
3025  {
3026  return m_type == value_t::boolean;
3027  }
3028 
3054  constexpr bool is_number() const noexcept
3055  {
3056  return is_number_integer() or is_number_float();
3057  }
3058 
3083  constexpr bool is_number_integer() const noexcept
3084  {
3085  return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
3086  }
3087 
3111  constexpr bool is_number_unsigned() const noexcept
3112  {
3113  return m_type == value_t::number_unsigned;
3114  }
3115 
3139  constexpr bool is_number_float() const noexcept
3140  {
3141  return m_type == value_t::number_float;
3142  }
3143 
3161  constexpr bool is_object() const noexcept
3162  {
3163  return m_type == value_t::object;
3164  }
3165 
3183  constexpr bool is_array() const noexcept
3184  {
3185  return m_type == value_t::array;
3186  }
3187 
3205  constexpr bool is_string() const noexcept
3206  {
3207  return m_type == value_t::string;
3208  }
3209 
3232  constexpr bool is_discarded() const noexcept
3233  {
3234  return m_type == value_t::discarded;
3235  }
3236 
3255  constexpr operator value_t() const noexcept
3256  {
3257  return m_type;
3258  }
3259 
3261 
3262  private:
3264  // value access //
3266 
3268  boolean_t get_impl(boolean_t* /*unused*/) const
3269  {
3270  if (is_boolean())
3271  {
3272  return m_value.boolean;
3273  }
3274 
3275  JSON_THROW(type_error::create(302, "type must be boolean, but is " + type_name()));
3276  }
3277 
3279  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
3280  {
3281  return is_object() ? m_value.object : nullptr;
3282  }
3283 
3285  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
3286  {
3287  return is_object() ? m_value.object : nullptr;
3288  }
3289 
3291  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
3292  {
3293  return is_array() ? m_value.array : nullptr;
3294  }
3295 
3297  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
3298  {
3299  return is_array() ? m_value.array : nullptr;
3300  }
3301 
3303  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
3304  {
3305  return is_string() ? m_value.string : nullptr;
3306  }
3307 
3309  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
3310  {
3311  return is_string() ? m_value.string : nullptr;
3312  }
3313 
3315  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
3316  {
3317  return is_boolean() ? &m_value.boolean : nullptr;
3318  }
3319 
3321  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
3322  {
3323  return is_boolean() ? &m_value.boolean : nullptr;
3324  }
3325 
3327  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
3328  {
3329  return is_number_integer() ? &m_value.number_integer : nullptr;
3330  }
3331 
3333  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
3334  {
3335  return is_number_integer() ? &m_value.number_integer : nullptr;
3336  }
3337 
3339  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
3340  {
3341  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3342  }
3343 
3345  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
3346  {
3347  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3348  }
3349 
3351  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
3352  {
3353  return is_number_float() ? &m_value.number_float : nullptr;
3354  }
3355 
3357  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
3358  {
3359  return is_number_float() ? &m_value.number_float : nullptr;
3360  }
3361 
3373  template<typename ReferenceType, typename ThisType>
3374  static ReferenceType get_ref_impl(ThisType& obj)
3375  {
3376  // helper type
3377  using PointerType = typename std::add_pointer<ReferenceType>::type;
3378 
3379  // delegate the call to get_ptr<>()
3380  auto ptr = obj.template get_ptr<PointerType>();
3381 
3382  if (ptr != nullptr)
3383  {
3384  return *ptr;
3385  }
3386 
3387  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + obj.type_name()));
3388  }
3389 
3390  public:
3394 
3409  template <
3410  typename BasicJsonType,
3411  detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
3412  basic_json_t>::value,
3413  int> = 0 >
3414  basic_json get() const
3415  {
3416  return *this;
3417  }
3418 
3458  template <
3459  typename ValueTypeCV,
3460  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3461  detail::enable_if_t <
3462  not std::is_same<basic_json_t, ValueType>::value and
3463  detail::has_from_json<basic_json_t, ValueType>::value and
3464  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
3465  int > = 0 >
3466  ValueType get() const noexcept(noexcept(
3467  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3468  {
3469  // we cannot static_assert on ValueTypeCV being non-const, because
3470  // there is support for get<const basic_json_t>(), which is why we
3471  // still need the uncvref
3472  static_assert(not std::is_reference<ValueTypeCV>::value,
3473  "get() cannot be used with reference types, you might want to use get_ref()");
3474  static_assert(std::is_default_constructible<ValueType>::value,
3475  "types must be DefaultConstructible when used with get()");
3476 
3477  ValueType ret;
3478  JSONSerializer<ValueType>::from_json(*this, ret);
3479  return ret;
3480  }
3481 
3513  template <
3514  typename ValueTypeCV,
3515  typename ValueType = detail::uncvref_t<ValueTypeCV>,
3516  detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
3517  detail::has_non_default_from_json<basic_json_t,
3518  ValueType>::value, int> = 0 >
3519  ValueType get() const noexcept(noexcept(
3520  JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
3521  {
3522  static_assert(not std::is_reference<ValueTypeCV>::value,
3523  "get() cannot be used with reference types, you might want to use get_ref()");
3524  return JSONSerializer<ValueTypeCV>::from_json(*this);
3525  }
3526 
3554  template<typename PointerType, typename std::enable_if<
3555  std::is_pointer<PointerType>::value, int>::type = 0>
3556  PointerType get() noexcept
3557  {
3558  // delegate the call to get_ptr
3559  return get_ptr<PointerType>();
3560  }
3561 
3566  template<typename PointerType, typename std::enable_if<
3567  std::is_pointer<PointerType>::value, int>::type = 0>
3568  constexpr const PointerType get() const noexcept
3569  {
3570  // delegate the call to get_ptr
3571  return get_ptr<PointerType>();
3572  }
3573 
3600  template<typename PointerType, typename std::enable_if<
3601  std::is_pointer<PointerType>::value, int>::type = 0>
3602  PointerType get_ptr() noexcept
3603  {
3604  // get the type of the PointerType (remove pointer and const)
3605  using pointee_t = typename std::remove_const<typename
3606  std::remove_pointer<typename
3607  std::remove_const<PointerType>::type>::type>::type;
3608  // make sure the type matches the allowed types
3609  static_assert(
3610  std::is_same<object_t, pointee_t>::value
3611  or std::is_same<array_t, pointee_t>::value
3612  or std::is_same<string_t, pointee_t>::value
3613  or std::is_same<boolean_t, pointee_t>::value
3614  or std::is_same<number_integer_t, pointee_t>::value
3615  or std::is_same<number_unsigned_t, pointee_t>::value
3616  or std::is_same<number_float_t, pointee_t>::value
3617  , "incompatible pointer type");
3618 
3619  // delegate the call to get_impl_ptr<>()
3620  return get_impl_ptr(static_cast<PointerType>(nullptr));
3621  }
3622 
3627  template<typename PointerType, typename std::enable_if<
3628  std::is_pointer<PointerType>::value and
3629  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
3630  constexpr const PointerType get_ptr() const noexcept
3631  {
3632  // get the type of the PointerType (remove pointer and const)
3633  using pointee_t = typename std::remove_const<typename
3634  std::remove_pointer<typename
3635  std::remove_const<PointerType>::type>::type>::type;
3636  // make sure the type matches the allowed types
3637  static_assert(
3638  std::is_same<object_t, pointee_t>::value
3639  or std::is_same<array_t, pointee_t>::value
3640  or std::is_same<string_t, pointee_t>::value
3641  or std::is_same<boolean_t, pointee_t>::value
3642  or std::is_same<number_integer_t, pointee_t>::value
3643  or std::is_same<number_unsigned_t, pointee_t>::value
3644  or std::is_same<number_float_t, pointee_t>::value
3645  , "incompatible pointer type");
3646 
3647  // delegate the call to get_impl_ptr<>() const
3648  return get_impl_ptr(static_cast<const PointerType>(nullptr));
3649  }
3650 
3677  template<typename ReferenceType, typename std::enable_if<
3678  std::is_reference<ReferenceType>::value, int>::type = 0>
3679  ReferenceType get_ref()
3680  {
3681  // delegate call to get_ref_impl
3682  return get_ref_impl<ReferenceType>(*this);
3683  }
3684 
3689  template<typename ReferenceType, typename std::enable_if<
3690  std::is_reference<ReferenceType>::value and
3691  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
3692  ReferenceType get_ref() const
3693  {
3694  // delegate call to get_ref_impl
3695  return get_ref_impl<ReferenceType>(*this);
3696  }
3697 
3727  template < typename ValueType, typename std::enable_if <
3728  not std::is_pointer<ValueType>::value and
3729  not std::is_same<ValueType, typename string_t::value_type>::value
3730 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
3731  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3732 #endif
3733 #if defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1 // fix for issue #464
3734  and not std::is_same<ValueType, typename std::string_view>::value
3735 #endif
3736  , int >::type = 0 >
3737  operator ValueType() const
3738  {
3739  // delegate the call to get<>() const
3740  return get<ValueType>();
3741  }
3742 
3744 
3745 
3747  // element access //
3749 
3753 
3781  {
3782  // at only works for arrays
3783  if (is_array())
3784  {
3785  JSON_TRY
3786  {
3787  return m_value.array->at(idx);
3788  }
3789  JSON_CATCH (std::out_of_range&)
3790  {
3791  // create better exception explanation
3792  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3793  }
3794  }
3795  else
3796  {
3797  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3798  }
3799  }
3800 
3827  const_reference at(size_type idx) const
3828  {
3829  // at only works for arrays
3830  if (is_array())
3831  {
3832  JSON_TRY
3833  {
3834  return m_value.array->at(idx);
3835  }
3836  JSON_CATCH (std::out_of_range&)
3837  {
3838  // create better exception explanation
3839  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
3840  }
3841  }
3842  else
3843  {
3844  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3845  }
3846  }
3847 
3878  reference at(const typename object_t::key_type& key)
3879  {
3880  // at only works for objects
3881  if (is_object())
3882  {
3883  JSON_TRY
3884  {
3885  return m_value.object->at(key);
3886  }
3887  JSON_CATCH (std::out_of_range&)
3888  {
3889  // create better exception explanation
3890  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3891  }
3892  }
3893  else
3894  {
3895  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3896  }
3897  }
3898 
3929  const_reference at(const typename object_t::key_type& key) const
3930  {
3931  // at only works for objects
3932  if (is_object())
3933  {
3934  JSON_TRY
3935  {
3936  return m_value.object->at(key);
3937  }
3938  JSON_CATCH (std::out_of_range&)
3939  {
3940  // create better exception explanation
3941  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
3942  }
3943  }
3944  else
3945  {
3946  JSON_THROW(type_error::create(304, "cannot use at() with " + type_name()));
3947  }
3948  }
3949 
3975  reference operator[](size_type idx)
3976  {
3977  // implicitly convert null value to an empty array
3978  if (is_null())
3979  {
3980  m_type = value_t::array;
3981  m_value.array = create<array_t>();
3982  assert_invariant();
3983  }
3984 
3985  // operator[] only works for arrays
3986  if (is_array())
3987  {
3988  // fill up array with null values if given idx is outside range
3989  if (idx >= m_value.array->size())
3990  {
3991  m_value.array->insert(m_value.array->end(),
3992  idx - m_value.array->size() + 1,
3993  basic_json());
3994  }
3995 
3996  return m_value.array->operator[](idx);
3997  }
3998 
3999  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4000  }
4001 
4021  const_reference operator[](size_type idx) const
4022  {
4023  // const operator[] only works for arrays
4024  if (is_array())
4025  {
4026  return m_value.array->operator[](idx);
4027  }
4028 
4029  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4030  }
4031 
4059  reference operator[](const typename object_t::key_type& key)
4060  {
4061  // implicitly convert null value to an empty object
4062  if (is_null())
4063  {
4064  m_type = value_t::object;
4065  m_value.object = create<object_t>();
4066  assert_invariant();
4067  }
4068 
4069  // operator[] only works for objects
4070  if (is_object())
4071  {
4072  return m_value.object->operator[](key);
4073  }
4074 
4075  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4076  }
4077 
4108  const_reference operator[](const typename object_t::key_type& key) const
4109  {
4110  // const operator[] only works for objects
4111  if (is_object())
4112  {
4113  assert(m_value.object->find(key) != m_value.object->end());
4114  return m_value.object->find(key)->second;
4115  }
4117  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4118  }
4119 
4147  template<typename T, std::size_t n>
4148  reference operator[](T * (&key)[n])
4149  {
4150  return operator[](static_cast<const T>(key));
4151  }
4152 
4182  template<typename T, std::size_t n>
4183  const_reference operator[](T * (&key)[n]) const
4184  {
4185  return operator[](static_cast<const T>(key));
4186  }
4187 
4215  template<typename T>
4216  reference operator[](T* key)
4217  {
4218  // implicitly convert null to object
4219  if (is_null())
4220  {
4221  m_type = value_t::object;
4222  m_value = value_t::object;
4223  assert_invariant();
4224  }
4225 
4226  // at only works for objects
4227  if (is_object())
4228  {
4229  return m_value.object->operator[](key);
4230  }
4231 
4232  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4233  }
4234 
4265  template<typename T>
4266  const_reference operator[](T* key) const
4267  {
4268  // at only works for objects
4269  if (is_object())
4270  {
4271  assert(m_value.object->find(key) != m_value.object->end());
4272  return m_value.object->find(key)->second;
4273  }
4275  JSON_THROW(type_error::create(305, "cannot use operator[] with " + type_name()));
4276  }
4277 
4326  template<class ValueType, typename std::enable_if<
4327  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4328  ValueType value(const typename object_t::key_type& key, ValueType default_value) const
4329  {
4330  // at only works for objects
4331  if (is_object())
4332  {
4333  // if key is found, return value and given default value otherwise
4334  const auto it = find(key);
4335  if (it != end())
4336  {
4337  return *it;
4338  }
4339 
4340  return default_value;
4341  }
4342  else
4343  {
4344  JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
4345  }
4346  }
4347 
4352  string_t value(const typename object_t::key_type& key, const char* default_value) const
4353  {
4354  return value(key, string_t(default_value));
4355  }
4356 
4398  template<class ValueType, typename std::enable_if<
4399  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4400  ValueType value(const json_pointer& ptr, ValueType default_value) const
4401  {
4402  // at only works for objects
4403  if (is_object())
4404  {
4405  // if pointer resolves a value, return it or use default value
4406  JSON_TRY
4407  {
4408  return ptr.get_checked(this);
4409  }
4410  JSON_CATCH (out_of_range&)
4411  {
4412  return default_value;
4413  }
4414  }
4415 
4416  JSON_THROW(type_error::create(306, "cannot use value() with " + type_name()));
4417  }
4418 
4423  string_t value(const json_pointer& ptr, const char* default_value) const
4424  {
4425  return value(ptr, string_t(default_value));
4426  }
4427 
4453  reference front()
4454  {
4455  return *begin();
4456  }
4457 
4462  {
4463  return *cbegin();
4464  }
4465 
4497  reference back()
4498  {
4499  auto tmp = end();
4500  --tmp;
4501  return *tmp;
4502  }
4503 
4507  const_reference back() const
4508  {
4509  auto tmp = cend();
4510  --tmp;
4511  return *tmp;
4512  }
4513 
4560  template<class IteratorType, typename std::enable_if<
4561  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4562  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4563  = 0>
4564  IteratorType erase(IteratorType pos)
4565  {
4566  // make sure iterator fits the current value
4567  if (this != pos.m_object)
4568  {
4569  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
4570  }
4571 
4572  IteratorType result = end();
4573 
4574  switch (m_type)
4575  {
4576  case value_t::boolean:
4577  case value_t::number_float:
4578  case value_t::number_integer:
4579  case value_t::number_unsigned:
4580  case value_t::string:
4581  {
4582  if (not pos.m_it.primitive_iterator.is_begin())
4583  {
4584  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
4585  }
4586 
4587  if (is_string())
4588  {
4589  AllocatorType<string_t> alloc;
4590  alloc.destroy(m_value.string);
4591  alloc.deallocate(m_value.string, 1);
4592  m_value.string = nullptr;
4593  }
4594 
4595  m_type = value_t::null;
4596  assert_invariant();
4597  break;
4598  }
4599 
4600  case value_t::object:
4601  {
4602  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4603  break;
4604  }
4605 
4606  case value_t::array:
4607  {
4608  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4609  break;
4610  }
4611 
4612  default:
4613  {
4614  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4615  }
4616  }
4617 
4618  return result;
4619  }
4620 
4667  template<class IteratorType, typename std::enable_if<
4668  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4669  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4670  = 0>
4671  IteratorType erase(IteratorType first, IteratorType last)
4672  {
4673  // make sure iterator fits the current value
4674  if (this != first.m_object or this != last.m_object)
4675  {
4676  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
4677  }
4678 
4679  IteratorType result = end();
4680 
4681  switch (m_type)
4682  {
4683  case value_t::boolean:
4684  case value_t::number_float:
4685  case value_t::number_integer:
4686  case value_t::number_unsigned:
4687  case value_t::string:
4688  {
4689  if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4690  {
4691  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
4692  }
4693 
4694  if (is_string())
4695  {
4696  AllocatorType<string_t> alloc;
4697  alloc.destroy(m_value.string);
4698  alloc.deallocate(m_value.string, 1);
4699  m_value.string = nullptr;
4700  }
4701 
4702  m_type = value_t::null;
4703  assert_invariant();
4704  break;
4705  }
4706 
4707  case value_t::object:
4708  {
4709  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4710  last.m_it.object_iterator);
4711  break;
4712  }
4713 
4714  case value_t::array:
4715  {
4716  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4717  last.m_it.array_iterator);
4718  break;
4719  }
4720 
4721  default:
4722  {
4723  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4724  }
4725  }
4726 
4727  return result;
4728  }
4729 
4759  size_type erase(const typename object_t::key_type& key)
4760  {
4761  // this erase only works for objects
4762  if (is_object())
4763  {
4764  return m_value.object->erase(key);
4765  }
4766 
4767  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4768  }
4769 
4794  void erase(const size_type idx)
4795  {
4796  // this erase only works for arrays
4797  if (is_array())
4798  {
4799  if (idx >= size())
4800  {
4801  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
4802  }
4803 
4804  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4805  }
4806  else
4807  {
4808  JSON_THROW(type_error::create(307, "cannot use erase() with " + type_name()));
4809  }
4810  }
4811 
4813 
4814 
4816  // lookup //
4818 
4821 
4844  iterator find(typename object_t::key_type key)
4845  {
4846  auto result = end();
4847 
4848  if (is_object())
4849  {
4850  result.m_it.object_iterator = m_value.object->find(key);
4851  }
4853  return result;
4854  }
4855 
4860  const_iterator find(typename object_t::key_type key) const
4861  {
4862  auto result = cend();
4863 
4864  if (is_object())
4865  {
4866  result.m_it.object_iterator = m_value.object->find(key);
4867  }
4869  return result;
4870  }
4871 
4893  size_type count(typename object_t::key_type key) const
4894  {
4895  // return 0 for all nonobject types
4896  return is_object() ? m_value.object->count(key) : 0;
4897  }
4898 
4900 
4903  // iterators //
4905 
4908 
4933  iterator begin() noexcept
4934  {
4935  iterator result(this);
4936  result.set_begin();
4937  return result;
4938  }
4939 
4943  const_iterator begin() const noexcept
4944  {
4945  return cbegin();
4946  }
4947 
4973  const_iterator cbegin() const noexcept
4974  {
4975  const_iterator result(this);
4976  result.set_begin();
4977  return result;
4978  }
4979 
5004  iterator end() noexcept
5005  {
5006  iterator result(this);
5007  result.set_end();
5008  return result;
5009  }
5010 
5014  const_iterator end() const noexcept
5015  {
5016  return cend();
5017  }
5018 
5044  const_iterator cend() const noexcept
5045  {
5046  const_iterator result(this);
5047  result.set_end();
5048  return result;
5049  }
5050 
5074  reverse_iterator rbegin() noexcept
5075  {
5076  return reverse_iterator(end());
5077  }
5078 
5083  {
5084  return crbegin();
5085  }
5086 
5111  reverse_iterator rend() noexcept
5112  {
5113  return reverse_iterator(begin());
5114  }
5115 
5119  const_reverse_iterator rend() const noexcept
5120  {
5121  return crend();
5122  }
5123 
5148  const_reverse_iterator crbegin() const noexcept
5149  {
5150  return const_reverse_iterator(cend());
5151  }
5152 
5177  const_reverse_iterator crend() const noexcept
5178  {
5179  return const_reverse_iterator(cbegin());
5180  }
5181 
5182  private:
5183  // forward declaration
5184  template<typename IteratorType> class iteration_proxy;
5186  public:
5198  static iteration_proxy<iterator> iterator_wrapper(reference cont)
5199  {
5200  return iteration_proxy<iterator>(cont);
5201  }
5202 
5206  static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
5207  {
5208  return iteration_proxy<const_iterator>(cont);
5209  }
5210 
5212 
5213 
5215  // capacity //
5217 
5220 
5258  bool empty() const noexcept
5259  {
5260  switch (m_type)
5261  {
5262  case value_t::null:
5263  {
5264  // null values are empty
5265  return true;
5266  }
5267 
5268  case value_t::array:
5269  {
5270  // delegate call to array_t::empty()
5271  return m_value.array->empty();
5272  }
5273 
5274  case value_t::object:
5275  {
5276  // delegate call to object_t::empty()
5277  return m_value.object->empty();
5278  }
5279 
5280  default:
5281  {
5282  // all other types are nonempty
5283  return false;
5284  }
5285  }
5286  }
5287 
5326  size_type size() const noexcept
5327  {
5328  switch (m_type)
5329  {
5330  case value_t::null:
5331  {
5332  // null values are empty
5333  return 0;
5334  }
5335 
5336  case value_t::array:
5337  {
5338  // delegate call to array_t::size()
5339  return m_value.array->size();
5340  }
5341 
5342  case value_t::object:
5343  {
5344  // delegate call to object_t::size()
5345  return m_value.object->size();
5346  }
5347 
5348  default:
5349  {
5350  // all other types have size 1
5351  return 1;
5352  }
5353  }
5354  }
5355 
5392  size_type max_size() const noexcept
5393  {
5394  switch (m_type)
5395  {
5396  case value_t::array:
5397  {
5398  // delegate call to array_t::max_size()
5399  return m_value.array->max_size();
5400  }
5401 
5402  case value_t::object:
5403  {
5404  // delegate call to object_t::max_size()
5405  return m_value.object->max_size();
5406  }
5407 
5408  default:
5409  {
5410  // all other types have max_size() == size()
5411  return size();
5412  }
5413  }
5414  }
5415 
5417 
5418 
5420  // modifiers //
5422 
5425 
5448  void clear() noexcept
5449  {
5450  switch (m_type)
5451  {
5452  case value_t::number_integer:
5453  {
5454  m_value.number_integer = 0;
5455  break;
5456  }
5457 
5458  case value_t::number_unsigned:
5459  {
5460  m_value.number_unsigned = 0;
5461  break;
5462  }
5463 
5464  case value_t::number_float:
5465  {
5466  m_value.number_float = 0.0;
5467  break;
5468  }
5469 
5470  case value_t::boolean:
5471  {
5472  m_value.boolean = false;
5473  break;
5474  }
5475 
5476  case value_t::string:
5477  {
5478  m_value.string->clear();
5479  break;
5480  }
5481 
5482  case value_t::array:
5483  {
5484  m_value.array->clear();
5485  break;
5486  }
5487 
5488  case value_t::object:
5489  {
5490  m_value.object->clear();
5491  break;
5492  }
5493 
5494  default:
5495  {
5496  break;
5497  }
5498  }
5499  }
5500 
5521  void push_back(basic_json&& val)
5522  {
5523  // push_back only works for null objects or arrays
5524  if (not(is_null() or is_array()))
5525  {
5526  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5527  }
5528 
5529  // transform null object into an array
5530  if (is_null())
5531  {
5532  m_type = value_t::array;
5533  m_value = value_t::array;
5534  assert_invariant();
5535  }
5536 
5537  // add element to array (move semantics)
5538  m_value.array->push_back(std::move(val));
5539  // invalidate object
5540  val.m_type = value_t::null;
5541  }
5542 
5547  reference operator+=(basic_json&& val)
5548  {
5549  push_back(std::move(val));
5550  return *this;
5551  }
5552 
5557  void push_back(const basic_json& val)
5558  {
5559  // push_back only works for null objects or arrays
5560  if (not(is_null() or is_array()))
5561  {
5562  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5563  }
5564 
5565  // transform null object into an array
5566  if (is_null())
5567  {
5568  m_type = value_t::array;
5569  m_value = value_t::array;
5570  assert_invariant();
5571  }
5572 
5573  // add element to array
5574  m_value.array->push_back(val);
5575  }
5576 
5581  reference operator+=(const basic_json& val)
5582  {
5583  push_back(val);
5584  return *this;
5585  }
5586 
5607  void push_back(const typename object_t::value_type& val)
5608  {
5609  // push_back only works for null objects or objects
5610  if (not(is_null() or is_object()))
5611  {
5612  JSON_THROW(type_error::create(308, "cannot use push_back() with " + type_name()));
5613  }
5614 
5615  // transform null object into an object
5616  if (is_null())
5617  {
5618  m_type = value_t::object;
5619  m_value = value_t::object;
5620  assert_invariant();
5621  }
5622 
5623  // add element to array
5624  m_value.object->insert(val);
5625  }
5626 
5631  reference operator+=(const typename object_t::value_type& val)
5632  {
5633  push_back(val);
5634  return *this;
5635  }
5636 
5662  void push_back(std::initializer_list<basic_json> init)
5663  {
5664  if (is_object() and init.size() == 2 and init.begin()->is_string())
5665  {
5666  const string_t key = *init.begin();
5667  push_back(typename object_t::value_type(key, *(init.begin() + 1)));
5668  }
5669  else
5670  {
5671  push_back(basic_json(init));
5672  }
5673  }
5674 
5679  reference operator+=(std::initializer_list<basic_json> init)
5680  {
5681  push_back(init);
5682  return *this;
5683  }
5684 
5706  template<class... Args>
5707  void emplace_back(Args&& ... args)
5708  {
5709  // emplace_back only works for null objects or arrays
5710  if (not(is_null() or is_array()))
5711  {
5712  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + type_name()));
5713  }
5714 
5715  // transform null object into an array
5716  if (is_null())
5717  {
5718  m_type = value_t::array;
5719  m_value = value_t::array;
5720  assert_invariant();
5721  }
5722 
5723  // add element to array (perfect forwarding)
5724  m_value.array->emplace_back(std::forward<Args>(args)...);
5725  }
5726 
5754  template<class... Args>
5755  std::pair<iterator, bool> emplace(Args&& ... args)
5756  {
5757  // emplace only works for null objects or arrays
5758  if (not(is_null() or is_object()))
5759  {
5760  JSON_THROW(type_error::create(311, "cannot use emplace() with " + type_name()));
5761  }
5762 
5763  // transform null object into an object
5764  if (is_null())
5765  {
5766  m_type = value_t::object;
5767  m_value = value_t::object;
5768  assert_invariant();
5769  }
5770 
5771  // add element to array (perfect forwarding)
5772  auto res = m_value.object->emplace(std::forward<Args>(args)...);
5773  // create result iterator and set iterator to the result of emplace
5774  auto it = begin();
5775  it.m_it.object_iterator = res.first;
5776 
5777  // return pair of iterator and boolean
5778  return {it, res.second};
5779  }
5780 
5803  iterator insert(const_iterator pos, const basic_json& val)
5804  {
5805  // insert only works for arrays
5806  if (is_array())
5807  {
5808  // check if iterator pos fits to this JSON value
5809  if (pos.m_object != this)
5810  {
5811  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5812  }
5813 
5814  // insert to array and return iterator
5815  iterator result(this);
5816  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5817  return result;
5818  }
5819 
5820  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5821  }
5822 
5827  iterator insert(const_iterator pos, basic_json&& val)
5828  {
5829  return insert(pos, val);
5830  }
5831 
5856  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
5857  {
5858  // insert only works for arrays
5859  if (is_array())
5860  {
5861  // check if iterator pos fits to this JSON value
5862  if (pos.m_object != this)
5863  {
5864  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5865  }
5866 
5867  // insert to array and return iterator
5868  iterator result(this);
5869  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5870  return result;
5871  }
5872 
5873  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5874  }
5875 
5906  iterator insert(const_iterator pos, const_iterator first, const_iterator last)
5907  {
5908  // insert only works for arrays
5909  if (not is_array())
5910  {
5911  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5912  }
5913 
5914  // check if iterator pos fits to this JSON value
5915  if (pos.m_object != this)
5916  {
5917  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5918  }
5919 
5920  // check if range iterators belong to the same JSON object
5921  if (first.m_object != last.m_object)
5922  {
5923  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
5924  }
5925 
5926  if (first.m_object == this or last.m_object == this)
5927  {
5928  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
5929  }
5930 
5931  // insert to array and return iterator
5932  iterator result(this);
5933  result.m_it.array_iterator = m_value.array->insert(
5934  pos.m_it.array_iterator,
5935  first.m_it.array_iterator,
5936  last.m_it.array_iterator);
5937  return result;
5938  }
5939 
5964  iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
5965  {
5966  // insert only works for arrays
5967  if (not is_array())
5968  {
5969  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
5970  }
5971 
5972  // check if iterator pos fits to this JSON value
5973  if (pos.m_object != this)
5974  {
5975  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5976  }
5977 
5978  // insert to array and return iterator
5979  iterator result(this);
5980  result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5981  return result;
5982  }
5983 
6007  void insert(const_iterator first, const_iterator last)
6008  {
6009  // insert only works for objects
6010  if (not is_object())
6011  {
6012  JSON_THROW(type_error::create(309, "cannot use insert() with " + type_name()));
6013  }
6014 
6015  // check if range iterators belong to the same JSON object
6016  if (first.m_object != last.m_object)
6017  {
6018  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
6019  }
6020 
6021  // passed iterators must belong to objects
6022  if (not first.m_object->is_object() or not first.m_object->is_object())
6023  {
6024  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
6025  }
6026 
6027  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
6028  }
6029 
6047  void swap(reference other) noexcept (
6048  std::is_nothrow_move_constructible<value_t>::value and
6049  std::is_nothrow_move_assignable<value_t>::value and
6050  std::is_nothrow_move_constructible<json_value>::value and
6051  std::is_nothrow_move_assignable<json_value>::value
6052  )
6053  {
6054  std::swap(m_type, other.m_type);
6055  std::swap(m_value, other.m_value);
6056  assert_invariant();
6057  }
6058 
6079  void swap(array_t& other)
6080  {
6081  // swap only works for arrays
6082  if (is_array())
6083  {
6084  std::swap(*(m_value.array), other);
6085  }
6086  else
6087  {
6088  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6089  }
6090  }
6091 
6112  void swap(object_t& other)
6113  {
6114  // swap only works for objects
6115  if (is_object())
6116  {
6117  std::swap(*(m_value.object), other);
6118  }
6119  else
6120  {
6121  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6122  }
6123  }
6124 
6145  void swap(string_t& other)
6146  {
6147  // swap only works for strings
6148  if (is_string())
6149  {
6150  std::swap(*(m_value.string), other);
6151  }
6152  else
6153  {
6154  JSON_THROW(type_error::create(310, "cannot use swap() with " + type_name()));
6155  }
6156  }
6157 
6159 
6160  public:
6162  // lexicographical comparison operators //
6164 
6167 
6195  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
6196  {
6197  const auto lhs_type = lhs.type();
6198  const auto rhs_type = rhs.type();
6199 
6200  if (lhs_type == rhs_type)
6201  {
6202  switch (lhs_type)
6203  {
6204  case value_t::array:
6205  {
6206  return *lhs.m_value.array == *rhs.m_value.array;
6207  }
6208  case value_t::object:
6209  {
6210  return *lhs.m_value.object == *rhs.m_value.object;
6211  }
6212  case value_t::null:
6213  {
6214  return true;
6215  }
6216  case value_t::string:
6217  {
6218  return *lhs.m_value.string == *rhs.m_value.string;
6219  }
6220  case value_t::boolean:
6221  {
6222  return lhs.m_value.boolean == rhs.m_value.boolean;
6223  }
6224  case value_t::number_integer:
6225  {
6226  return lhs.m_value.number_integer == rhs.m_value.number_integer;
6227  }
6228  case value_t::number_unsigned:
6229  {
6230  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
6231  }
6232  case value_t::number_float:
6233  {
6234  return lhs.m_value.number_float == rhs.m_value.number_float;
6235  }
6236  default:
6237  {
6238  return false;
6239  }
6240  }
6241  }
6242  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6243  {
6244  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
6245  }
6246  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6247  {
6248  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
6249  }
6250  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6251  {
6252  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
6253  }
6254  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6255  {
6256  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
6257  }
6258  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6259  {
6260  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
6261  }
6262  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6263  {
6264  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6265  }
6266 
6267  return false;
6268  }
6269 
6274  template<typename ScalarType, typename std::enable_if<
6275  std::is_scalar<ScalarType>::value, int>::type = 0>
6276  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
6277  {
6278  return (lhs == basic_json(rhs));
6279  }
6280 
6285  template<typename ScalarType, typename std::enable_if<
6286  std::is_scalar<ScalarType>::value, int>::type = 0>
6287  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
6288  {
6289  return (basic_json(lhs) == rhs);
6290  }
6291 
6308  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
6309  {
6310  return not (lhs == rhs);
6311  }
6312 
6317  template<typename ScalarType, typename std::enable_if<
6318  std::is_scalar<ScalarType>::value, int>::type = 0>
6319  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
6320  {
6321  return (lhs != basic_json(rhs));
6322  }
6323 
6328  template<typename ScalarType, typename std::enable_if<
6329  std::is_scalar<ScalarType>::value, int>::type = 0>
6330  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
6331  {
6332  return (basic_json(lhs) != rhs);
6333  }
6334 
6359  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6360  {
6361  const auto lhs_type = lhs.type();
6362  const auto rhs_type = rhs.type();
6363 
6364  if (lhs_type == rhs_type)
6365  {
6366  switch (lhs_type)
6367  {
6368  case value_t::array:
6369  {
6370  return *lhs.m_value.array < *rhs.m_value.array;
6371  }
6372  case value_t::object:
6373  {
6374  return *lhs.m_value.object < *rhs.m_value.object;
6375  }
6376  case value_t::null:
6377  {
6378  return false;
6379  }
6380  case value_t::string:
6381  {
6382  return *lhs.m_value.string < *rhs.m_value.string;
6383  }
6384  case value_t::boolean:
6385  {
6386  return lhs.m_value.boolean < rhs.m_value.boolean;
6387  }
6388  case value_t::number_integer:
6389  {
6390  return lhs.m_value.number_integer < rhs.m_value.number_integer;
6391  }
6392  case value_t::number_unsigned:
6393  {
6394  return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6395  }
6396  case value_t::number_float:
6397  {
6398  return lhs.m_value.number_float < rhs.m_value.number_float;
6399  }
6400  default:
6401  {
6402  return false;
6403  }
6404  }
6405  }
6406  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6407  {
6408  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6409  }
6410  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6411  {
6412  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6413  }
6414  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6415  {
6416  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6417  }
6418  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6419  {
6420  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6421  }
6422  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6423  {
6424  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6425  }
6426  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6427  {
6428  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6429  }
6430 
6431  // We only reach this line if we cannot compare values. In that case,
6432  // we compare types. Note we have to call the operator explicitly,
6433  // because MSVC has problems otherwise.
6434  return operator<(lhs_type, rhs_type);
6435  }
6436 
6441  template<typename ScalarType, typename std::enable_if<
6442  std::is_scalar<ScalarType>::value, int>::type = 0>
6443  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
6444  {
6445  return (lhs < basic_json(rhs));
6446  }
6447 
6452  template<typename ScalarType, typename std::enable_if<
6453  std::is_scalar<ScalarType>::value, int>::type = 0>
6454  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
6455  {
6456  return (basic_json(lhs) < rhs);
6457  }
6458 
6476  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6477  {
6478  return not (rhs < lhs);
6479  }
6480 
6485  template<typename ScalarType, typename std::enable_if<
6486  std::is_scalar<ScalarType>::value, int>::type = 0>
6487  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
6488  {
6489  return (lhs <= basic_json(rhs));
6490  }
6491 
6496  template<typename ScalarType, typename std::enable_if<
6497  std::is_scalar<ScalarType>::value, int>::type = 0>
6498  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
6499  {
6500  return (basic_json(lhs) <= rhs);
6501  }
6502 
6520  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6521  {
6522  return not (lhs <= rhs);
6523  }
6524 
6529  template<typename ScalarType, typename std::enable_if<
6530  std::is_scalar<ScalarType>::value, int>::type = 0>
6531  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
6532  {
6533  return (lhs > basic_json(rhs));
6534  }
6535 
6540  template<typename ScalarType, typename std::enable_if<
6541  std::is_scalar<ScalarType>::value, int>::type = 0>
6542  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
6543  {
6544  return (basic_json(lhs) > rhs);
6545  }
6546 
6564  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6565  {
6566  return not (lhs < rhs);
6567  }
6568 
6573  template<typename ScalarType, typename std::enable_if<
6574  std::is_scalar<ScalarType>::value, int>::type = 0>
6575  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
6576  {
6577  return (lhs >= basic_json(rhs));
6578  }
6579 
6584  template<typename ScalarType, typename std::enable_if<
6585  std::is_scalar<ScalarType>::value, int>::type = 0>
6586  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
6587  {
6588  return (basic_json(lhs) >= rhs);
6589  }
6590 
6592 
6593 
6595  // serialization //
6597 
6600 
6601  private:
6605  class serializer
6606  {
6607  private:
6608  serializer(const serializer&) = delete;
6609  serializer& operator=(const serializer&) = delete;
6610 
6611  public:
6615  serializer(std::ostream& s)
6616  : o(s), loc(std::localeconv()),
6617  thousands_sep(!loc->thousands_sep ? '\0' : loc->thousands_sep[0]),
6618  decimal_point(!loc->decimal_point ? '\0' : loc->decimal_point[0])
6619  {}
6620 
6638  void dump(const basic_json& val,
6639  const bool pretty_print,
6640  const unsigned int indent_step,
6641  const unsigned int current_indent = 0)
6642  {
6643  switch (val.m_type)
6644  {
6645  case value_t::object:
6646  {
6647  if (val.m_value.object->empty())
6648  {
6649  o.write("{}", 2);
6650  return;
6651  }
6652 
6653  if (pretty_print)
6654  {
6655  o.write("{\n", 2);
6656 
6657  // variable to hold indentation for recursive calls
6658  const auto new_indent = current_indent + indent_step;
6659  if (indent_string.size() < new_indent)
6660  {
6661  indent_string.resize(new_indent, ' ');
6662  }
6663 
6664  // first n-1 elements
6665  auto i = val.m_value.object->cbegin();
6666  for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6667  {
6668  o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
6669  o.put('\"');
6670  dump_escaped(i->first);
6671  o.write("\": ", 3);
6672  dump(i->second, true, indent_step, new_indent);
6673  o.write(",\n", 2);
6674  }
6675 
6676  // last element
6677  assert(i != val.m_value.object->cend());
6678  o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
6679  o.put('\"');
6680  dump_escaped(i->first);
6681  o.write("\": ", 3);
6682  dump(i->second, true, indent_step, new_indent);
6683 
6684  o.put('\n');
6685  o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
6686  o.put('}');
6687  }
6688  else
6689  {
6690  o.put('{');
6691 
6692  // first n-1 elements
6693  auto i = val.m_value.object->cbegin();
6694  for (size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6695  {
6696  o.put('\"');
6697  dump_escaped(i->first);
6698  o.write("\":", 2);
6699  dump(i->second, false, indent_step, current_indent);
6700  o.put(',');
6701  }
6702 
6703  // last element
6704  assert(i != val.m_value.object->cend());
6705  o.put('\"');
6706  dump_escaped(i->first);
6707  o.write("\":", 2);
6708  dump(i->second, false, indent_step, current_indent);
6709 
6710  o.put('}');
6711  }
6712 
6713  return;
6714  }
6715 
6716  case value_t::array:
6717  {
6718  if (val.m_value.array->empty())
6719  {
6720  o.write("[]", 2);
6721  return;
6722  }
6723 
6724  if (pretty_print)
6725  {
6726  o.write("[\n", 2);
6727 
6728  // variable to hold indentation for recursive calls
6729  const auto new_indent = current_indent + indent_step;
6730  if (indent_string.size() < new_indent)
6731  {
6732  indent_string.resize(new_indent, ' ');
6733  }
6734 
6735  // first n-1 elements
6736  for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6737  {
6738  o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
6739  dump(*i, true, indent_step, new_indent);
6740  o.write(",\n", 2);
6741  }
6742 
6743  // last element
6744  assert(not val.m_value.array->empty());
6745  o.write(indent_string.c_str(), static_cast<std::streamsize>(new_indent));
6746  dump(val.m_value.array->back(), true, indent_step, new_indent);
6747 
6748  o.put('\n');
6749  o.write(indent_string.c_str(), static_cast<std::streamsize>(current_indent));
6750  o.put(']');
6751  }
6752  else
6753  {
6754  o.put('[');
6755 
6756  // first n-1 elements
6757  for (auto i = val.m_value.array->cbegin(); i != val.m_value.array->cend() - 1; ++i)
6758  {
6759  dump(*i, false, indent_step, current_indent);
6760  o.put(',');
6761  }
6762 
6763  // last element
6764  assert(not val.m_value.array->empty());
6765  dump(val.m_value.array->back(), false, indent_step, current_indent);
6766 
6767  o.put(']');
6768  }
6769 
6770  return;
6771  }
6772 
6773  case value_t::string:
6774  {
6775  o.put('\"');
6776  dump_escaped(*val.m_value.string);
6777  o.put('\"');
6778  return;
6779  }
6780 
6781  case value_t::boolean:
6782  {
6783  if (val.m_value.boolean)
6784  {
6785  o.write("true", 4);
6786  }
6787  else
6788  {
6789  o.write("false", 5);
6790  }
6791  return;
6792  }
6793 
6794  case value_t::number_integer:
6795  {
6796  dump_integer(val.m_value.number_integer);
6797  return;
6798  }
6799 
6800  case value_t::number_unsigned:
6801  {
6802  dump_integer(val.m_value.number_unsigned);
6803  return;
6804  }
6805 
6806  case value_t::number_float:
6807  {
6808  dump_float(val.m_value.number_float);
6809  return;
6810  }
6811 
6812  case value_t::discarded:
6813  {
6814  o.write("<discarded>", 11);
6815  return;
6816  }
6817 
6818  case value_t::null:
6819  {
6820  o.write("null", 4);
6821  return;
6822  }
6823  }
6824  }
6825 
6826  private:
6835  static std::size_t extra_space(const string_t& s) noexcept
6836  {
6837  return std::accumulate(s.begin(), s.end(), size_t{},
6838  [](size_t res, typename string_t::value_type c)
6839  {
6840  switch (c)
6841  {
6842  case '"':
6843  case '\\':
6844  case '\b':
6845  case '\f':
6846  case '\n':
6847  case '\r':
6848  case '\t':
6849  {
6850  // from c (1 byte) to \x (2 bytes)
6851  return res + 1;
6852  }
6853 
6854  case 0x00:
6855  case 0x01:
6856  case 0x02:
6857  case 0x03:
6858  case 0x04:
6859  case 0x05:
6860  case 0x06:
6861  case 0x07:
6862  case 0x0b:
6863  case 0x0e:
6864  case 0x0f:
6865  case 0x10:
6866  case 0x11:
6867  case 0x12:
6868  case 0x13:
6869  case 0x14:
6870  case 0x15:
6871  case 0x16:
6872  case 0x17:
6873  case 0x18:
6874  case 0x19:
6875  case 0x1a:
6876  case 0x1b:
6877  case 0x1c:
6878  case 0x1d:
6879  case 0x1e:
6880  case 0x1f:
6881  {
6882  // from c (1 byte) to \uxxxx (6 bytes)
6883  return res + 5;
6884  }
6885 
6886  default:
6887  {
6888  return res;
6889  }
6890  }
6891  });
6892  }
6893 
6906  void dump_escaped(const string_t& s) const
6907  {
6908  const auto space = extra_space(s);
6909  if (space == 0)
6910  {
6911  o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
6912  return;
6913  }
6914 
6915  // create a result string of necessary size
6916  string_t result(s.size() + space, '\\');
6917  std::size_t pos = 0;
6918 
6919  for (const auto& c : s)
6920  {
6921  switch (c)
6922  {
6923  // quotation mark (0x22)
6924  case '"':
6925  {
6926  result[pos + 1] = '"';
6927  pos += 2;
6928  break;
6929  }
6930 
6931  // reverse solidus (0x5c)
6932  case '\\':
6933  {
6934  // nothing to change
6935  pos += 2;
6936  break;
6937  }
6938 
6939  // backspace (0x08)
6940  case '\b':
6941  {
6942  result[pos + 1] = 'b';
6943  pos += 2;
6944  break;
6945  }
6946 
6947  // formfeed (0x0c)
6948  case '\f':
6949  {
6950  result[pos + 1] = 'f';
6951  pos += 2;
6952  break;
6953  }
6954 
6955  // newline (0x0a)
6956  case '\n':
6957  {
6958  result[pos + 1] = 'n';
6959  pos += 2;
6960  break;
6961  }
6962 
6963  // carriage return (0x0d)
6964  case '\r':
6965  {
6966  result[pos + 1] = 'r';
6967  pos += 2;
6968  break;
6969  }
6970 
6971  // horizontal tab (0x09)
6972  case '\t':
6973  {
6974  result[pos + 1] = 't';
6975  pos += 2;
6976  break;
6977  }
6978 
6979  case 0x00:
6980  case 0x01:
6981  case 0x02:
6982  case 0x03:
6983  case 0x04:
6984  case 0x05:
6985  case 0x06:
6986  case 0x07:
6987  case 0x0b:
6988  case 0x0e:
6989  case 0x0f:
6990  case 0x10:
6991  case 0x11:
6992  case 0x12:
6993  case 0x13:
6994  case 0x14:
6995  case 0x15:
6996  case 0x16:
6997  case 0x17:
6998  case 0x18:
6999  case 0x19:
7000  case 0x1a:
7001  case 0x1b:
7002  case 0x1c:
7003  case 0x1d:
7004  case 0x1e:
7005  case 0x1f:
7006  {
7007  // convert a number 0..15 to its hex representation
7008  // (0..f)
7009  static const char hexify[16] =
7010  {
7011  '0', '1', '2', '3', '4', '5', '6', '7',
7012  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
7013  };
7014 
7015  // print character c as \uxxxx
7016  for (const char m :
7017  { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
7018  })
7019  {
7020  result[++pos] = m;
7021  }
7022 
7023  ++pos;
7024  break;
7025  }
7026 
7027  default:
7028  {
7029  // all other characters are added as-is
7030  result[pos++] = c;
7031  break;
7032  }
7033  }
7034  }
7035 
7036  assert(pos == s.size() + space);
7037  o.write(result.c_str(), static_cast<std::streamsize>(result.size()));
7038  }
7039 
7049  template<typename NumberType, detail::enable_if_t <
7050  std::is_same<NumberType, number_unsigned_t>::value or
7051  std::is_same<NumberType, number_integer_t>::value, int> = 0>
7052  void dump_integer(NumberType x)
7053  {
7054  // special case for "0"
7055  if (x == 0)
7056  {
7057  o.put('0');
7058  return;
7059  }
7060 
7061  const bool is_negative = x < 0;
7062  size_t i = 0;
7063 
7064  // spare 1 byte for '\0'
7065  while (x != 0 and i < number_buffer.size() - 1)
7066  {
7067  const auto digit = std::labs(static_cast<long>(x % 10));
7068  number_buffer[i++] = static_cast<char>('0' + digit);
7069  x /= 10;
7070  }
7071 
7072  // make sure the number has been processed completely
7073  assert(x == 0);
7074 
7075  if (is_negative)
7076  {
7077  // make sure there is capacity for the '-'
7078  assert(i < number_buffer.size() - 2);
7079  number_buffer[i++] = '-';
7080  }
7081 
7082  std::reverse(number_buffer.begin(), number_buffer.begin() + i);
7083  o.write(number_buffer.data(), static_cast<std::streamsize>(i));
7084  }
7085 
7094  void dump_float(number_float_t x)
7095  {
7096  // NaN / inf
7097  if (not std::isfinite(x) or std::isnan(x))
7098  {
7099  o.write("null", 4);
7100  return;
7101  }
7102 
7103  // special case for 0.0 and -0.0
7104  if (x == 0)
7105  {
7106  if (std::signbit(x))
7107  {
7108  o.write("-0.0", 4);
7109  }
7110  else
7111  {
7112  o.write("0.0", 3);
7113  }
7114  return;
7115  }
7116 
7117  // get number of digits for a text -> float -> text round-trip
7118  static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
7119 
7120  // the actual conversion
7121  std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(),
7122  "%.*g", d, x);
7123 
7124  // negative value indicates an error
7125  assert(len > 0);
7126  // check if buffer was large enough
7127  assert(static_cast<size_t>(len) < number_buffer.size());
7128 
7129  // erase thousands separator
7130  if (thousands_sep != '\0')
7131  {
7132  const auto end = std::remove(number_buffer.begin(),
7133  number_buffer.begin() + len,
7134  thousands_sep);
7135  std::fill(end, number_buffer.end(), '\0');
7136  assert((end - number_buffer.begin()) <= len);
7137  len = (end - number_buffer.begin());
7138  }
7139 
7140  // convert decimal point to '.'
7141  if (decimal_point != '\0' and decimal_point != '.')
7142  {
7143  for (auto& c : number_buffer)
7144  {
7145  if (c == decimal_point)
7146  {
7147  c = '.';
7148  break;
7149  }
7150  }
7151  }
7152 
7153  o.write(number_buffer.data(), static_cast<std::streamsize>(len));
7154 
7155  // determine if need to append ".0"
7156  const bool value_is_int_like = std::none_of(number_buffer.begin(),
7157  number_buffer.begin() + len + 1,
7158  [](char c)
7159  {
7160  return c == '.' or c == 'e';
7161  });
7162 
7163  if (value_is_int_like)
7164  {
7165  o.write(".0", 2);
7166  }
7167  }
7168 
7169  private:
7171  std::ostream& o;
7172 
7174  std::array<char, 64> number_buffer{{}};
7175 
7177  const std::lconv* loc = nullptr;
7179  const char thousands_sep = '\0';
7181  const char decimal_point = '\0';
7182 
7184  string_t indent_string = string_t(512, ' ');
7185  };
7186 
7187  public:
7210  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
7211  {
7212  // read width member and use it as indentation parameter if nonzero
7213  const bool pretty_print = (o.width() > 0);
7214  const auto indentation = (pretty_print ? o.width() : 0);
7215 
7216  // reset width to 0 for subsequent calls to this stream
7217  o.width(0);
7219  // do the actual serialization
7220  serializer s(o);
7221  s.dump(j, pretty_print, static_cast<unsigned int>(indentation));
7222  return o;
7223  }
7224 
7232  JSON_DEPRECATED
7233  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
7234  {
7235  return o << j;
7236  }
7237 
7239 
7240 
7242  // deserialization //
7244 
7247 
7280  template<class T, std::size_t N>
7281  static basic_json parse(T (&array)[N],
7282  const parser_callback_t cb = nullptr)
7283  {
7284  // delegate the call to the iterator-range parse overload
7285  return parse(std::begin(array), std::end(array), cb);
7286  }
7287 
7319  template<typename CharT, typename std::enable_if<
7320  std::is_pointer<CharT>::value and
7321  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
7322  sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
7323  static basic_json parse(const CharT s,
7324  const parser_callback_t cb = nullptr)
7325  {
7326  return parser(reinterpret_cast<const char*>(s), cb).parse();
7327  }
7328 
7358  static basic_json parse(std::istream& i,
7359  const parser_callback_t cb = nullptr)
7360  {
7361  return parser(i, cb).parse();
7362  }
7363 
7367  static basic_json parse(std::istream&& i,
7368  const parser_callback_t cb = nullptr)
7369  {
7370  return parser(i, cb).parse();
7371  }
7372 
7418  template<class IteratorType, typename std::enable_if<
7419  std::is_base_of<
7420  std::random_access_iterator_tag,
7421  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
7422  static basic_json parse(IteratorType first, IteratorType last,
7423  const parser_callback_t cb = nullptr)
7424  {
7425  // assertion to check that the iterator range is indeed contiguous,
7426  // see http://stackoverflow.com/a/35008842/266378 for more discussion
7427  assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
7428  [&first](std::pair<bool, int> res, decltype(*first) val)
7429  {
7430  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
7431  return res;
7432  }).first);
7433 
7434  // assertion to check that each element is 1 byte long
7435  static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
7436  "each element in the iterator range must have the size of 1 byte");
7437 
7438  // if iterator range is empty, create a parser with an empty string
7439  // to generate "unexpected EOF" error message
7440  if (std::distance(first, last) <= 0)
7441  {
7442  return parser("").parse();
7443  }
7444 
7445  return parser(first, last, cb).parse();
7446  }
7447 
7492  template<class ContiguousContainer, typename std::enable_if<
7493  not std::is_pointer<ContiguousContainer>::value and
7494  std::is_base_of<
7495  std::random_access_iterator_tag,
7496  typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
7497  , int>::type = 0>
7498  static basic_json parse(const ContiguousContainer& c,
7499  const parser_callback_t cb = nullptr)
7500  {
7501  // delegate the call to the iterator-range parse overload
7502  return parse(std::begin(c), std::end(c), cb);
7503  }
7504 
7512  JSON_DEPRECATED
7513  friend std::istream& operator<<(basic_json& j, std::istream& i)
7514  {
7515  j = parser(i).parse();
7516  return i;
7517  }
7518 
7545  friend std::istream& operator>>(std::istream& i, basic_json& j)
7546  {
7547  j = parser(i).parse();
7548  return i;
7549  }
7550 
7552 
7554  // binary serialization/deserialization //
7556 
7559 
7560  private:
7566  template<typename T>
7567  static void add_to_vector(std::vector<uint8_t>& vec, size_t bytes, const T number)
7568  {
7569  assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
7570 
7571  switch (bytes)
7572  {
7573  case 8:
7574  {
7575  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
7576  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
7577  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
7578  vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
7579  vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
7580  vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
7581  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7582  vec.push_back(static_cast<uint8_t>(number & 0xff));
7583  break;
7584  }
7585 
7586  case 4:
7587  {
7588  vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
7589  vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
7590  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7591  vec.push_back(static_cast<uint8_t>(number & 0xff));
7592  break;
7593  }
7594 
7595  case 2:
7596  {
7597  vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
7598  vec.push_back(static_cast<uint8_t>(number & 0xff));
7599  break;
7600  }
7601 
7602  case 1:
7603  {
7604  vec.push_back(static_cast<uint8_t>(number & 0xff));
7605  break;
7606  }
7607  }
7608  }
7609 
7646  template<typename T>
7647  static T get_from_vector(const std::vector<uint8_t>& vec, const size_t current_index)
7648  {
7649  // check if we can read sizeof(T) bytes starting the next index
7650  check_length(vec.size(), sizeof(T), current_index + 1);
7651 
7652  T result;
7653  auto* ptr = reinterpret_cast<uint8_t*>(&result);
7654  for (size_t i = 0; i < sizeof(T); ++i)
7655  {
7656  *ptr++ = vec[current_index + sizeof(T) - i];
7657  }
7658  return result;
7659  }
7660 
7671  static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
7672  {
7673  switch (j.type())
7674  {
7675  case value_t::null:
7676  {
7677  // nil
7678  v.push_back(0xc0);
7679  break;
7680  }
7681 
7682  case value_t::boolean:
7683  {
7684  // true and false
7685  v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
7686  break;
7687  }
7688 
7689  case value_t::number_integer:
7690  {
7691  if (j.m_value.number_integer >= 0)
7692  {
7693  // MessagePack does not differentiate between positive
7694  // signed integers and unsigned integers. Therefore, we
7695  // used the code from the value_t::number_unsigned case
7696  // here.
7697  if (j.m_value.number_unsigned < 128)
7698  {
7699  // positive fixnum
7700  add_to_vector(v, 1, j.m_value.number_unsigned);
7701  }
7702  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7703  {
7704  // uint 8
7705  v.push_back(0xcc);
7706  add_to_vector(v, 1, j.m_value.number_unsigned);
7707  }
7708  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7709  {
7710  // uint 16
7711  v.push_back(0xcd);
7712  add_to_vector(v, 2, j.m_value.number_unsigned);
7713  }
7714  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7715  {
7716  // uint 32
7717  v.push_back(0xce);
7718  add_to_vector(v, 4, j.m_value.number_unsigned);
7719  }
7720  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7721  {
7722  // uint 64
7723  v.push_back(0xcf);
7724  add_to_vector(v, 8, j.m_value.number_unsigned);
7725  }
7726  }
7727  else
7728  {
7729  if (j.m_value.number_integer >= -32)
7730  {
7731  // negative fixnum
7732  add_to_vector(v, 1, j.m_value.number_integer);
7733  }
7734  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)())
7735  {
7736  // int 8
7737  v.push_back(0xd0);
7738  add_to_vector(v, 1, j.m_value.number_integer);
7739  }
7740  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)())
7741  {
7742  // int 16
7743  v.push_back(0xd1);
7744  add_to_vector(v, 2, j.m_value.number_integer);
7745  }
7746  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)())
7747  {
7748  // int 32
7749  v.push_back(0xd2);
7750  add_to_vector(v, 4, j.m_value.number_integer);
7751  }
7752  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)())
7753  {
7754  // int 64
7755  v.push_back(0xd3);
7756  add_to_vector(v, 8, j.m_value.number_integer);
7757  }
7758  }
7759  break;
7760  }
7761 
7762  case value_t::number_unsigned:
7763  {
7764  if (j.m_value.number_unsigned < 128)
7765  {
7766  // positive fixnum
7767  add_to_vector(v, 1, j.m_value.number_unsigned);
7768  }
7769  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
7770  {
7771  // uint 8
7772  v.push_back(0xcc);
7773  add_to_vector(v, 1, j.m_value.number_unsigned);
7774  }
7775  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
7776  {
7777  // uint 16
7778  v.push_back(0xcd);
7779  add_to_vector(v, 2, j.m_value.number_unsigned);
7780  }
7781  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
7782  {
7783  // uint 32
7784  v.push_back(0xce);
7785  add_to_vector(v, 4, j.m_value.number_unsigned);
7786  }
7787  else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
7788  {
7789  // uint 64
7790  v.push_back(0xcf);
7791  add_to_vector(v, 8, j.m_value.number_unsigned);
7792  }
7793  break;
7794  }
7795 
7796  case value_t::number_float:
7797  {
7798  // float 64
7799  v.push_back(0xcb);
7800  const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
7801  for (size_t i = 0; i < 8; ++i)
7802  {
7803  v.push_back(helper[7 - i]);
7804  }
7805  break;
7806  }
7807 
7808  case value_t::string:
7809  {
7810  const auto N = j.m_value.string->size();
7811  if (N <= 31)
7812  {
7813  // fixstr
7814  v.push_back(static_cast<uint8_t>(0xa0 | N));
7815  }
7816  else if (N <= 255)
7817  {
7818  // str 8
7819  v.push_back(0xd9);
7820  add_to_vector(v, 1, N);
7821  }
7822  else if (N <= 65535)
7823  {
7824  // str 16
7825  v.push_back(0xda);
7826  add_to_vector(v, 2, N);
7827  }
7828  else if (N <= 4294967295)
7829  {
7830  // str 32
7831  v.push_back(0xdb);
7832  add_to_vector(v, 4, N);
7833  }
7834 
7835  // append string
7836  std::copy(j.m_value.string->begin(), j.m_value.string->end(),
7837  std::back_inserter(v));
7838  break;
7839  }
7840 
7841  case value_t::array:
7842  {
7843  const auto N = j.m_value.array->size();
7844  if (N <= 15)
7845  {
7846  // fixarray
7847  v.push_back(static_cast<uint8_t>(0x90 | N));
7848  }
7849  else if (N <= 0xffff)
7850  {
7851  // array 16
7852  v.push_back(0xdc);
7853  add_to_vector(v, 2, N);
7854  }
7855  else if (N <= 0xffffffff)
7856  {
7857  // array 32
7858  v.push_back(0xdd);
7859  add_to_vector(v, 4, N);
7860  }
7861 
7862  // append each element
7863  for (const auto& el : *j.m_value.array)
7864  {
7865  to_msgpack_internal(el, v);
7866  }
7867  break;
7868  }
7869 
7870  case value_t::object:
7871  {
7872  const auto N = j.m_value.object->size();
7873  if (N <= 15)
7874  {
7875  // fixmap
7876  v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
7877  }
7878  else if (N <= 65535)
7879  {
7880  // map 16
7881  v.push_back(0xde);
7882  add_to_vector(v, 2, N);
7883  }
7884  else if (N <= 4294967295)
7885  {
7886  // map 32
7887  v.push_back(0xdf);
7888  add_to_vector(v, 4, N);
7889  }
7890 
7891  // append each element
7892  for (const auto& el : *j.m_value.object)
7893  {
7894  to_msgpack_internal(el.first, v);
7895  to_msgpack_internal(el.second, v);
7896  }
7897  break;
7898  }
7899 
7900  default:
7901  {
7902  break;
7903  }
7904  }
7905  }
7906 
7917  static void to_cbor_internal(const basic_json& j, std::vector<uint8_t>& v)
7918  {
7919  switch (j.type())
7920  {
7921  case value_t::null:
7922  {
7923  v.push_back(0xf6);
7924  break;
7925  }
7926 
7927  case value_t::boolean:
7928  {
7929  v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
7930  break;
7931  }
7932 
7933  case value_t::number_integer:
7934  {
7935  if (j.m_value.number_integer >= 0)
7936  {
7937  // CBOR does not differentiate between positive signed
7938  // integers and unsigned integers. Therefore, we used the
7939  // code from the value_t::number_unsigned case here.
7940  if (j.m_value.number_integer <= 0x17)
7941  {
7942  add_to_vector(v, 1, j.m_value.number_integer);
7943  }
7944  else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
7945  {
7946  v.push_back(0x18);
7947  // one-byte uint8_t
7948  add_to_vector(v, 1, j.m_value.number_integer);
7949  }
7950  else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
7951  {
7952  v.push_back(0x19);
7953  // two-byte uint16_t
7954  add_to_vector(v, 2, j.m_value.number_integer);
7955  }
7956  else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
7957  {
7958  v.push_back(0x1a);
7959  // four-byte uint32_t
7960  add_to_vector(v, 4, j.m_value.number_integer);
7961  }
7962  else
7963  {
7964  v.push_back(0x1b);
7965  // eight-byte uint64_t
7966  add_to_vector(v, 8, j.m_value.number_integer);
7967  }
7968  }
7969  else
7970  {
7971  // The conversions below encode the sign in the first
7972  // byte, and the value is converted to a positive number.
7973  const auto positive_number = -1 - j.m_value.number_integer;
7974  if (j.m_value.number_integer >= -24)
7975  {
7976  v.push_back(static_cast<uint8_t>(0x20 + positive_number));
7977  }
7978  else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
7979  {
7980  // int 8
7981  v.push_back(0x38);
7982  add_to_vector(v, 1, positive_number);
7983  }
7984  else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
7985  {
7986  // int 16
7987  v.push_back(0x39);
7988  add_to_vector(v, 2, positive_number);
7989  }
7990  else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
7991  {
7992  // int 32
7993  v.push_back(0x3a);
7994  add_to_vector(v, 4, positive_number);
7995  }
7996  else
7997  {
7998  // int 64
7999  v.push_back(0x3b);
8000  add_to_vector(v, 8, positive_number);
8001  }
8002  }
8003  break;
8004  }
8005 
8006  case value_t::number_unsigned:
8007  {
8008  if (j.m_value.number_unsigned <= 0x17)
8009  {
8010  v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
8011  }
8012  else if (j.m_value.number_unsigned <= 0xff)
8013  {
8014  v.push_back(0x18);
8015  // one-byte uint8_t
8016  add_to_vector(v, 1, j.m_value.number_unsigned);
8017  }
8018  else if (j.m_value.number_unsigned <= 0xffff)
8019  {
8020  v.push_back(0x19);
8021  // two-byte uint16_t
8022  add_to_vector(v, 2, j.m_value.number_unsigned);
8023  }
8024  else if (j.m_value.number_unsigned <= 0xffffffff)
8025  {
8026  v.push_back(0x1a);
8027  // four-byte uint32_t
8028  add_to_vector(v, 4, j.m_value.number_unsigned);
8029  }
8030  else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
8031  {
8032  v.push_back(0x1b);
8033  // eight-byte uint64_t
8034  add_to_vector(v, 8, j.m_value.number_unsigned);
8035  }
8036  break;
8037  }
8038 
8039  case value_t::number_float:
8040  {
8041  // Double-Precision Float
8042  v.push_back(0xfb);
8043  const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
8044  for (size_t i = 0; i < 8; ++i)
8045  {
8046  v.push_back(helper[7 - i]);
8047  }
8048  break;
8049  }
8050 
8051  case value_t::string:
8052  {
8053  const auto N = j.m_value.string->size();
8054  if (N <= 0x17)
8055  {
8056  v.push_back(static_cast<uint8_t>(0x60 + N)); // 1 byte for string + size
8057  }
8058  else if (N <= 0xff)
8059  {
8060  v.push_back(0x78); // one-byte uint8_t for N
8061  add_to_vector(v, 1, N);
8062  }
8063  else if (N <= 0xffff)
8064  {
8065  v.push_back(0x79); // two-byte uint16_t for N
8066  add_to_vector(v, 2, N);
8067  }
8068  else if (N <= 0xffffffff)
8069  {
8070  v.push_back(0x7a); // four-byte uint32_t for N
8071  add_to_vector(v, 4, N);
8072  }
8073  // LCOV_EXCL_START
8074  else if (N <= 0xffffffffffffffff)
8075  {
8076  v.push_back(0x7b); // eight-byte uint64_t for N
8077  add_to_vector(v, 8, N);
8078  }
8079  // LCOV_EXCL_STOP
8080 
8081  // append string
8082  std::copy(j.m_value.string->begin(), j.m_value.string->end(),
8083  std::back_inserter(v));
8084  break;
8085  }
8086 
8087  case value_t::array:
8088  {
8089  const auto N = j.m_value.array->size();
8090  if (N <= 0x17)
8091  {
8092  v.push_back(static_cast<uint8_t>(0x80 + N)); // 1 byte for array + size
8093  }
8094  else if (N <= 0xff)
8095  {
8096  v.push_back(0x98); // one-byte uint8_t for N
8097  add_to_vector(v, 1, N);
8098  }
8099  else if (N <= 0xffff)
8100  {
8101  v.push_back(0x99); // two-byte uint16_t for N
8102  add_to_vector(v, 2, N);
8103  }
8104  else if (N <= 0xffffffff)
8105  {
8106  v.push_back(0x9a); // four-byte uint32_t for N
8107  add_to_vector(v, 4, N);
8108  }
8109  // LCOV_EXCL_START
8110  else if (N <= 0xffffffffffffffff)
8111  {
8112  v.push_back(0x9b); // eight-byte uint64_t for N
8113  add_to_vector(v, 8, N);
8114  }
8115  // LCOV_EXCL_STOP
8116 
8117  // append each element
8118  for (const auto& el : *j.m_value.array)
8119  {
8120  to_cbor_internal(el, v);
8121  }
8122  break;
8123  }
8124 
8125  case value_t::object:
8126  {
8127  const auto N = j.m_value.object->size();
8128  if (N <= 0x17)
8129  {
8130  v.push_back(static_cast<uint8_t>(0xa0 + N)); // 1 byte for object + size
8131  }
8132  else if (N <= 0xff)
8133  {
8134  v.push_back(0xb8);
8135  add_to_vector(v, 1, N); // one-byte uint8_t for N
8136  }
8137  else if (N <= 0xffff)
8138  {
8139  v.push_back(0xb9);
8140  add_to_vector(v, 2, N); // two-byte uint16_t for N
8141  }
8142  else if (N <= 0xffffffff)
8143  {
8144  v.push_back(0xba);
8145  add_to_vector(v, 4, N); // four-byte uint32_t for N
8146  }
8147  // LCOV_EXCL_START
8148  else if (N <= 0xffffffffffffffff)
8149  {
8150  v.push_back(0xbb);
8151  add_to_vector(v, 8, N); // eight-byte uint64_t for N
8152  }
8153  // LCOV_EXCL_STOP
8154 
8155  // append each element
8156  for (const auto& el : *j.m_value.object)
8157  {
8158  to_cbor_internal(el.first, v);
8159  to_cbor_internal(el.second, v);
8160  }
8161  break;
8162  }
8163 
8164  default:
8165  {
8166  break;
8167  }
8168  }
8169  }
8170 
8171 
8172  /*
8173  @brief checks if given lengths do not exceed the size of a given vector
8174 
8175  To secure the access to the byte vector during CBOR/MessagePack
8176  deserialization, bytes are copied from the vector into buffers. This
8177  function checks if the number of bytes to copy (@a len) does not exceed
8178  the size @s size of the vector. Additionally, an @a offset is given from
8179  where to start reading the bytes.
8180 
8181  This function checks whether reading the bytes is safe; that is, offset is
8182  a valid index in the vector, offset+len
8183 
8184  @param[in] size size of the byte vector
8185  @param[in] len number of bytes to read
8186  @param[in] offset offset where to start reading
8187 
8188  vec: x x x x x X X X X X
8189  ^ ^ ^
8190  0 offset len
8191 
8192  @throws out_of_range if `len > v.size()`
8193  */
8194  static void check_length(const size_t size, const size_t len, const size_t offset)
8195  {
8196  // simple case: requested length is greater than the vector's length
8197  if (len > size or offset > size)
8198  {
8199  JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
8200  }
8201 
8202  // second case: adding offset would result in overflow
8203  if ((size > ((std::numeric_limits<size_t>::max)() - offset)))
8204  {
8205  JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
8206  }
8207 
8208  // last case: reading past the end of the vector
8209  if (len + offset > size)
8210  {
8211  JSON_THROW(parse_error::create(110, offset + 1, "cannot read " + std::to_string(len) + " bytes from vector"));
8212  }
8213  }
8214 
8231  static void msgpack_expect_string(const std::vector<uint8_t>& v, size_t idx)
8232  {
8233  check_length(v.size(), 1, idx);
8234 
8235  const auto byte = v[idx];
8236  if ((byte >= 0xa0 and byte <= 0xbf) or (byte >= 0xd9 and byte <= 0xdb))
8237  {
8238  return;
8239  }
8240 
8241  std::stringstream ss;
8242  ss << std::hex << static_cast<int>(v[idx]);
8243  JSON_THROW(parse_error::create(113, idx + 1, "expected a MessagePack string; last byte: 0x" + ss.str()));
8244  }
8245 
8261  static void cbor_expect_string(const std::vector<uint8_t>& v, size_t idx)
8262  {
8263  check_length(v.size(), 1, idx);
8264 
8265  const auto byte = v[idx];
8266  if ((byte >= 0x60 and byte <= 0x7b) or byte == 0x7f)
8267  {
8268  return;
8269  }
8270 
8271  std::stringstream ss;
8272  ss << std::hex << static_cast<int>(v[idx]);
8273  JSON_THROW(parse_error::create(113, idx + 1, "expected a CBOR string; last byte: 0x" + ss.str()));
8274  }
8275 
8291  static basic_json from_msgpack_internal(const std::vector<uint8_t>& v, size_t& idx)
8292  {
8293  // store and increment index
8294  const size_t current_idx = idx++;
8295 
8296  // make sure reading 1 byte is safe
8297  check_length(v.size(), 1, current_idx);
8298 
8299  if (v[current_idx] <= 0xbf)
8300  {
8301  if (v[current_idx] <= 0x7f) // positive fixint
8302  {
8303  return v[current_idx];
8304  }
8305  if (v[current_idx] <= 0x8f) // fixmap
8306  {
8307  basic_json result = value_t::object;
8308  const size_t len = v[current_idx] & 0x0f;
8309  for (size_t i = 0; i < len; ++i)
8310  {
8311  msgpack_expect_string(v, idx);
8312  std::string key = from_msgpack_internal(v, idx);
8313  result[key] = from_msgpack_internal(v, idx);
8314  }
8315  return result;
8316  }
8317  else if (v[current_idx] <= 0x9f) // fixarray
8318  {
8319  basic_json result = value_t::array;
8320  const size_t len = v[current_idx] & 0x0f;
8321  for (size_t i = 0; i < len; ++i)
8322  {
8323  result.push_back(from_msgpack_internal(v, idx));
8324  }
8325  return result;
8326  }
8327  else // fixstr
8328  {
8329  const size_t len = v[current_idx] & 0x1f;
8330  const size_t offset = current_idx + 1;
8331  idx += len; // skip content bytes
8332  check_length(v.size(), len, offset);
8333  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8334  }
8335  }
8336  else if (v[current_idx] >= 0xe0) // negative fixint
8337  {
8338  return static_cast<int8_t>(v[current_idx]);
8339  }
8340  else
8341  {
8342  switch (v[current_idx])
8343  {
8344  case 0xc0: // nil
8345  {
8346  return value_t::null;
8347  }
8348 
8349  case 0xc2: // false
8350  {
8351  return false;
8352  }
8353 
8354  case 0xc3: // true
8355  {
8356  return true;
8357  }
8358 
8359  case 0xca: // float 32
8360  {
8361  // copy bytes in reverse order into the double variable
8362  float res;
8363  check_length(v.size(), sizeof(float), current_idx + 1);
8364  for (size_t byte = 0; byte < sizeof(float); ++byte)
8365  {
8366  reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
8367  }
8368  idx += sizeof(float); // skip content bytes
8369  return res;
8370  }
8371 
8372  case 0xcb: // float 64
8373  {
8374  // copy bytes in reverse order into the double variable
8375  double res;
8376  check_length(v.size(), sizeof(double), current_idx + 1);
8377  for (size_t byte = 0; byte < sizeof(double); ++byte)
8378  {
8379  reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
8380  }
8381  idx += sizeof(double); // skip content bytes
8382  return res;
8383  }
8384 
8385  case 0xcc: // uint 8
8386  {
8387  idx += 1; // skip content byte
8388  return get_from_vector<uint8_t>(v, current_idx);
8389  }
8390 
8391  case 0xcd: // uint 16
8392  {
8393  idx += 2; // skip 2 content bytes
8394  return get_from_vector<uint16_t>(v, current_idx);
8395  }
8396 
8397  case 0xce: // uint 32
8398  {
8399  idx += 4; // skip 4 content bytes
8400  return get_from_vector<uint32_t>(v, current_idx);
8401  }
8402 
8403  case 0xcf: // uint 64
8404  {
8405  idx += 8; // skip 8 content bytes
8406  return get_from_vector<uint64_t>(v, current_idx);
8407  }
8408 
8409  case 0xd0: // int 8
8410  {
8411  idx += 1; // skip content byte
8412  return get_from_vector<int8_t>(v, current_idx);
8413  }
8414 
8415  case 0xd1: // int 16
8416  {
8417  idx += 2; // skip 2 content bytes
8418  return get_from_vector<int16_t>(v, current_idx);
8419  }
8420 
8421  case 0xd2: // int 32
8422  {
8423  idx += 4; // skip 4 content bytes
8424  return get_from_vector<int32_t>(v, current_idx);
8425  }
8426 
8427  case 0xd3: // int 64
8428  {
8429  idx += 8; // skip 8 content bytes
8430  return get_from_vector<int64_t>(v, current_idx);
8431  }
8432 
8433  case 0xd9: // str 8
8434  {
8435  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8436  const size_t offset = current_idx + 2;
8437  idx += len + 1; // skip size byte + content bytes
8438  check_length(v.size(), len, offset);
8439  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8440  }
8441 
8442  case 0xda: // str 16
8443  {
8444  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8445  const size_t offset = current_idx + 3;
8446  idx += len + 2; // skip 2 size bytes + content bytes
8447  check_length(v.size(), len, offset);
8448  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8449  }
8450 
8451  case 0xdb: // str 32
8452  {
8453  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8454  const size_t offset = current_idx + 5;
8455  idx += len + 4; // skip 4 size bytes + content bytes
8456  check_length(v.size(), len, offset);
8457  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8458  }
8459 
8460  case 0xdc: // array 16
8461  {
8462  basic_json result = value_t::array;
8463  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8464  idx += 2; // skip 2 size bytes
8465  for (size_t i = 0; i < len; ++i)
8466  {
8467  result.push_back(from_msgpack_internal(v, idx));
8468  }
8469  return result;
8470  }
8471 
8472  case 0xdd: // array 32
8473  {
8474  basic_json result = value_t::array;
8475  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8476  idx += 4; // skip 4 size bytes
8477  for (size_t i = 0; i < len; ++i)
8478  {
8479  result.push_back(from_msgpack_internal(v, idx));
8480  }
8481  return result;
8482  }
8483 
8484  case 0xde: // map 16
8485  {
8486  basic_json result = value_t::object;
8487  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8488  idx += 2; // skip 2 size bytes
8489  for (size_t i = 0; i < len; ++i)
8490  {
8491  msgpack_expect_string(v, idx);
8492  std::string key = from_msgpack_internal(v, idx);
8493  result[key] = from_msgpack_internal(v, idx);
8494  }
8495  return result;
8496  }
8497 
8498  case 0xdf: // map 32
8499  {
8500  basic_json result = value_t::object;
8501  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8502  idx += 4; // skip 4 size bytes
8503  for (size_t i = 0; i < len; ++i)
8504  {
8505  msgpack_expect_string(v, idx);
8506  std::string key = from_msgpack_internal(v, idx);
8507  result[key] = from_msgpack_internal(v, idx);
8508  }
8509  return result;
8510  }
8511 
8512  default:
8513  {
8514  std::stringstream ss;
8515  ss << std::hex << static_cast<int>(v[current_idx]);
8516  JSON_THROW(parse_error::create(112, current_idx + 1, "error reading MessagePack; last byte: 0x" + ss.str()));
8517  }
8518  }
8519  }
8520  }
8521 
8537  static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
8538  {
8539  // store and increment index
8540  const size_t current_idx = idx++;
8541 
8542  // make sure reading 1 byte is safe
8543  check_length(v.size(), 1, current_idx);
8544 
8545  switch (v[current_idx])
8546  {
8547  // Integer 0x00..0x17 (0..23)
8548  case 0x00:
8549  case 0x01:
8550  case 0x02:
8551  case 0x03:
8552  case 0x04:
8553  case 0x05:
8554  case 0x06:
8555  case 0x07:
8556  case 0x08:
8557  case 0x09:
8558  case 0x0a:
8559  case 0x0b:
8560  case 0x0c:
8561  case 0x0d:
8562  case 0x0e:
8563  case 0x0f:
8564  case 0x10:
8565  case 0x11:
8566  case 0x12:
8567  case 0x13:
8568  case 0x14:
8569  case 0x15:
8570  case 0x16:
8571  case 0x17:
8572  {
8573  return v[current_idx];
8574  }
8575 
8576  case 0x18: // Unsigned integer (one-byte uint8_t follows)
8577  {
8578  idx += 1; // skip content byte
8579  return get_from_vector<uint8_t>(v, current_idx);
8580  }
8581 
8582  case 0x19: // Unsigned integer (two-byte uint16_t follows)
8583  {
8584  idx += 2; // skip 2 content bytes
8585  return get_from_vector<uint16_t>(v, current_idx);
8586  }
8587 
8588  case 0x1a: // Unsigned integer (four-byte uint32_t follows)
8589  {
8590  idx += 4; // skip 4 content bytes
8591  return get_from_vector<uint32_t>(v, current_idx);
8592  }
8593 
8594  case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
8595  {
8596  idx += 8; // skip 8 content bytes
8597  return get_from_vector<uint64_t>(v, current_idx);
8598  }
8599 
8600  // Negative integer -1-0x00..-1-0x17 (-1..-24)
8601  case 0x20:
8602  case 0x21:
8603  case 0x22:
8604  case 0x23:
8605  case 0x24:
8606  case 0x25:
8607  case 0x26:
8608  case 0x27:
8609  case 0x28:
8610  case 0x29:
8611  case 0x2a:
8612  case 0x2b:
8613  case 0x2c:
8614  case 0x2d:
8615  case 0x2e:
8616  case 0x2f:
8617  case 0x30:
8618  case 0x31:
8619  case 0x32:
8620  case 0x33:
8621  case 0x34:
8622  case 0x35:
8623  case 0x36:
8624  case 0x37:
8625  {
8626  return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
8627  }
8628 
8629  case 0x38: // Negative integer (one-byte uint8_t follows)
8630  {
8631  idx += 1; // skip content byte
8632  // must be uint8_t !
8633  return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
8634  }
8635 
8636  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8637  {
8638  idx += 2; // skip 2 content bytes
8639  return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
8640  }
8641 
8642  case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
8643  {
8644  idx += 4; // skip 4 content bytes
8645  return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
8646  }
8647 
8648  case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
8649  {
8650  idx += 8; // skip 8 content bytes
8651  return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
8652  }
8653 
8654  // UTF-8 string (0x00..0x17 bytes follow)
8655  case 0x60:
8656  case 0x61:
8657  case 0x62:
8658  case 0x63:
8659  case 0x64:
8660  case 0x65:
8661  case 0x66:
8662  case 0x67:
8663  case 0x68:
8664  case 0x69:
8665  case 0x6a:
8666  case 0x6b:
8667  case 0x6c:
8668  case 0x6d:
8669  case 0x6e:
8670  case 0x6f:
8671  case 0x70:
8672  case 0x71:
8673  case 0x72:
8674  case 0x73:
8675  case 0x74:
8676  case 0x75:
8677  case 0x76:
8678  case 0x77:
8679  {
8680  const auto len = static_cast<size_t>(v[current_idx] - 0x60);
8681  const size_t offset = current_idx + 1;
8682  idx += len; // skip content bytes
8683  check_length(v.size(), len, offset);
8684  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8685  }
8686 
8687  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8688  {
8689  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8690  const size_t offset = current_idx + 2;
8691  idx += len + 1; // skip size byte + content bytes
8692  check_length(v.size(), len, offset);
8693  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8694  }
8695 
8696  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8697  {
8698  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8699  const size_t offset = current_idx + 3;
8700  idx += len + 2; // skip 2 size bytes + content bytes
8701  check_length(v.size(), len, offset);
8702  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8703  }
8704 
8705  case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
8706  {
8707  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8708  const size_t offset = current_idx + 5;
8709  idx += len + 4; // skip 4 size bytes + content bytes
8710  check_length(v.size(), len, offset);
8711  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8712  }
8713 
8714  case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
8715  {
8716  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8717  const size_t offset = current_idx + 9;
8718  idx += len + 8; // skip 8 size bytes + content bytes
8719  check_length(v.size(), len, offset);
8720  return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
8721  }
8722 
8723  case 0x7f: // UTF-8 string (indefinite length)
8724  {
8725  std::string result;
8726  while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8727  {
8728  string_t s = from_cbor_internal(v, idx);
8729  result += s;
8730  }
8731  // skip break byte (0xFF)
8732  idx += 1;
8733  return result;
8734  }
8735 
8736  // array (0x00..0x17 data items follow)
8737  case 0x80:
8738  case 0x81:
8739  case 0x82:
8740  case 0x83:
8741  case 0x84:
8742  case 0x85:
8743  case 0x86:
8744  case 0x87:
8745  case 0x88:
8746  case 0x89:
8747  case 0x8a:
8748  case 0x8b:
8749  case 0x8c:
8750  case 0x8d:
8751  case 0x8e:
8752  case 0x8f:
8753  case 0x90:
8754  case 0x91:
8755  case 0x92:
8756  case 0x93:
8757  case 0x94:
8758  case 0x95:
8759  case 0x96:
8760  case 0x97:
8761  {
8762  basic_json result = value_t::array;
8763  const auto len = static_cast<size_t>(v[current_idx] - 0x80);
8764  for (size_t i = 0; i < len; ++i)
8765  {
8766  result.push_back(from_cbor_internal(v, idx));
8767  }
8768  return result;
8769  }
8770 
8771  case 0x98: // array (one-byte uint8_t for n follows)
8772  {
8773  basic_json result = value_t::array;
8774  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8775  idx += 1; // skip 1 size byte
8776  for (size_t i = 0; i < len; ++i)
8777  {
8778  result.push_back(from_cbor_internal(v, idx));
8779  }
8780  return result;
8781  }
8782 
8783  case 0x99: // array (two-byte uint16_t for n follow)
8784  {
8785  basic_json result = value_t::array;
8786  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8787  idx += 2; // skip 4 size bytes
8788  for (size_t i = 0; i < len; ++i)
8789  {
8790  result.push_back(from_cbor_internal(v, idx));
8791  }
8792  return result;
8793  }
8794 
8795  case 0x9a: // array (four-byte uint32_t for n follow)
8796  {
8797  basic_json result = value_t::array;
8798  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8799  idx += 4; // skip 4 size bytes
8800  for (size_t i = 0; i < len; ++i)
8801  {
8802  result.push_back(from_cbor_internal(v, idx));
8803  }
8804  return result;
8805  }
8806 
8807  case 0x9b: // array (eight-byte uint64_t for n follow)
8808  {
8809  basic_json result = value_t::array;
8810  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8811  idx += 8; // skip 8 size bytes
8812  for (size_t i = 0; i < len; ++i)
8813  {
8814  result.push_back(from_cbor_internal(v, idx));
8815  }
8816  return result;
8817  }
8818 
8819  case 0x9f: // array (indefinite length)
8820  {
8821  basic_json result = value_t::array;
8822  while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8823  {
8824  result.push_back(from_cbor_internal(v, idx));
8825  }
8826  // skip break byte (0xFF)
8827  idx += 1;
8828  return result;
8829  }
8830 
8831  // map (0x00..0x17 pairs of data items follow)
8832  case 0xa0:
8833  case 0xa1:
8834  case 0xa2:
8835  case 0xa3:
8836  case 0xa4:
8837  case 0xa5:
8838  case 0xa6:
8839  case 0xa7:
8840  case 0xa8:
8841  case 0xa9:
8842  case 0xaa:
8843  case 0xab:
8844  case 0xac:
8845  case 0xad:
8846  case 0xae:
8847  case 0xaf:
8848  case 0xb0:
8849  case 0xb1:
8850  case 0xb2:
8851  case 0xb3:
8852  case 0xb4:
8853  case 0xb5:
8854  case 0xb6:
8855  case 0xb7:
8856  {
8857  basic_json result = value_t::object;
8858  const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
8859  for (size_t i = 0; i < len; ++i)
8860  {
8861  cbor_expect_string(v, idx);
8862  std::string key = from_cbor_internal(v, idx);
8863  result[key] = from_cbor_internal(v, idx);
8864  }
8865  return result;
8866  }
8867 
8868  case 0xb8: // map (one-byte uint8_t for n follows)
8869  {
8870  basic_json result = value_t::object;
8871  const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
8872  idx += 1; // skip 1 size byte
8873  for (size_t i = 0; i < len; ++i)
8874  {
8875  cbor_expect_string(v, idx);
8876  std::string key = from_cbor_internal(v, idx);
8877  result[key] = from_cbor_internal(v, idx);
8878  }
8879  return result;
8880  }
8881 
8882  case 0xb9: // map (two-byte uint16_t for n follow)
8883  {
8884  basic_json result = value_t::object;
8885  const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
8886  idx += 2; // skip 2 size bytes
8887  for (size_t i = 0; i < len; ++i)
8888  {
8889  cbor_expect_string(v, idx);
8890  std::string key = from_cbor_internal(v, idx);
8891  result[key] = from_cbor_internal(v, idx);
8892  }
8893  return result;
8894  }
8895 
8896  case 0xba: // map (four-byte uint32_t for n follow)
8897  {
8898  basic_json result = value_t::object;
8899  const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
8900  idx += 4; // skip 4 size bytes
8901  for (size_t i = 0; i < len; ++i)
8902  {
8903  cbor_expect_string(v, idx);
8904  std::string key = from_cbor_internal(v, idx);
8905  result[key] = from_cbor_internal(v, idx);
8906  }
8907  return result;
8908  }
8909 
8910  case 0xbb: // map (eight-byte uint64_t for n follow)
8911  {
8912  basic_json result = value_t::object;
8913  const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
8914  idx += 8; // skip 8 size bytes
8915  for (size_t i = 0; i < len; ++i)
8916  {
8917  cbor_expect_string(v, idx);
8918  std::string key = from_cbor_internal(v, idx);
8919  result[key] = from_cbor_internal(v, idx);
8920  }
8921  return result;
8922  }
8923 
8924  case 0xbf: // map (indefinite length)
8925  {
8926  basic_json result = value_t::object;
8927  while (static_cast<void>(check_length(v.size(), 1, idx)), v[idx] != 0xff)
8928  {
8929  cbor_expect_string(v, idx);
8930  std::string key = from_cbor_internal(v, idx);
8931  result[key] = from_cbor_internal(v, idx);
8932  }
8933  // skip break byte (0xFF)
8934  idx += 1;
8935  return result;
8936  }
8937 
8938  case 0xf4: // false
8939  {
8940  return false;
8941  }
8942 
8943  case 0xf5: // true
8944  {
8945  return true;
8946  }
8947 
8948  case 0xf6: // null
8949  {
8950  return value_t::null;
8951  }
8952 
8953  case 0xf9: // Half-Precision Float (two-byte IEEE 754)
8954  {
8955  idx += 2; // skip two content bytes
8956 
8957  // code from RFC 7049, Appendix D, Figure 3:
8958  // As half-precision floating-point numbers were only added to
8959  // IEEE 754 in 2008, today's programming platforms often still
8960  // only have limited support for them. It is very easy to
8961  // include at least decoding support for them even without such
8962  // support. An example of a small decoder for half-precision
8963  // floating-point numbers in the C language is shown in Fig. 3.
8964  check_length(v.size(), 2, current_idx + 1);
8965  const int half = (v[current_idx + 1] << 8) + v[current_idx + 2];
8966  const int exp = (half >> 10) & 0x1f;
8967  const int mant = half & 0x3ff;
8968  double val;
8969  if (exp == 0)
8970  {
8971  val = std::ldexp(mant, -24);
8972  }
8973  else if (exp != 31)
8974  {
8975  val = std::ldexp(mant + 1024, exp - 25);
8976  }
8977  else
8978  {
8979  val = mant == 0
8980  ? std::numeric_limits<double>::infinity()
8981  : std::numeric_limits<double>::quiet_NaN();
8982  }
8983  return (half & 0x8000) != 0 ? -val : val;
8984  }
8985 
8986  case 0xfa: // Single-Precision Float (four-byte IEEE 754)
8987  {
8988  // copy bytes in reverse order into the float variable
8989  float res;
8990  check_length(v.size(), sizeof(float), current_idx + 1);
8991  for (size_t byte = 0; byte < sizeof(float); ++byte)
8992  {
8993  reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v[current_idx + 1 + byte];
8994  }
8995  idx += sizeof(float); // skip content bytes
8996  return res;
8997  }
8998 
8999  case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
9000  {
9001  // copy bytes in reverse order into the double variable
9002  double res;
9003  check_length(v.size(), sizeof(double), current_idx + 1);
9004  for (size_t byte = 0; byte < sizeof(double); ++byte)
9005  {
9006  reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v[current_idx + 1 + byte];
9007  }
9008  idx += sizeof(double); // skip content bytes
9009  return res;
9010  }
9011 
9012  default: // anything else (0xFF is handled inside the other types)
9013  {
9014  std::stringstream ss;
9015  ss << std::hex << static_cast<int>(v[current_idx]);
9016  JSON_THROW(parse_error::create(112, current_idx + 1, "error reading CBOR; last byte: 0x" + ss.str()));
9017  }
9018  }
9019  }
9020 
9021  public:
9096  static std::vector<uint8_t> to_msgpack(const basic_json& j)
9097  {
9098  std::vector<uint8_t> result;
9099  to_msgpack_internal(j, result);
9100  return result;
9101  }
9102 
9170  static basic_json from_msgpack(const std::vector<uint8_t>& v,
9171  const size_t start_index = 0)
9172  {
9173  size_t i = start_index;
9174  return from_msgpack_internal(v, i);
9175  }
9176 
9259  static std::vector<uint8_t> to_cbor(const basic_json& j)
9260  {
9261  std::vector<uint8_t> result;
9262  to_cbor_internal(j, result);
9263  return result;
9264  }
9265 
9353  static basic_json from_cbor(const std::vector<uint8_t>& v,
9354  const size_t start_index = 0)
9355  {
9356  size_t i = start_index;
9357  return from_cbor_internal(v, i);
9358  }
9359 
9363  // convenience functions //
9365 
9381  std::string type_name() const
9382  {
9383  {
9384  switch (m_type)
9385  {
9386  case value_t::null:
9387  return "null";
9388  case value_t::object:
9389  return "object";
9390  case value_t::array:
9391  return "array";
9392  case value_t::string:
9393  return "string";
9394  case value_t::boolean:
9395  return "boolean";
9396  case value_t::discarded:
9397  return "discarded";
9398  default:
9399  return "number";
9400  }
9401  }
9402  }
9403 
9404 
9405  private:
9407  // member variables //
9409 
9411  value_t m_type = value_t::null;
9412 
9414  json_value m_value = {};
9415 
9416 
9417  private:
9419  // iterators //
9421 
9431  class primitive_iterator_t
9432  {
9433  public:
9434 
9435  difference_type get_value() const noexcept
9436  {
9437  return m_it;
9438  }
9440  void set_begin() noexcept
9441  {
9442  m_it = begin_value;
9443  }
9444 
9446  void set_end() noexcept
9447  {
9448  m_it = end_value;
9449  }
9450 
9452  constexpr bool is_begin() const noexcept
9453  {
9454  return (m_it == begin_value);
9455  }
9456 
9458  constexpr bool is_end() const noexcept
9459  {
9460  return (m_it == end_value);
9461  }
9462 
9463  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9464  {
9465  return lhs.m_it == rhs.m_it;
9466  }
9467 
9468  friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9469  {
9470  return !(lhs == rhs);
9471  }
9472 
9473  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9474  {
9475  return lhs.m_it < rhs.m_it;
9476  }
9477 
9478  friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9479  {
9480  return lhs.m_it <= rhs.m_it;
9481  }
9482 
9483  friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9484  {
9485  return lhs.m_it > rhs.m_it;
9486  }
9487 
9488  friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9489  {
9490  return lhs.m_it >= rhs.m_it;
9491  }
9492 
9493  primitive_iterator_t operator+(difference_type i)
9494  {
9495  auto result = *this;
9496  result += i;
9497  return result;
9498  }
9499 
9500  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9501  {
9502  return lhs.m_it - rhs.m_it;
9503  }
9504 
9505  friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
9506  {
9507  return os << it.m_it;
9508  }
9509 
9510  primitive_iterator_t& operator++()
9511  {
9512  ++m_it;
9513  return *this;
9514  }
9515 
9516  primitive_iterator_t operator++(int)
9517  {
9518  auto result = *this;
9519  m_it++;
9520  return result;
9521  }
9522 
9523  primitive_iterator_t& operator--()
9524  {
9525  --m_it;
9526  return *this;
9527  }
9528 
9529  primitive_iterator_t operator--(int)
9530  {
9531  auto result = *this;
9532  m_it--;
9533  return result;
9534  }
9535 
9536  primitive_iterator_t& operator+=(difference_type n)
9537  {
9538  m_it += n;
9539  return *this;
9540  }
9541 
9542  primitive_iterator_t& operator-=(difference_type n)
9543  {
9544  m_it -= n;
9545  return *this;
9546  }
9547 
9548  private:
9549  static constexpr difference_type begin_value = 0;
9550  static constexpr difference_type end_value = begin_value + 1;
9551 
9553  difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
9554  };
9555 
9563  struct internal_iterator
9564  {
9566  typename object_t::iterator object_iterator;
9568  typename array_t::iterator array_iterator;
9570  primitive_iterator_t primitive_iterator;
9571 
9573  internal_iterator() noexcept
9574  : object_iterator(), array_iterator(), primitive_iterator()
9575  {}
9576  };
9577 
9579  template<typename IteratorType>
9580  class iteration_proxy
9581  {
9582  private:
9584  class iteration_proxy_internal
9585  {
9586  private:
9588  IteratorType anchor;
9590  size_t array_index = 0;
9591 
9592  public:
9593  explicit iteration_proxy_internal(IteratorType it) noexcept
9594  : anchor(it)
9595  {}
9596 
9598  iteration_proxy_internal& operator*()
9599  {
9600  return *this;
9601  }
9602 
9604  iteration_proxy_internal& operator++()
9605  {
9606  ++anchor;
9607  ++array_index;
9608 
9609  return *this;
9610  }
9611 
9613  bool operator!= (const iteration_proxy_internal& o) const
9614  {
9615  return anchor != o.anchor;
9616  }
9617 
9619  typename basic_json::string_t key() const
9620  {
9621  assert(anchor.m_object != nullptr);
9622 
9623  switch (anchor.m_object->type())
9624  {
9625  // use integer array index as key
9626  case value_t::array:
9627  {
9628  return std::to_string(array_index);
9629  }
9630 
9631  // use key from the object
9632  case value_t::object:
9633  {
9634  return anchor.key();
9635  }
9636 
9637  // use an empty key for all primitive types
9638  default:
9639  {
9640  return "";
9641  }
9642  }
9643  }
9644 
9646  typename IteratorType::reference value() const
9647  {
9648  return anchor.value();
9649  }
9650  };
9651 
9653  typename IteratorType::reference container;
9654 
9655  public:
9657  explicit iteration_proxy(typename IteratorType::reference cont)
9658  : container(cont)
9659  {}
9660 
9662  iteration_proxy_internal begin() noexcept
9663  {
9664  return iteration_proxy_internal(container.begin());
9665  }
9666 
9668  iteration_proxy_internal end() noexcept
9669  {
9670  return iteration_proxy_internal(container.end());
9671  }
9672  };
9673 
9674  public:
9694  template<typename U>
9695  class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
9696  {
9698  friend class basic_json;
9699 
9700  // make sure U is basic_json or const basic_json
9701  static_assert(std::is_same<U, basic_json>::value
9702  or std::is_same<U, const basic_json>::value,
9703  "iter_impl only accepts (const) basic_json");
9704 
9705  public:
9707  using value_type = typename basic_json::value_type;
9711  using pointer = typename std::conditional<std::is_const<U>::value,
9712  typename basic_json::const_pointer,
9713  typename basic_json::pointer>::type;
9715  using reference = typename std::conditional<std::is_const<U>::value,
9716  typename basic_json::const_reference,
9717  typename basic_json::reference>::type;
9719  using iterator_category = std::bidirectional_iterator_tag;
9720 
9722  iter_impl() = default;
9723 
9730  explicit iter_impl(pointer object) noexcept
9731  : m_object(object)
9732  {
9733  assert(m_object != nullptr);
9734 
9735  switch (m_object->m_type)
9736  {
9737  case basic_json::value_t::object:
9738  {
9739  m_it.object_iterator = typename object_t::iterator();
9740  break;
9741  }
9742 
9743  case basic_json::value_t::array:
9744  {
9745  m_it.array_iterator = typename array_t::iterator();
9746  break;
9747  }
9748 
9749  default:
9750  {
9751  m_it.primitive_iterator = primitive_iterator_t();
9752  break;
9753  }
9754  }
9755  }
9756 
9757  /*
9758  Use operator `const_iterator` instead of `const_iterator(const iterator&
9759  other) noexcept` to avoid two class definitions for @ref iterator and
9760  @ref const_iterator.
9761 
9762  This function is only called if this class is an @ref iterator. If this
9763  class is a @ref const_iterator this function is not called.
9764  */
9765  operator const_iterator() const
9766  {
9767  const_iterator ret;
9768 
9769  if (m_object)
9770  {
9771  ret.m_object = m_object;
9772  ret.m_it = m_it;
9773  }
9774 
9775  return ret;
9776  }
9777 
9783  iter_impl(const iter_impl& other) noexcept
9784  : m_object(other.m_object), m_it(other.m_it)
9785  {}
9786 
9792  iter_impl& operator=(iter_impl other) noexcept(
9793  std::is_nothrow_move_constructible<pointer>::value and
9794  std::is_nothrow_move_assignable<pointer>::value and
9795  std::is_nothrow_move_constructible<internal_iterator>::value and
9796  std::is_nothrow_move_assignable<internal_iterator>::value
9797  )
9798  {
9799  std::swap(m_object, other.m_object);
9800  std::swap(m_it, other.m_it);
9801  return *this;
9802  }
9803 
9804  private:
9809  void set_begin() noexcept
9810  {
9811  assert(m_object != nullptr);
9812 
9813  switch (m_object->m_type)
9814  {
9815  case basic_json::value_t::object:
9816  {
9817  m_it.object_iterator = m_object->m_value.object->begin();
9818  break;
9819  }
9820 
9821  case basic_json::value_t::array:
9822  {
9823  m_it.array_iterator = m_object->m_value.array->begin();
9824  break;
9825  }
9826 
9827  case basic_json::value_t::null:
9828  {
9829  // set to end so begin()==end() is true: null is empty
9830  m_it.primitive_iterator.set_end();
9831  break;
9832  }
9833 
9834  default:
9835  {
9836  m_it.primitive_iterator.set_begin();
9837  break;
9838  }
9839  }
9840  }
9841 
9846  void set_end() noexcept
9847  {
9848  assert(m_object != nullptr);
9849 
9850  switch (m_object->m_type)
9851  {
9852  case basic_json::value_t::object:
9853  {
9854  m_it.object_iterator = m_object->m_value.object->end();
9855  break;
9856  }
9857 
9858  case basic_json::value_t::array:
9859  {
9860  m_it.array_iterator = m_object->m_value.array->end();
9861  break;
9862  }
9863 
9864  default:
9865  {
9866  m_it.primitive_iterator.set_end();
9867  break;
9868  }
9869  }
9870  }
9871 
9872  public:
9877  reference operator*() const
9878  {
9879  assert(m_object != nullptr);
9880 
9881  switch (m_object->m_type)
9882  {
9883  case basic_json::value_t::object:
9884  {
9885  assert(m_it.object_iterator != m_object->m_value.object->end());
9886  return m_it.object_iterator->second;
9887  }
9888 
9889  case basic_json::value_t::array:
9890  {
9891  assert(m_it.array_iterator != m_object->m_value.array->end());
9892  return *m_it.array_iterator;
9893  }
9894 
9895  case basic_json::value_t::null:
9896  {
9897  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9898  }
9899 
9900  default:
9901  {
9902  if (m_it.primitive_iterator.is_begin())
9903  {
9904  return *m_object;
9905  }
9906 
9907  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9908  }
9909  }
9910  }
9911 
9916  pointer operator->() const
9917  {
9918  assert(m_object != nullptr);
9919 
9920  switch (m_object->m_type)
9921  {
9922  case basic_json::value_t::object:
9923  {
9924  assert(m_it.object_iterator != m_object->m_value.object->end());
9925  return &(m_it.object_iterator->second);
9926  }
9927 
9928  case basic_json::value_t::array:
9929  {
9930  assert(m_it.array_iterator != m_object->m_value.array->end());
9931  return &*m_it.array_iterator;
9932  }
9933 
9934  default:
9935  {
9936  if (m_it.primitive_iterator.is_begin())
9937  {
9938  return m_object;
9939  }
9940 
9941  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9942  }
9943  }
9944  }
9945 
9950  iter_impl operator++(int)
9951  {
9952  auto result = *this;
9953  ++(*this);
9954  return result;
9955  }
9956 
9961  iter_impl& operator++()
9962  {
9963  assert(m_object != nullptr);
9964 
9965  switch (m_object->m_type)
9966  {
9967  case basic_json::value_t::object:
9968  {
9969  std::advance(m_it.object_iterator, 1);
9970  break;
9971  }
9972 
9973  case basic_json::value_t::array:
9974  {
9975  std::advance(m_it.array_iterator, 1);
9976  break;
9977  }
9978 
9979  default:
9980  {
9981  ++m_it.primitive_iterator;
9982  break;
9983  }
9984  }
9985 
9986  return *this;
9987  }
9988 
9993  iter_impl operator--(int)
9994  {
9995  auto result = *this;
9996  --(*this);
9997  return result;
9998  }
9999 
10004  iter_impl& operator--()
10005  {
10006  assert(m_object != nullptr);
10007 
10008  switch (m_object->m_type)
10009  {
10010  case basic_json::value_t::object:
10011  {
10012  std::advance(m_it.object_iterator, -1);
10013  break;
10014  }
10015 
10016  case basic_json::value_t::array:
10017  {
10018  std::advance(m_it.array_iterator, -1);
10019  break;
10020  }
10021 
10022  default:
10023  {
10024  --m_it.primitive_iterator;
10025  break;
10026  }
10027  }
10028 
10029  return *this;
10030  }
10031 
10036  bool operator==(const iter_impl& other) const
10037  {
10038  // if objects are not the same, the comparison is undefined
10039  if (m_object != other.m_object)
10040  {
10041  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10042  }
10043 
10044  assert(m_object != nullptr);
10045 
10046  switch (m_object->m_type)
10047  {
10048  case basic_json::value_t::object:
10049  {
10050  return (m_it.object_iterator == other.m_it.object_iterator);
10051  }
10052 
10053  case basic_json::value_t::array:
10054  {
10055  return (m_it.array_iterator == other.m_it.array_iterator);
10056  }
10057 
10058  default:
10059  {
10060  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10061  }
10062  }
10063  }
10064 
10069  bool operator!=(const iter_impl& other) const
10070  {
10071  return not operator==(other);
10072  }
10073 
10078  bool operator<(const iter_impl& other) const
10079  {
10080  // if objects are not the same, the comparison is undefined
10081  if (m_object != other.m_object)
10082  {
10083  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10084  }
10085 
10086  assert(m_object != nullptr);
10087 
10088  switch (m_object->m_type)
10089  {
10090  case basic_json::value_t::object:
10091  {
10092  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
10093  }
10094 
10095  case basic_json::value_t::array:
10096  {
10097  return (m_it.array_iterator < other.m_it.array_iterator);
10098  }
10099 
10100  default:
10101  {
10102  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10103  }
10104  }
10105  }
10106 
10111  bool operator<=(const iter_impl& other) const
10112  {
10113  return not other.operator < (*this);
10114  }
10115 
10120  bool operator>(const iter_impl& other) const
10121  {
10122  return not operator<=(other);
10123  }
10124 
10129  bool operator>=(const iter_impl& other) const
10130  {
10131  return not operator<(other);
10132  }
10133 
10138  iter_impl& operator+=(difference_type i)
10139  {
10140  assert(m_object != nullptr);
10141 
10142  switch (m_object->m_type)
10143  {
10144  case basic_json::value_t::object:
10145  {
10146  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10147  }
10148 
10149  case basic_json::value_t::array:
10150  {
10151  std::advance(m_it.array_iterator, i);
10152  break;
10153  }
10154 
10155  default:
10156  {
10157  m_it.primitive_iterator += i;
10158  break;
10159  }
10160  }
10161 
10162  return *this;
10163  }
10164 
10169  iter_impl& operator-=(difference_type i)
10170  {
10171  return operator+=(-i);
10172  }
10173 
10178  iter_impl operator+(difference_type i)
10179  {
10180  auto result = *this;
10181  result += i;
10182  return result;
10183  }
10184 
10189  iter_impl operator-(difference_type i)
10190  {
10191  auto result = *this;
10192  result -= i;
10193  return result;
10194  }
10195 
10200  difference_type operator-(const iter_impl& other) const
10201  {
10202  assert(m_object != nullptr);
10203 
10204  switch (m_object->m_type)
10205  {
10206  case basic_json::value_t::object:
10207  {
10208  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10209  }
10210 
10211  case basic_json::value_t::array:
10212  {
10213  return m_it.array_iterator - other.m_it.array_iterator;
10214  }
10215 
10216  default:
10217  {
10218  return m_it.primitive_iterator - other.m_it.primitive_iterator;
10219  }
10220  }
10221  }
10222 
10227  reference operator[](difference_type n) const
10228  {
10229  assert(m_object != nullptr);
10230 
10231  switch (m_object->m_type)
10232  {
10233  case basic_json::value_t::object:
10234  {
10235  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
10236  }
10237 
10238  case basic_json::value_t::array:
10239  {
10240  return *std::next(m_it.array_iterator, n);
10241  }
10242 
10243  case basic_json::value_t::null:
10244  {
10245  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10246  }
10247 
10248  default:
10249  {
10250  if (m_it.primitive_iterator.get_value() == -n)
10251  {
10252  return *m_object;
10253  }
10254 
10255  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10256  }
10257  }
10258  }
10259 
10264  typename object_t::key_type key() const
10265  {
10266  assert(m_object != nullptr);
10267 
10268  if (m_object->is_object())
10269  {
10270  return m_it.object_iterator->first;
10271  }
10273  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
10274  }
10275 
10280  reference value() const
10281  {
10282  return operator*();
10283  }
10284 
10285  private:
10287  pointer m_object = nullptr;
10289  internal_iterator m_it = internal_iterator();
10290  };
10291 
10309  template<typename Base>
10310  class json_reverse_iterator : public std::reverse_iterator<Base>
10311  {
10312  public:
10314  using base_iterator = std::reverse_iterator<Base>;
10316  using reference = typename Base::reference;
10317 
10319  json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
10320  : base_iterator(it)
10321  {}
10325  : base_iterator(it)
10326  {}
10329  json_reverse_iterator operator++(int)
10330  {
10331  return base_iterator::operator++(1);
10332  }
10333 
10335  json_reverse_iterator& operator++()
10336  {
10337  base_iterator::operator++();
10338  return *this;
10339  }
10340 
10342  json_reverse_iterator operator--(int)
10343  {
10344  return base_iterator::operator--(1);
10345  }
10346 
10348  json_reverse_iterator& operator--()
10349  {
10350  base_iterator::operator--();
10351  return *this;
10352  }
10353 
10355  json_reverse_iterator& operator+=(difference_type i)
10356  {
10357  base_iterator::operator+=(i);
10358  return *this;
10359  }
10360 
10362  json_reverse_iterator operator+(difference_type i) const
10363  {
10364  auto result = *this;
10365  result += i;
10366  return result;
10367  }
10368 
10371  {
10372  auto result = *this;
10373  result -= i;
10374  return result;
10375  }
10376 
10379  {
10380  return this->base() - other.base();
10381  }
10382 
10384  reference operator[](difference_type n) const
10385  {
10386  return *(this->operator+(n));
10387  }
10388 
10390  typename object_t::key_type key() const
10391  {
10392  auto it = --this->base();
10393  return it.key();
10394  }
10395 
10397  reference value() const
10398  {
10399  auto it = --this->base();
10400  return it.operator * ();
10401  }
10402  };
10403 
10404 
10405  private:
10407  // lexer and parser //
10409 
10417  class lexer
10418  {
10419  public:
10421  enum class token_type
10422  {
10423  uninitialized,
10424  literal_true,
10425  literal_false,
10426  literal_null,
10427  value_string,
10428  value_unsigned,
10429  value_integer,
10430  value_float,
10431  begin_array,
10432  begin_object,
10433  end_array,
10434  end_object,
10435  name_separator,
10436  value_separator,
10437  parse_error,
10438  end_of_input
10439  };
10440 
10442  using lexer_char_t = unsigned char;
10443 
10445  lexer(const lexer_char_t* buff, const size_t len) noexcept
10446  : m_content(buff)
10447  {
10448  assert(m_content != nullptr);
10449  m_start = m_cursor = m_content;
10450  m_limit = m_content + len;
10451  }
10452 
10457  explicit lexer(std::istream& s)
10458  : m_stream(&s), m_line_buffer()
10459  {
10460  // immediately abort if stream is erroneous
10461  if (s.fail())
10462  {
10463  JSON_THROW(parse_error::create(111, 0, "bad input stream"));
10464  }
10465 
10466  // fill buffer
10467  fill_line_buffer();
10468 
10469  // skip UTF-8 byte-order mark
10470  if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF")
10471  {
10472  m_line_buffer[0] = ' ';
10473  m_line_buffer[1] = ' ';
10474  m_line_buffer[2] = ' ';
10475  }
10476  }
10477 
10478  // switch off unwanted functions (due to pointer members)
10479  lexer() = delete;
10480  lexer(const lexer&) = delete;
10481  lexer operator=(const lexer&) = delete;
10482 
10506  string_t to_unicode(const std::size_t codepoint1,
10507  const std::size_t codepoint2 = 0) const
10508  {
10509  // calculate the code point from the given code points
10510  std::size_t codepoint = codepoint1;
10511 
10512  // check if codepoint1 is a high surrogate
10513  if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
10514  {
10515  // check if codepoint2 is a low surrogate
10516  if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
10517  {
10518  codepoint =
10519  // high surrogate occupies the most significant 22 bits
10520  (codepoint1 << 10)
10521  // low surrogate occupies the least significant 15 bits
10522  + codepoint2
10523  // there is still the 0xD800, 0xDC00 and 0x10000 noise
10524  // in the result so we have to subtract with:
10525  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
10526  - 0x35FDC00;
10527  }
10528  else
10529  {
10530  JSON_THROW(parse_error::create(102, get_position(), "missing or wrong low surrogate"));
10531  }
10532  }
10533 
10534  string_t result;
10535 
10536  if (codepoint < 0x80)
10537  {
10538  // 1-byte characters: 0xxxxxxx (ASCII)
10539  result.append(1, static_cast<typename string_t::value_type>(codepoint));
10540  }
10541  else if (codepoint <= 0x7ff)
10542  {
10543  // 2-byte characters: 110xxxxx 10xxxxxx
10544  result.append(1, static_cast<typename string_t::value_type>(0xC0 | (codepoint >> 6)));
10545  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10546  }
10547  else if (codepoint <= 0xffff)
10548  {
10549  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
10550  result.append(1, static_cast<typename string_t::value_type>(0xE0 | (codepoint >> 12)));
10551  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
10552  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10553  }
10554  else if (codepoint <= 0x10ffff)
10555  {
10556  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
10557  result.append(1, static_cast<typename string_t::value_type>(0xF0 | (codepoint >> 18)));
10558  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
10559  result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
10560  result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
10561  }
10562  else
10563  {
10564  JSON_THROW(parse_error::create(103, get_position(), "code points above 0x10FFFF are invalid"));
10565  }
10566 
10567  return result;
10568  }
10569 
10571  static std::string token_type_name(const token_type t)
10572  {
10573  switch (t)
10574  {
10575  case token_type::uninitialized:
10576  return "<uninitialized>";
10577  case token_type::literal_true:
10578  return "true literal";
10579  case token_type::literal_false:
10580  return "false literal";
10581  case token_type::literal_null:
10582  return "null literal";
10583  case token_type::value_string:
10584  return "string literal";
10585  case lexer::token_type::value_unsigned:
10586  case lexer::token_type::value_integer:
10587  case lexer::token_type::value_float:
10588  return "number literal";
10589  case token_type::begin_array:
10590  return "'['";
10591  case token_type::begin_object:
10592  return "'{'";
10593  case token_type::end_array:
10594  return "']'";
10595  case token_type::end_object:
10596  return "'}'";
10597  case token_type::name_separator:
10598  return "':'";
10599  case token_type::value_separator:
10600  return "','";
10601  case token_type::parse_error:
10602  return "<parse error>";
10603  case token_type::end_of_input:
10604  return "end of input";
10605  default:
10606  {
10607  // catch non-enum values
10608  return "unknown token"; // LCOV_EXCL_LINE
10609  }
10610  }
10611  }
10612 
10633  token_type scan()
10634  {
10635  while (true)
10636  {
10637  // pointer for backtracking information
10638  m_marker = nullptr;
10639 
10640  // remember the begin of the token
10641  m_start = m_cursor;
10642  assert(m_start != nullptr);
10643 
10644 
10645  {
10646  lexer_char_t yych;
10647  unsigned int yyaccept = 0;
10648  static const unsigned char yybm[] =
10649  {
10650  0, 0, 0, 0, 0, 0, 0, 0,
10651  0, 32, 32, 0, 0, 32, 0, 0,
10652  0, 0, 0, 0, 0, 0, 0, 0,
10653  0, 0, 0, 0, 0, 0, 0, 0,
10654  160, 128, 0, 128, 128, 128, 128, 128,
10655  128, 128, 128, 128, 128, 128, 128, 128,
10656  192, 192, 192, 192, 192, 192, 192, 192,
10657  192, 192, 128, 128, 128, 128, 128, 128,
10658  128, 128, 128, 128, 128, 128, 128, 128,
10659  128, 128, 128, 128, 128, 128, 128, 128,
10660  128, 128, 128, 128, 128, 128, 128, 128,
10661  128, 128, 128, 128, 0, 128, 128, 128,
10662  128, 128, 128, 128, 128, 128, 128, 128,
10663  128, 128, 128, 128, 128, 128, 128, 128,
10664  128, 128, 128, 128, 128, 128, 128, 128,
10665  128, 128, 128, 128, 128, 128, 128, 128,
10666  0, 0, 0, 0, 0, 0, 0, 0,
10667  0, 0, 0, 0, 0, 0, 0, 0,
10668  0, 0, 0, 0, 0, 0, 0, 0,
10669  0, 0, 0, 0, 0, 0, 0, 0,
10670  0, 0, 0, 0, 0, 0, 0, 0,
10671  0, 0, 0, 0, 0, 0, 0, 0,
10672  0, 0, 0, 0, 0, 0, 0, 0,
10673  0, 0, 0, 0, 0, 0, 0, 0,
10674  0, 0, 0, 0, 0, 0, 0, 0,
10675  0, 0, 0, 0, 0, 0, 0, 0,
10676  0, 0, 0, 0, 0, 0, 0, 0,
10677  0, 0, 0, 0, 0, 0, 0, 0,
10678  0, 0, 0, 0, 0, 0, 0, 0,
10679  0, 0, 0, 0, 0, 0, 0, 0,
10680  0, 0, 0, 0, 0, 0, 0, 0,
10681  0, 0, 0, 0, 0, 0, 0, 0,
10682  };
10683  if ((m_limit - m_cursor) < 5)
10684  {
10685  fill_line_buffer(5); // LCOV_EXCL_LINE
10686  }
10687  yych = *m_cursor;
10688  if (yybm[0 + yych] & 32)
10689  {
10690  goto basic_json_parser_6;
10691  }
10692  if (yych <= '[')
10693  {
10694  if (yych <= '-')
10695  {
10696  if (yych <= '"')
10697  {
10698  if (yych <= 0x00)
10699  {
10700  goto basic_json_parser_2;
10701  }
10702  if (yych <= '!')
10703  {
10704  goto basic_json_parser_4;
10705  }
10706  goto basic_json_parser_9;
10707  }
10708  else
10709  {
10710  if (yych <= '+')
10711  {
10712  goto basic_json_parser_4;
10713  }
10714  if (yych <= ',')
10715  {
10716  goto basic_json_parser_10;
10717  }
10718  goto basic_json_parser_12;
10719  }
10720  }
10721  else
10722  {
10723  if (yych <= '9')
10724  {
10725  if (yych <= '/')
10726  {
10727  goto basic_json_parser_4;
10728  }
10729  if (yych <= '0')
10730  {
10731  goto basic_json_parser_13;
10732  }
10733  goto basic_json_parser_15;
10734  }
10735  else
10736  {
10737  if (yych <= ':')
10738  {
10739  goto basic_json_parser_17;
10740  }
10741  if (yych <= 'Z')
10742  {
10743  goto basic_json_parser_4;
10744  }
10745  goto basic_json_parser_19;
10746  }
10747  }
10748  }
10749  else
10750  {
10751  if (yych <= 'n')
10752  {
10753  if (yych <= 'e')
10754  {
10755  if (yych == ']')
10756  {
10757  goto basic_json_parser_21;
10758  }
10759  goto basic_json_parser_4;
10760  }
10761  else
10762  {
10763  if (yych <= 'f')
10764  {
10765  goto basic_json_parser_23;
10766  }
10767  if (yych <= 'm')
10768  {
10769  goto basic_json_parser_4;
10770  }
10771  goto basic_json_parser_24;
10772  }
10773  }
10774  else
10775  {
10776  if (yych <= 'z')
10777  {
10778  if (yych == 't')
10779  {
10780  goto basic_json_parser_25;
10781  }
10782  goto basic_json_parser_4;
10783  }
10784  else
10785  {
10786  if (yych <= '{')
10787  {
10788  goto basic_json_parser_26;
10789  }
10790  if (yych == '}')
10791  {
10792  goto basic_json_parser_28;
10793  }
10794  goto basic_json_parser_4;
10795  }
10796  }
10797  }
10798 basic_json_parser_2:
10799  ++m_cursor;
10800  {
10801  last_token_type = token_type::end_of_input;
10802  break;
10803  }
10804 basic_json_parser_4:
10805  ++m_cursor;
10806 basic_json_parser_5:
10807  {
10808  last_token_type = token_type::parse_error;
10809  break;
10810  }
10811 basic_json_parser_6:
10812  ++m_cursor;
10813  if (m_limit <= m_cursor)
10814  {
10815  fill_line_buffer(1); // LCOV_EXCL_LINE
10816  }
10817  yych = *m_cursor;
10818  if (yybm[0 + yych] & 32)
10819  {
10820  goto basic_json_parser_6;
10821  }
10822  {
10823  position += static_cast<size_t>((m_cursor - m_start));
10824  continue;
10825  }
10826 basic_json_parser_9:
10827  yyaccept = 0;
10828  yych = *(m_marker = ++m_cursor);
10829  if (yych <= 0x1F)
10830  {
10831  goto basic_json_parser_5;
10832  }
10833  if (yych <= 0x7F)
10834  {
10835  goto basic_json_parser_31;
10836  }
10837  if (yych <= 0xC1)
10838  {
10839  goto basic_json_parser_5;
10840  }
10841  if (yych <= 0xF4)
10842  {
10843  goto basic_json_parser_31;
10844  }
10845  goto basic_json_parser_5;
10846 basic_json_parser_10:
10847  ++m_cursor;
10848  {
10849  last_token_type = token_type::value_separator;
10850  break;
10851  }
10852 basic_json_parser_12:
10853  yych = *++m_cursor;
10854  if (yych <= '/')
10855  {
10856  goto basic_json_parser_5;
10857  }
10858  if (yych <= '0')
10859  {
10860  goto basic_json_parser_43;
10861  }
10862  if (yych <= '9')
10863  {
10864  goto basic_json_parser_45;
10865  }
10866  goto basic_json_parser_5;
10867 basic_json_parser_13:
10868  yyaccept = 1;
10869  yych = *(m_marker = ++m_cursor);
10870  if (yych <= '9')
10871  {
10872  if (yych == '.')
10873  {
10874  goto basic_json_parser_47;
10875  }
10876  if (yych >= '0')
10877  {
10878  goto basic_json_parser_48;
10879  }
10880  }
10881  else
10882  {
10883  if (yych <= 'E')
10884  {
10885  if (yych >= 'E')
10886  {
10887  goto basic_json_parser_51;
10888  }
10889  }
10890  else
10891  {
10892  if (yych == 'e')
10893  {
10894  goto basic_json_parser_51;
10895  }
10896  }
10897  }
10898 basic_json_parser_14:
10899  {
10900  last_token_type = token_type::value_unsigned;
10901  break;
10902  }
10903 basic_json_parser_15:
10904  yyaccept = 1;
10905  m_marker = ++m_cursor;
10906  if ((m_limit - m_cursor) < 3)
10907  {
10908  fill_line_buffer(3); // LCOV_EXCL_LINE
10909  }
10910  yych = *m_cursor;
10911  if (yybm[0 + yych] & 64)
10912  {
10913  goto basic_json_parser_15;
10914  }
10915  if (yych <= 'D')
10916  {
10917  if (yych == '.')
10918  {
10919  goto basic_json_parser_47;
10920  }
10921  goto basic_json_parser_14;
10922  }
10923  else
10924  {
10925  if (yych <= 'E')
10926  {
10927  goto basic_json_parser_51;
10928  }
10929  if (yych == 'e')
10930  {
10931  goto basic_json_parser_51;
10932  }
10933  goto basic_json_parser_14;
10934  }
10935 basic_json_parser_17:
10936  ++m_cursor;
10937  {
10938  last_token_type = token_type::name_separator;
10939  break;
10940  }
10941 basic_json_parser_19:
10942  ++m_cursor;
10943  {
10944  last_token_type = token_type::begin_array;
10945  break;
10946  }
10947 basic_json_parser_21:
10948  ++m_cursor;
10949  {
10950  last_token_type = token_type::end_array;
10951  break;
10952  }
10953 basic_json_parser_23:
10954  yyaccept = 0;
10955  yych = *(m_marker = ++m_cursor);
10956  if (yych == 'a')
10957  {
10958  goto basic_json_parser_52;
10959  }
10960  goto basic_json_parser_5;
10961 basic_json_parser_24:
10962  yyaccept = 0;
10963  yych = *(m_marker = ++m_cursor);
10964  if (yych == 'u')
10965  {
10966  goto basic_json_parser_53;
10967  }
10968  goto basic_json_parser_5;
10969 basic_json_parser_25:
10970  yyaccept = 0;
10971  yych = *(m_marker = ++m_cursor);
10972  if (yych == 'r')
10973  {
10974  goto basic_json_parser_54;
10975  }
10976  goto basic_json_parser_5;
10977 basic_json_parser_26:
10978  ++m_cursor;
10979  {
10980  last_token_type = token_type::begin_object;
10981  break;
10982  }
10983 basic_json_parser_28:
10984  ++m_cursor;
10985  {
10986  last_token_type = token_type::end_object;
10987  break;
10988  }
10989 basic_json_parser_30:
10990  ++m_cursor;
10991  if (m_limit <= m_cursor)
10992  {
10993  fill_line_buffer(1); // LCOV_EXCL_LINE
10994  }
10995  yych = *m_cursor;
10996 basic_json_parser_31:
10997  if (yybm[0 + yych] & 128)
10998  {
10999  goto basic_json_parser_30;
11000  }
11001  if (yych <= 0xE0)
11002  {
11003  if (yych <= '\\')
11004  {
11005  if (yych <= 0x1F)
11006  {
11007  goto basic_json_parser_32;
11008  }
11009  if (yych <= '"')
11010  {
11011  goto basic_json_parser_33;
11012  }
11013  goto basic_json_parser_35;
11014  }
11015  else
11016  {
11017  if (yych <= 0xC1)
11018  {
11019  goto basic_json_parser_32;
11020  }
11021  if (yych <= 0xDF)
11022  {
11023  goto basic_json_parser_36;
11024  }
11025  goto basic_json_parser_37;
11026  }
11027  }
11028  else
11029  {
11030  if (yych <= 0xEF)
11031  {
11032  if (yych == 0xED)
11033  {
11034  goto basic_json_parser_39;
11035  }
11036  goto basic_json_parser_38;
11037  }
11038  else
11039  {
11040  if (yych <= 0xF0)
11041  {
11042  goto basic_json_parser_40;
11043  }
11044  if (yych <= 0xF3)
11045  {
11046  goto basic_json_parser_41;
11047  }
11048  if (yych <= 0xF4)
11049  {
11050  goto basic_json_parser_42;
11051  }
11052  }
11053  }
11054 basic_json_parser_32:
11055  m_cursor = m_marker;
11056  if (yyaccept <= 1)
11057  {
11058  if (yyaccept == 0)
11059  {
11060  goto basic_json_parser_5;
11061  }
11062  else
11063  {
11064  goto basic_json_parser_14;
11065  }
11066  }
11067  else
11068  {
11069  if (yyaccept == 2)
11070  {
11071  goto basic_json_parser_44;
11072  }
11073  else
11074  {
11075  goto basic_json_parser_58;
11076  }
11077  }
11078 basic_json_parser_33:
11079  ++m_cursor;
11080  {
11081  last_token_type = token_type::value_string;
11082  break;
11083  }
11084 basic_json_parser_35:
11085  ++m_cursor;
11086  if (m_limit <= m_cursor)
11087  {
11088  fill_line_buffer(1); // LCOV_EXCL_LINE
11089  }
11090  yych = *m_cursor;
11091  if (yych <= 'e')
11092  {
11093  if (yych <= '/')
11094  {
11095  if (yych == '"')
11096  {
11097  goto basic_json_parser_30;
11098  }
11099  if (yych <= '.')
11100  {
11101  goto basic_json_parser_32;
11102  }
11103  goto basic_json_parser_30;
11104  }
11105  else
11106  {
11107  if (yych <= '\\')
11108  {
11109  if (yych <= '[')
11110  {
11111  goto basic_json_parser_32;
11112  }
11113  goto basic_json_parser_30;
11114  }
11115  else
11116  {
11117  if (yych == 'b')
11118  {
11119  goto basic_json_parser_30;
11120  }
11121  goto basic_json_parser_32;
11122  }
11123  }
11124  }
11125  else
11126  {
11127  if (yych <= 'q')
11128  {
11129  if (yych <= 'f')
11130  {
11131  goto basic_json_parser_30;
11132  }
11133  if (yych == 'n')
11134  {
11135  goto basic_json_parser_30;
11136  }
11137  goto basic_json_parser_32;
11138  }
11139  else
11140  {
11141  if (yych <= 's')
11142  {
11143  if (yych <= 'r')
11144  {
11145  goto basic_json_parser_30;
11146  }
11147  goto basic_json_parser_32;
11148  }
11149  else
11150  {
11151  if (yych <= 't')
11152  {
11153  goto basic_json_parser_30;
11154  }
11155  if (yych <= 'u')
11156  {
11157  goto basic_json_parser_55;
11158  }
11159  goto basic_json_parser_32;
11160  }
11161  }
11162  }
11163 basic_json_parser_36:
11164  ++m_cursor;
11165  if (m_limit <= m_cursor)
11166  {
11167  fill_line_buffer(1); // LCOV_EXCL_LINE
11168  }
11169  yych = *m_cursor;
11170  if (yych <= 0x7F)
11171  {
11172  goto basic_json_parser_32;
11173  }
11174  if (yych <= 0xBF)
11175  {
11176  goto basic_json_parser_30;
11177  }
11178  goto basic_json_parser_32;
11179 basic_json_parser_37:
11180  ++m_cursor;
11181  if (m_limit <= m_cursor)
11182  {
11183  fill_line_buffer(1); // LCOV_EXCL_LINE
11184  }
11185  yych = *m_cursor;
11186  if (yych <= 0x9F)
11187  {
11188  goto basic_json_parser_32;
11189  }
11190  if (yych <= 0xBF)
11191  {
11192  goto basic_json_parser_36;
11193  }
11194  goto basic_json_parser_32;
11195 basic_json_parser_38:
11196  ++m_cursor;
11197  if (m_limit <= m_cursor)
11198  {
11199  fill_line_buffer(1); // LCOV_EXCL_LINE
11200  }
11201  yych = *m_cursor;
11202  if (yych <= 0x7F)
11203  {
11204  goto basic_json_parser_32;
11205  }
11206  if (yych <= 0xBF)
11207  {
11208  goto basic_json_parser_36;
11209  }
11210  goto basic_json_parser_32;
11211 basic_json_parser_39:
11212  ++m_cursor;
11213  if (m_limit <= m_cursor)
11214  {
11215  fill_line_buffer(1); // LCOV_EXCL_LINE
11216  }
11217  yych = *m_cursor;
11218  if (yych <= 0x7F)
11219  {
11220  goto basic_json_parser_32;
11221  }
11222  if (yych <= 0x9F)
11223  {
11224  goto basic_json_parser_36;
11225  }
11226  goto basic_json_parser_32;
11227 basic_json_parser_40:
11228  ++m_cursor;
11229  if (m_limit <= m_cursor)
11230  {
11231  fill_line_buffer(1); // LCOV_EXCL_LINE
11232  }
11233  yych = *m_cursor;
11234  if (yych <= 0x8F)
11235  {
11236  goto basic_json_parser_32;
11237  }
11238  if (yych <= 0xBF)
11239  {
11240  goto basic_json_parser_38;
11241  }
11242  goto basic_json_parser_32;
11243 basic_json_parser_41:
11244  ++m_cursor;
11245  if (m_limit <= m_cursor)
11246  {
11247  fill_line_buffer(1); // LCOV_EXCL_LINE
11248  }
11249  yych = *m_cursor;
11250  if (yych <= 0x7F)
11251  {
11252  goto basic_json_parser_32;
11253  }
11254  if (yych <= 0xBF)
11255  {
11256  goto basic_json_parser_38;
11257  }
11258  goto basic_json_parser_32;
11259 basic_json_parser_42:
11260  ++m_cursor;
11261  if (m_limit <= m_cursor)
11262  {
11263  fill_line_buffer(1); // LCOV_EXCL_LINE
11264  }
11265  yych = *m_cursor;
11266  if (yych <= 0x7F)
11267  {
11268  goto basic_json_parser_32;
11269  }
11270  if (yych <= 0x8F)
11271  {
11272  goto basic_json_parser_38;
11273  }
11274  goto basic_json_parser_32;
11275 basic_json_parser_43:
11276  yyaccept = 2;
11277  yych = *(m_marker = ++m_cursor);
11278  if (yych <= '9')
11279  {
11280  if (yych == '.')
11281  {
11282  goto basic_json_parser_47;
11283  }
11284  if (yych >= '0')
11285  {
11286  goto basic_json_parser_48;
11287  }
11288  }
11289  else
11290  {
11291  if (yych <= 'E')
11292  {
11293  if (yych >= 'E')
11294  {
11295  goto basic_json_parser_51;
11296  }
11297  }
11298  else
11299  {
11300  if (yych == 'e')
11301  {
11302  goto basic_json_parser_51;
11303  }
11304  }
11305  }
11306 basic_json_parser_44:
11307  {
11308  last_token_type = token_type::value_integer;
11309  break;
11310  }
11311 basic_json_parser_45:
11312  yyaccept = 2;
11313  m_marker = ++m_cursor;
11314  if ((m_limit - m_cursor) < 3)
11315  {
11316  fill_line_buffer(3); // LCOV_EXCL_LINE
11317  }
11318  yych = *m_cursor;
11319  if (yych <= '9')
11320  {
11321  if (yych == '.')
11322  {
11323  goto basic_json_parser_47;
11324  }
11325  if (yych <= '/')
11326  {
11327  goto basic_json_parser_44;
11328  }
11329  goto basic_json_parser_45;
11330  }
11331  else
11332  {
11333  if (yych <= 'E')
11334  {
11335  if (yych <= 'D')
11336  {
11337  goto basic_json_parser_44;
11338  }
11339  goto basic_json_parser_51;
11340  }
11341  else
11342  {
11343  if (yych == 'e')
11344  {
11345  goto basic_json_parser_51;
11346  }
11347  goto basic_json_parser_44;
11348  }
11349  }
11350 basic_json_parser_47:
11351  yych = *++m_cursor;
11352  if (yych <= '/')
11353  {
11354  goto basic_json_parser_32;
11355  }
11356  if (yych <= '9')
11357  {
11358  goto basic_json_parser_56;
11359  }
11360  goto basic_json_parser_32;
11361 basic_json_parser_48:
11362  ++m_cursor;
11363  if (m_limit <= m_cursor)
11364  {
11365  fill_line_buffer(1); // LCOV_EXCL_LINE
11366  }
11367  yych = *m_cursor;
11368  if (yych <= '/')
11369  {
11370  goto basic_json_parser_50;
11371  }
11372  if (yych <= '9')
11373  {
11374  goto basic_json_parser_48;
11375  }
11376 basic_json_parser_50:
11377  {
11378  last_token_type = token_type::parse_error;
11379  break;
11380  }
11381 basic_json_parser_51:
11382  yych = *++m_cursor;
11383  if (yych <= ',')
11384  {
11385  if (yych == '+')
11386  {
11387  goto basic_json_parser_59;
11388  }
11389  goto basic_json_parser_32;
11390  }
11391  else
11392  {
11393  if (yych <= '-')
11394  {
11395  goto basic_json_parser_59;
11396  }
11397  if (yych <= '/')
11398  {
11399  goto basic_json_parser_32;
11400  }
11401  if (yych <= '9')
11402  {
11403  goto basic_json_parser_60;
11404  }
11405  goto basic_json_parser_32;
11406  }
11407 basic_json_parser_52:
11408  yych = *++m_cursor;
11409  if (yych == 'l')
11410  {
11411  goto basic_json_parser_62;
11412  }
11413  goto basic_json_parser_32;
11414 basic_json_parser_53:
11415  yych = *++m_cursor;
11416  if (yych == 'l')
11417  {
11418  goto basic_json_parser_63;
11419  }
11420  goto basic_json_parser_32;
11421 basic_json_parser_54:
11422  yych = *++m_cursor;
11423  if (yych == 'u')
11424  {
11425  goto basic_json_parser_64;
11426  }
11427  goto basic_json_parser_32;
11428 basic_json_parser_55:
11429  ++m_cursor;
11430  if (m_limit <= m_cursor)
11431  {
11432  fill_line_buffer(1); // LCOV_EXCL_LINE
11433  }
11434  yych = *m_cursor;
11435  if (yych <= '@')
11436  {
11437  if (yych <= '/')
11438  {
11439  goto basic_json_parser_32;
11440  }
11441  if (yych <= '9')
11442  {
11443  goto basic_json_parser_65;
11444  }
11445  goto basic_json_parser_32;
11446  }
11447  else
11448  {
11449  if (yych <= 'F')
11450  {
11451  goto basic_json_parser_65;
11452  }
11453  if (yych <= '`')
11454  {
11455  goto basic_json_parser_32;
11456  }
11457  if (yych <= 'f')
11458  {
11459  goto basic_json_parser_65;
11460  }
11461  goto basic_json_parser_32;
11462  }
11463 basic_json_parser_56:
11464  yyaccept = 3;
11465  m_marker = ++m_cursor;
11466  if ((m_limit - m_cursor) < 3)
11467  {
11468  fill_line_buffer(3); // LCOV_EXCL_LINE
11469  }
11470  yych = *m_cursor;
11471  if (yych <= 'D')
11472  {
11473  if (yych <= '/')
11474  {
11475  goto basic_json_parser_58;
11476  }
11477  if (yych <= '9')
11478  {
11479  goto basic_json_parser_56;
11480  }
11481  }
11482  else
11483  {
11484  if (yych <= 'E')
11485  {
11486  goto basic_json_parser_51;
11487  }
11488  if (yych == 'e')
11489  {
11490  goto basic_json_parser_51;
11491  }
11492  }
11493 basic_json_parser_58:
11494  {
11495  last_token_type = token_type::value_float;
11496  break;
11497  }
11498 basic_json_parser_59:
11499  yych = *++m_cursor;
11500  if (yych <= '/')
11501  {
11502  goto basic_json_parser_32;
11503  }
11504  if (yych >= ':')
11505  {
11506  goto basic_json_parser_32;
11507  }
11508 basic_json_parser_60:
11509  ++m_cursor;
11510  if (m_limit <= m_cursor)
11511  {
11512  fill_line_buffer(1); // LCOV_EXCL_LINE
11513  }
11514  yych = *m_cursor;
11515  if (yych <= '/')
11516  {
11517  goto basic_json_parser_58;
11518  }
11519  if (yych <= '9')
11520  {
11521  goto basic_json_parser_60;
11522  }
11523  goto basic_json_parser_58;
11524 basic_json_parser_62:
11525  yych = *++m_cursor;
11526  if (yych == 's')
11527  {
11528  goto basic_json_parser_66;
11529  }
11530  goto basic_json_parser_32;
11531 basic_json_parser_63:
11532  yych = *++m_cursor;
11533  if (yych == 'l')
11534  {
11535  goto basic_json_parser_67;
11536  }
11537  goto basic_json_parser_32;
11538 basic_json_parser_64:
11539  yych = *++m_cursor;
11540  if (yych == 'e')
11541  {
11542  goto basic_json_parser_69;
11543  }
11544  goto basic_json_parser_32;
11545 basic_json_parser_65:
11546  ++m_cursor;
11547  if (m_limit <= m_cursor)
11548  {
11549  fill_line_buffer(1); // LCOV_EXCL_LINE
11550  }
11551  yych = *m_cursor;
11552  if (yych <= '@')
11553  {
11554  if (yych <= '/')
11555  {
11556  goto basic_json_parser_32;
11557  }
11558  if (yych <= '9')
11559  {
11560  goto basic_json_parser_71;
11561  }
11562  goto basic_json_parser_32;
11563  }
11564  else
11565  {
11566  if (yych <= 'F')
11567  {
11568  goto basic_json_parser_71;
11569  }
11570  if (yych <= '`')
11571  {
11572  goto basic_json_parser_32;
11573  }
11574  if (yych <= 'f')
11575  {
11576  goto basic_json_parser_71;
11577  }
11578  goto basic_json_parser_32;
11579  }
11580 basic_json_parser_66:
11581  yych = *++m_cursor;
11582  if (yych == 'e')
11583  {
11584  goto basic_json_parser_72;
11585  }
11586  goto basic_json_parser_32;
11587 basic_json_parser_67:
11588  ++m_cursor;
11589  {
11590  last_token_type = token_type::literal_null;
11591  break;
11592  }
11593 basic_json_parser_69:
11594  ++m_cursor;
11595  {
11596  last_token_type = token_type::literal_true;
11597  break;
11598  }
11599 basic_json_parser_71:
11600  ++m_cursor;
11601  if (m_limit <= m_cursor)
11602  {
11603  fill_line_buffer(1); // LCOV_EXCL_LINE
11604  }
11605  yych = *m_cursor;
11606  if (yych <= '@')
11607  {
11608  if (yych <= '/')
11609  {
11610  goto basic_json_parser_32;
11611  }
11612  if (yych <= '9')
11613  {
11614  goto basic_json_parser_74;
11615  }
11616  goto basic_json_parser_32;
11617  }
11618  else
11619  {
11620  if (yych <= 'F')
11621  {
11622  goto basic_json_parser_74;
11623  }
11624  if (yych <= '`')
11625  {
11626  goto basic_json_parser_32;
11627  }
11628  if (yych <= 'f')
11629  {
11630  goto basic_json_parser_74;
11631  }
11632  goto basic_json_parser_32;
11633  }
11634 basic_json_parser_72:
11635  ++m_cursor;
11636  {
11637  last_token_type = token_type::literal_false;
11638  break;
11639  }
11640 basic_json_parser_74:
11641  ++m_cursor;
11642  if (m_limit <= m_cursor)
11643  {
11644  fill_line_buffer(1); // LCOV_EXCL_LINE
11645  }
11646  yych = *m_cursor;
11647  if (yych <= '@')
11648  {
11649  if (yych <= '/')
11650  {
11651  goto basic_json_parser_32;
11652  }
11653  if (yych <= '9')
11654  {
11655  goto basic_json_parser_30;
11656  }
11657  goto basic_json_parser_32;
11658  }
11659  else
11660  {
11661  if (yych <= 'F')
11662  {
11663  goto basic_json_parser_30;
11664  }
11665  if (yych <= '`')
11666  {
11667  goto basic_json_parser_32;
11668  }
11669  if (yych <= 'f')
11670  {
11671  goto basic_json_parser_30;
11672  }
11673  goto basic_json_parser_32;
11674  }
11675  }
11676 
11677  }
11678 
11679  position += static_cast<size_t>((m_cursor - m_start));
11680  return last_token_type;
11681  }
11682 
11711  void fill_line_buffer(size_t n = 0)
11712  {
11713  // if line buffer is used, m_content points to its data
11714  assert(m_line_buffer.empty()
11715  or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
11716 
11717  // if line buffer is used, m_limit is set past the end of its data
11718  assert(m_line_buffer.empty()
11719  or m_limit == m_content + m_line_buffer.size());
11720 
11721  // pointer relationships
11722  assert(m_content <= m_start);
11723  assert(m_start <= m_cursor);
11724  assert(m_cursor <= m_limit);
11725  assert(m_marker == nullptr or m_marker <= m_limit);
11726 
11727  // number of processed characters (p)
11728  const auto num_processed_chars = static_cast<size_t>(m_start - m_content);
11729  // offset for m_marker wrt. to m_start
11730  const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
11731  // number of unprocessed characters (u)
11732  const auto offset_cursor = m_cursor - m_start;
11733 
11734  // no stream is used or end of file is reached
11735  if (m_stream == nullptr or m_stream->eof())
11736  {
11737  // m_start may or may not be pointing into m_line_buffer at
11738  // this point. We trust the standard library to do the right
11739  // thing. See http://stackoverflow.com/q/28142011/266378
11740  m_line_buffer.assign(m_start, m_limit);
11741 
11742  // append n characters to make sure that there is sufficient
11743  // space between m_cursor and m_limit
11744  m_line_buffer.append(1, '\x00');
11745  if (n > 0)
11746  {
11747  m_line_buffer.append(n - 1, '\x01');
11748  }
11749  }
11750  else
11751  {
11752  // delete processed characters from line buffer
11753  m_line_buffer.erase(0, num_processed_chars);
11754  // read next line from input stream
11755  m_line_buffer_tmp.clear();
11756 
11757  // check if stream is still good
11758  if (m_stream->fail())
11759  {
11760  JSON_THROW(parse_error::create(111, 0, "bad input stream"));
11761  }
11762 
11763  std::getline(*m_stream, m_line_buffer_tmp, '\n');
11764 
11765  // add line with newline symbol to the line buffer
11766  m_line_buffer += m_line_buffer_tmp;
11767  m_line_buffer.push_back('\n');
11768  }
11769 
11770  // set pointers
11771  m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
11772  assert(m_content != nullptr);
11773  m_start = m_content;
11774  m_marker = m_start + offset_marker;
11775  m_cursor = m_start + offset_cursor;
11776  m_limit = m_start + m_line_buffer.size();
11777  }
11778 
11780  string_t get_token_string() const
11781  {
11782  assert(m_start != nullptr);
11783  return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
11784  static_cast<size_t>(m_cursor - m_start));
11785  }
11786 
11845  string_t get_string() const
11846  {
11847  assert(m_cursor - m_start >= 2);
11848 
11849  string_t result;
11850  result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
11851 
11852  // iterate the result between the quotes
11853  for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
11854  {
11855  // find next escape character
11856  auto e = std::find(i, m_cursor - 1, '\\');
11857  if (e != i)
11858  {
11859  // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
11860  for (auto k = i; k < e; k++)
11861  {
11862  result.push_back(static_cast<typename string_t::value_type>(*k));
11863  }
11864  i = e - 1; // -1 because of ++i
11865  }
11866  else
11867  {
11868  // processing escaped character
11869  // read next character
11870  ++i;
11871 
11872  switch (*i)
11873  {
11874  // the default escapes
11875  case 't':
11876  {
11877  result += "\t";
11878  break;
11879  }
11880  case 'b':
11881  {
11882  result += "\b";
11883  break;
11884  }
11885  case 'f':
11886  {
11887  result += "\f";
11888  break;
11889  }
11890  case 'n':
11891  {
11892  result += "\n";
11893  break;
11894  }
11895  case 'r':
11896  {
11897  result += "\r";
11898  break;
11899  }
11900  case '\\':
11901  {
11902  result += "\\";
11903  break;
11904  }
11905  case '/':
11906  {
11907  result += "/";
11908  break;
11909  }
11910  case '"':
11911  {
11912  result += "\"";
11913  break;
11914  }
11915 
11916  // unicode
11917  case 'u':
11918  {
11919  // get code xxxx from uxxxx
11920  auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
11921  4).c_str(), nullptr, 16);
11922 
11923  // check if codepoint is a high surrogate
11924  if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
11925  {
11926  // make sure there is a subsequent unicode
11927  if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
11928  {
11929  JSON_THROW(parse_error::create(102, get_position(), "missing low surrogate"));
11930  }
11931 
11932  // get code yyyy from uxxxx\uyyyy
11933  auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
11934  (i + 7), 4).c_str(), nullptr, 16);
11935  result += to_unicode(codepoint, codepoint2);
11936  // skip the next 10 characters (xxxx\uyyyy)
11937  i += 10;
11938  }
11939  else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
11940  {
11941  // we found a lone low surrogate
11942  JSON_THROW(parse_error::create(102, get_position(), "missing high surrogate"));
11943  }
11944  else
11945  {
11946  // add unicode character(s)
11947  result += to_unicode(codepoint);
11948  // skip the next four characters (xxxx)
11949  i += 4;
11950  }
11951  break;
11952  }
11953  }
11954  }
11955  }
11956 
11957  return result;
11958  }
11959 
11960 
11970  struct strtonum
11971  {
11972  public:
11973  strtonum(const char* start, const char* end)
11974  : m_start(start), m_end(end)
11975  {}
11976 
11983  template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
11984  bool to(T& val) const
11985  {
11986  return parse(val, std::is_integral<T>());
11987  }
11988 
11989  private:
11990  const char* const m_start = nullptr;
11991  const char* const m_end = nullptr;
11993  // floating-point conversion
11994 
11995  // overloaded wrappers for strtod/strtof/strtold
11996  // that will be called from parse<floating_point_t>
11997  static void strtof(float& f, const char* str, char** endptr)
11998  {
11999  f = std::strtof(str, endptr);
12000  }
12001 
12002  static void strtof(double& f, const char* str, char** endptr)
12003  {
12004  f = std::strtod(str, endptr);
12005  }
12006 
12007  static void strtof(long double& f, const char* str, char** endptr)
12008  {
12009  f = std::strtold(str, endptr);
12010  }
12011 
12012  template<typename T>
12013  bool parse(T& value, /*is_integral=*/std::false_type) const
12014  {
12015  // replace decimal separator with locale-specific version,
12016  // when necessary; data will point to either the original
12017  // string, or buf, or tempstr containing the fixed string.
12018  std::string tempstr;
12019  std::array<char, 64> buf;
12020  const size_t len = static_cast<size_t>(m_end - m_start);
12021 
12022  // lexer will reject empty numbers
12023  assert(len > 0);
12024 
12025  // since dealing with strtod family of functions, we're
12026  // getting the decimal point char from the C locale facilities
12027  // instead of C++'s numpunct facet of the current std::locale
12028  const auto loc = localeconv();
12029  assert(loc != nullptr);
12030  const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
12031 
12032  const char* data = m_start;
12033 
12034  if (decimal_point_char != '.')
12035  {
12036  const size_t ds_pos = static_cast<size_t>(std::find(m_start, m_end, '.') - m_start);
12037 
12038  if (ds_pos != len)
12039  {
12040  // copy the data into the local buffer or tempstr, if
12041  // buffer is too small; replace decimal separator, and
12042  // update data to point to the modified bytes
12043  if ((len + 1) < buf.size())
12044  {
12045  std::copy(m_start, m_end, buf.begin());
12046  buf[len] = 0;
12047  buf[ds_pos] = decimal_point_char;
12048  data = buf.data();
12049  }
12050  else
12051  {
12052  tempstr.assign(m_start, m_end);
12053  tempstr[ds_pos] = decimal_point_char;
12054  data = tempstr.c_str();
12055  }
12056  }
12057  }
12058 
12059  char* endptr = nullptr;
12060  value = 0;
12061  // this calls appropriate overload depending on T
12062  strtof(value, data, &endptr);
12063 
12064  // parsing was successful iff strtof parsed exactly the number
12065  // of characters determined by the lexer (len)
12066  const bool ok = (endptr == (data + len));
12067 
12068  if (ok and (value == static_cast<T>(0.0)) and (*data == '-'))
12069  {
12070  // some implementations forget to negate the zero
12071  value = -0.0;
12072  }
12073 
12074  return ok;
12075  }
12076 
12077  // integral conversion
12078 
12079  signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const
12080  {
12081  return std::strtoll(m_start, endptr, 10);
12082  }
12083 
12084  unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const
12085  {
12086  return std::strtoull(m_start, endptr, 10);
12087  }
12088 
12089  template<typename T>
12090  bool parse(T& value, /*is_integral=*/std::true_type) const
12091  {
12092  char* endptr = nullptr;
12093  errno = 0; // these are thread-local
12094  const auto x = parse_integral(&endptr, std::is_signed<T>());
12095 
12096  // called right overload?
12097  static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(), "");
12098 
12099  value = static_cast<T>(x);
12100 
12101  return (x == static_cast<decltype(x)>(value)) // x fits into destination T
12102  and (x < 0) == (value < 0) // preserved sign
12103  //and ((x != 0) or is_integral()) // strto[u]ll did nto fail
12104  and (errno == 0) // strto[u]ll did not overflow
12105  and (m_start < m_end) // token was not empty
12106  and (endptr == m_end); // parsed entire token exactly
12107  }
12108  };
12109 
12129  bool get_number(basic_json& result, const token_type token) const
12130  {
12131  assert(m_start != nullptr);
12132  assert(m_start < m_cursor);
12133  assert((token == token_type::value_unsigned) or
12134  (token == token_type::value_integer) or
12135  (token == token_type::value_float));
12136 
12137  strtonum num_converter(reinterpret_cast<const char*>(m_start),
12138  reinterpret_cast<const char*>(m_cursor));
12139 
12140  switch (token)
12141  {
12142  case lexer::token_type::value_unsigned:
12143  {
12144  number_unsigned_t val;
12145  if (num_converter.to(val))
12146  {
12147  // parsing successful
12148  result.m_type = value_t::number_unsigned;
12149  result.m_value = val;
12150  return true;
12151  }
12152  break;
12153  }
12154 
12155  case lexer::token_type::value_integer:
12156  {
12157  number_integer_t val;
12158  if (num_converter.to(val))
12159  {
12160  // parsing successful
12161  result.m_type = value_t::number_integer;
12162  result.m_value = val;
12163  return true;
12164  }
12165  break;
12166  }
12167 
12168  default:
12169  {
12170  break;
12171  }
12172  }
12173 
12174  // parse float (either explicitly or because a previous conversion
12175  // failed)
12176  number_float_t val;
12177  if (num_converter.to(val))
12178  {
12179  // parsing successful
12180  result.m_type = value_t::number_float;
12181  result.m_value = val;
12182 
12183  // throw in case of infinity or NAN
12184  if (not std::isfinite(result.m_value.number_float))
12185  {
12186  JSON_THROW(out_of_range::create(406, "number overflow parsing '" + get_token_string() + "'"));
12187  }
12188 
12189  return true;
12190  }
12191 
12192  // couldn't parse number in any format
12193  return false;
12194  }
12195 
12196  constexpr size_t get_position() const
12197  {
12198  return position;
12199  }
12200 
12201  private:
12203  std::istream* m_stream = nullptr;
12205  string_t m_line_buffer {};
12207  string_t m_line_buffer_tmp {};
12209  const lexer_char_t* m_content = nullptr;
12211  const lexer_char_t* m_start = nullptr;
12213  const lexer_char_t* m_marker = nullptr;
12215  const lexer_char_t* m_cursor = nullptr;
12217  const lexer_char_t* m_limit = nullptr;
12219  token_type last_token_type = token_type::end_of_input;
12221  size_t position = 0;
12222  };
12223 
12229  class parser
12230  {
12231  public:
12233  parser(const char* buff, const parser_callback_t cb = nullptr)
12234  : callback(cb),
12235  m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
12236  {}
12237 
12242  parser(std::istream& is, const parser_callback_t cb = nullptr)
12243  : callback(cb), m_lexer(is)
12244  {}
12245 
12247  template<class IteratorType, typename std::enable_if<
12248  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
12249  , int>::type
12250  = 0>
12251  parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
12252  : callback(cb),
12253  m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
12254  static_cast<size_t>(std::distance(first, last)))
12255  {}
12256 
12263  basic_json parse()
12264  {
12265  // read first token
12266  get_token();
12267 
12268  basic_json result = parse_internal(true);
12269  result.assert_invariant();
12270 
12271  expect(lexer::token_type::end_of_input);
12272 
12273  // return parser result and replace it with null in case the
12274  // top-level value was discarded by the callback function
12275  return result.is_discarded() ? basic_json() : std::move(result);
12276  }
12277 
12278  private:
12285  basic_json parse_internal(bool keep)
12286  {
12287  auto result = basic_json(value_t::discarded);
12288 
12289  switch (last_token)
12290  {
12291  case lexer::token_type::begin_object:
12292  {
12293  if (keep and (not callback
12294  or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
12295  {
12296  // explicitly set result to object to cope with {}
12297  result.m_type = value_t::object;
12298  result.m_value = value_t::object;
12299  }
12300 
12301  // read next token
12302  get_token();
12303 
12304  // closing } -> we are done
12305  if (last_token == lexer::token_type::end_object)
12306  {
12307  get_token();
12308  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12309  {
12310  result = basic_json(value_t::discarded);
12311  }
12312  return result;
12313  }
12314 
12315  // no comma is expected here
12316  unexpect(lexer::token_type::value_separator);
12317 
12318  // otherwise: parse key-value pairs
12319  do
12320  {
12321  // ugly, but could be fixed with loop reorganization
12322  if (last_token == lexer::token_type::value_separator)
12323  {
12324  get_token();
12325  }
12326 
12327  // store key
12328  expect(lexer::token_type::value_string);
12329  const auto key = m_lexer.get_string();
12330 
12331  bool keep_tag = false;
12332  if (keep)
12333  {
12334  if (callback)
12335  {
12336  basic_json k(key);
12337  keep_tag = callback(depth, parse_event_t::key, k);
12338  }
12339  else
12340  {
12341  keep_tag = true;
12342  }
12343  }
12344 
12345  // parse separator (:)
12346  get_token();
12347  expect(lexer::token_type::name_separator);
12348 
12349  // parse and add value
12350  get_token();
12351  auto value = parse_internal(keep);
12352  if (keep and keep_tag and not value.is_discarded())
12353  {
12354  result[key] = std::move(value);
12355  }
12356  }
12357  while (last_token == lexer::token_type::value_separator);
12358 
12359  // closing }
12360  expect(lexer::token_type::end_object);
12361  get_token();
12362  if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
12363  {
12364  result = basic_json(value_t::discarded);
12365  }
12366 
12367  return result;
12368  }
12369 
12370  case lexer::token_type::begin_array:
12371  {
12372  if (keep and (not callback
12373  or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
12374  {
12375  // explicitly set result to object to cope with []
12376  result.m_type = value_t::array;
12377  result.m_value = value_t::array;
12378  }
12379 
12380  // read next token
12381  get_token();
12382 
12383  // closing ] -> we are done
12384  if (last_token == lexer::token_type::end_array)
12385  {
12386  get_token();
12387  if (callback and not callback(--depth, parse_event_t::array_end, result))
12388  {
12389  result = basic_json(value_t::discarded);
12390  }
12391  return result;
12392  }
12393 
12394  // no comma is expected here
12395  unexpect(lexer::token_type::value_separator);
12396 
12397  // otherwise: parse values
12398  do
12399  {
12400  // ugly, but could be fixed with loop reorganization
12401  if (last_token == lexer::token_type::value_separator)
12402  {
12403  get_token();
12404  }
12405 
12406  // parse value
12407  auto value = parse_internal(keep);
12408  if (keep and not value.is_discarded())
12409  {
12410  result.push_back(std::move(value));
12411  }
12412  }
12413  while (last_token == lexer::token_type::value_separator);
12414 
12415  // closing ]
12416  expect(lexer::token_type::end_array);
12417  get_token();
12418  if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
12419  {
12420  result = basic_json(value_t::discarded);
12421  }
12422 
12423  return result;
12424  }
12425 
12426  case lexer::token_type::literal_null:
12427  {
12428  get_token();
12429  result.m_type = value_t::null;
12430  break;
12431  }
12432 
12433  case lexer::token_type::value_string:
12434  {
12435  const auto s = m_lexer.get_string();
12436  get_token();
12437  result = basic_json(s);
12438  break;
12439  }
12440 
12441  case lexer::token_type::literal_true:
12442  {
12443  get_token();
12444  result.m_type = value_t::boolean;
12445  result.m_value = true;
12446  break;
12447  }
12448 
12449  case lexer::token_type::literal_false:
12450  {
12451  get_token();
12452  result.m_type = value_t::boolean;
12453  result.m_value = false;
12454  break;
12455  }
12456 
12457  case lexer::token_type::value_unsigned:
12458  case lexer::token_type::value_integer:
12459  case lexer::token_type::value_float:
12460  {
12461  m_lexer.get_number(result, last_token);
12462  get_token();
12463  break;
12464  }
12465 
12466  default:
12467  {
12468  // the last token was unexpected
12469  unexpect(last_token);
12470  }
12471  }
12472 
12473  if (keep and callback and not callback(depth, parse_event_t::value, result))
12474  {
12475  result = basic_json(value_t::discarded);
12476  }
12477  return result;
12478  }
12479 
12481  typename lexer::token_type get_token()
12482  {
12483  last_token = m_lexer.scan();
12484  return last_token;
12485  }
12486 
12490  void expect(typename lexer::token_type t) const
12491  {
12492  if (t != last_token)
12493  {
12494  std::string error_msg = "parse error - unexpected ";
12495  error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
12496  "'") :
12497  lexer::token_type_name(last_token));
12498  error_msg += "; expected " + lexer::token_type_name(t);
12499  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12500  }
12501  }
12502 
12506  void unexpect(typename lexer::token_type t) const
12507  {
12508  if (t == last_token)
12509  {
12510  std::string error_msg = "parse error - unexpected ";
12511  error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
12512  "'") :
12513  lexer::token_type_name(last_token));
12514  JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
12515  }
12516  }
12517 
12518  private:
12520  int depth = 0;
12522  const parser_callback_t callback = nullptr;
12524  typename lexer::token_type last_token = lexer::token_type::uninitialized;
12526  lexer m_lexer;
12527  };
12528 
12529  public:
12541  class json_pointer
12542  {
12544  friend class basic_json;
12545 
12546  public:
12569  explicit json_pointer(const std::string& s = "")
12570  : reference_tokens(split(s))
12571  {}
12572 
12588  std::string to_string() const noexcept
12589  {
12590  return std::accumulate(reference_tokens.begin(),
12591  reference_tokens.end(), std::string{},
12592  [](const std::string & a, const std::string & b)
12593  {
12594  return a + "/" + escape(b);
12595  });
12596  }
12597 
12599  operator std::string() const
12600  {
12601  return to_string();
12602  }
12603 
12604  private:
12609  std::string pop_back()
12610  {
12611  if (is_root())
12612  {
12613  JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
12614  }
12615 
12616  auto last = reference_tokens.back();
12617  reference_tokens.pop_back();
12618  return last;
12619  }
12620 
12622  bool is_root() const
12623  {
12624  return reference_tokens.empty();
12625  }
12626 
12627  json_pointer top() const
12628  {
12629  if (is_root())
12630  {
12631  JSON_THROW(out_of_range::create(405, "JSON pointer has no parent"));
12632  }
12633 
12634  json_pointer result = *this;
12635  result.reference_tokens = {reference_tokens[0]};
12636  return result;
12637  }
12638 
12647  reference get_and_create(reference j) const
12648  {
12649  pointer result = &j;
12650 
12651  // in case no reference tokens exist, return a reference to the
12652  // JSON value j which will be overwritten by a primitive value
12653  for (const auto& reference_token : reference_tokens)
12654  {
12655  switch (result->m_type)
12656  {
12657  case value_t::null:
12658  {
12659  if (reference_token == "0")
12660  {
12661  // start a new array if reference token is 0
12662  result = &result->operator[](0);
12663  }
12664  else
12665  {
12666  // start a new object otherwise
12667  result = &result->operator[](reference_token);
12668  }
12669  break;
12670  }
12671 
12672  case value_t::object:
12673  {
12674  // create an entry in the object
12675  result = &result->operator[](reference_token);
12676  break;
12677  }
12678 
12679  case value_t::array:
12680  {
12681  // create an entry in the array
12682  JSON_TRY
12683  {
12684  result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
12685  }
12686  JSON_CATCH (std::invalid_argument&)
12687  {
12688  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12689  }
12690  break;
12691  }
12692 
12693  /*
12694  The following code is only reached if there exists a
12695  reference token _and_ the current value is primitive. In
12696  this case, we have an error situation, because primitive
12697  values may only occur as single value; that is, with an
12698  empty list of reference tokens.
12699  */
12700  default:
12701  {
12702  JSON_THROW(type_error::create(313, "invalid value to unflatten"));
12703  }
12704  }
12705  }
12706 
12707  return *result;
12708  }
12709 
12729  reference get_unchecked(pointer ptr) const
12730  {
12731  for (const auto& reference_token : reference_tokens)
12732  {
12733  // convert null values to arrays or objects before continuing
12734  if (ptr->m_type == value_t::null)
12735  {
12736  // check if reference token is a number
12737  const bool nums = std::all_of(reference_token.begin(),
12738  reference_token.end(),
12739  [](const char x)
12740  {
12741  return (x >= '0' and x <= '9');
12742  });
12743 
12744  // change value to array for numbers or "-" or to object
12745  // otherwise
12746  if (nums or reference_token == "-")
12747  {
12748  *ptr = value_t::array;
12749  }
12750  else
12751  {
12752  *ptr = value_t::object;
12753  }
12754  }
12755 
12756  switch (ptr->m_type)
12757  {
12758  case value_t::object:
12759  {
12760  // use unchecked object access
12761  ptr = &ptr->operator[](reference_token);
12762  break;
12763  }
12764 
12765  case value_t::array:
12766  {
12767  // error condition (cf. RFC 6901, Sect. 4)
12768  if (reference_token.size() > 1 and reference_token[0] == '0')
12769  {
12770  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
12771  }
12772 
12773  if (reference_token == "-")
12774  {
12775  // explicitly treat "-" as index beyond the end
12776  ptr = &ptr->operator[](ptr->m_value.array->size());
12777  }
12778  else
12779  {
12780  // convert array index to number; unchecked access
12781  JSON_TRY
12782  {
12783  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
12784  }
12785  JSON_CATCH (std::invalid_argument&)
12786  {
12787  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12788  }
12789  }
12790  break;
12791  }
12792 
12793  default:
12794  {
12795  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12796  }
12797  }
12798  }
12799 
12800  return *ptr;
12801  }
12802 
12809  reference get_checked(pointer ptr) const
12810  {
12811  for (const auto& reference_token : reference_tokens)
12812  {
12813  switch (ptr->m_type)
12814  {
12815  case value_t::object:
12816  {
12817  // note: at performs range check
12818  ptr = &ptr->at(reference_token);
12819  break;
12820  }
12821 
12822  case value_t::array:
12823  {
12824  if (reference_token == "-")
12825  {
12826  // "-" always fails the range check
12827  JSON_THROW(out_of_range::create(402, "array index '-' (" +
12828  std::to_string(ptr->m_value.array->size()) +
12829  ") is out of range"));
12830  }
12831 
12832  // error condition (cf. RFC 6901, Sect. 4)
12833  if (reference_token.size() > 1 and reference_token[0] == '0')
12834  {
12835  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
12836  }
12837 
12838  // note: at performs range check
12839  JSON_TRY
12840  {
12841  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12842  }
12843  JSON_CATCH (std::invalid_argument&)
12844  {
12845  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12846  }
12847  break;
12848  }
12849 
12850  default:
12851  {
12852  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12853  }
12854  }
12855  }
12856 
12857  return *ptr;
12858  }
12859 
12873  const_reference get_unchecked(const_pointer ptr) const
12874  {
12875  for (const auto& reference_token : reference_tokens)
12876  {
12877  switch (ptr->m_type)
12878  {
12879  case value_t::object:
12880  {
12881  // use unchecked object access
12882  ptr = &ptr->operator[](reference_token);
12883  break;
12884  }
12885 
12886  case value_t::array:
12887  {
12888  if (reference_token == "-")
12889  {
12890  // "-" cannot be used for const access
12891  JSON_THROW(out_of_range::create(402, "array index '-' (" +
12892  std::to_string(ptr->m_value.array->size()) +
12893  ") is out of range"));
12894  }
12895 
12896  // error condition (cf. RFC 6901, Sect. 4)
12897  if (reference_token.size() > 1 and reference_token[0] == '0')
12898  {
12899  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
12900  }
12901 
12902  // use unchecked array access
12903  JSON_TRY
12904  {
12905  ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
12906  }
12907  JSON_CATCH (std::invalid_argument&)
12908  {
12909  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12910  }
12911  break;
12912  }
12913 
12914  default:
12915  {
12916  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12917  }
12918  }
12919  }
12920 
12921  return *ptr;
12922  }
12923 
12930  const_reference get_checked(const_pointer ptr) const
12931  {
12932  for (const auto& reference_token : reference_tokens)
12933  {
12934  switch (ptr->m_type)
12935  {
12936  case value_t::object:
12937  {
12938  // note: at performs range check
12939  ptr = &ptr->at(reference_token);
12940  break;
12941  }
12942 
12943  case value_t::array:
12944  {
12945  if (reference_token == "-")
12946  {
12947  // "-" always fails the range check
12948  JSON_THROW(out_of_range::create(402, "array index '-' (" +
12949  std::to_string(ptr->m_value.array->size()) +
12950  ") is out of range"));
12951  }
12952 
12953  // error condition (cf. RFC 6901, Sect. 4)
12954  if (reference_token.size() > 1 and reference_token[0] == '0')
12955  {
12956  JSON_THROW(parse_error::create(106, 0, "array index '" + reference_token + "' must not begin with '0'"));
12957  }
12958 
12959  // note: at performs range check
12960  JSON_TRY
12961  {
12962  ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12963  }
12964  JSON_CATCH (std::invalid_argument&)
12965  {
12966  JSON_THROW(parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
12967  }
12968  break;
12969  }
12970 
12971  default:
12972  {
12973  JSON_THROW(out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12974  }
12975  }
12976  }
12977 
12978  return *ptr;
12979  }
12980 
12990  static std::vector<std::string> split(const std::string& reference_string)
12991  {
12992  std::vector<std::string> result;
12993 
12994  // special case: empty reference string -> no reference tokens
12995  if (reference_string.empty())
12996  {
12997  return result;
12998  }
12999 
13000  // check if nonempty reference string begins with slash
13001  if (reference_string[0] != '/')
13002  {
13003  JSON_THROW(parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'"));
13004  }
13005 
13006  // extract the reference tokens:
13007  // - slash: position of the last read slash (or end of string)
13008  // - start: position after the previous slash
13009  for (
13010  // search for the first slash after the first character
13011  size_t slash = reference_string.find_first_of('/', 1),
13012  // set the beginning of the first reference token
13013  start = 1;
13014  // we can stop if start == string::npos+1 = 0
13015  start != 0;
13016  // set the beginning of the next reference token
13017  // (will eventually be 0 if slash == std::string::npos)
13018  start = slash + 1,
13019  // find next slash
13020  slash = reference_string.find_first_of('/', start))
13021  {
13022  // use the text between the beginning of the reference token
13023  // (start) and the last slash (slash).
13024  auto reference_token = reference_string.substr(start, slash - start);
13025 
13026  // check reference tokens are properly escaped
13027  for (size_t pos = reference_token.find_first_of('~');
13028  pos != std::string::npos;
13029  pos = reference_token.find_first_of('~', pos + 1))
13030  {
13031  assert(reference_token[pos] == '~');
13032 
13033  // ~ must be followed by 0 or 1
13034  if (pos == reference_token.size() - 1 or
13035  (reference_token[pos + 1] != '0' and
13036  reference_token[pos + 1] != '1'))
13037  {
13038  JSON_THROW(parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
13039  }
13040  }
13041 
13042  // finally, store the reference token
13043  unescape(reference_token);
13044  result.push_back(reference_token);
13045  }
13046 
13047  return result;
13048  }
13049 
13063  static void replace_substring(std::string& s,
13064  const std::string& f,
13065  const std::string& t)
13066  {
13067  assert(not f.empty());
13068 
13069  for (
13070  size_t pos = s.find(f); // find first occurrence of f
13071  pos != std::string::npos; // make sure f was found
13072  s.replace(pos, f.size(), t), // replace with t
13073  pos = s.find(f, pos + t.size()) // find next occurrence of f
13074  );
13075  }
13076 
13078  static std::string escape(std::string s)
13079  {
13080  // escape "~"" to "~0" and "/" to "~1"
13081  replace_substring(s, "~", "~0");
13082  replace_substring(s, "/", "~1");
13083  return s;
13084  }
13085 
13087  static void unescape(std::string& s)
13088  {
13089  // first transform any occurrence of the sequence '~1' to '/'
13090  replace_substring(s, "~1", "/");
13091  // then transform any occurrence of the sequence '~0' to '~'
13092  replace_substring(s, "~0", "~");
13093  }
13094 
13102  static void flatten(const std::string& reference_string,
13103  const basic_json& value,
13104  basic_json& result)
13105  {
13106  switch (value.m_type)
13107  {
13108  case value_t::array:
13109  {
13110  if (value.m_value.array->empty())
13111  {
13112  // flatten empty array as null
13113  result[reference_string] = nullptr;
13114  }
13115  else
13116  {
13117  // iterate array and use index as reference string
13118  for (size_t i = 0; i < value.m_value.array->size(); ++i)
13119  {
13120  flatten(reference_string + "/" + std::to_string(i),
13121  value.m_value.array->operator[](i), result);
13122  }
13123  }
13124  break;
13125  }
13126 
13127  case value_t::object:
13128  {
13129  if (value.m_value.object->empty())
13130  {
13131  // flatten empty object as null
13132  result[reference_string] = nullptr;
13133  }
13134  else
13135  {
13136  // iterate object and use keys as reference string
13137  for (const auto& element : *value.m_value.object)
13138  {
13139  flatten(reference_string + "/" + escape(element.first),
13140  element.second, result);
13141  }
13142  }
13143  break;
13144  }
13145 
13146  default:
13147  {
13148  // add primitive value with its reference string
13149  result[reference_string] = value;
13150  break;
13151  }
13152  }
13153  }
13154 
13165  static basic_json unflatten(const basic_json& value)
13166  {
13167  if (not value.is_object())
13168  {
13169  JSON_THROW(type_error::create(314, "only objects can be unflattened"));
13170  }
13171 
13172  basic_json result;
13173 
13174  // iterate the JSON object values
13175  for (const auto& element : *value.m_value.object)
13176  {
13177  if (not element.second.is_primitive())
13178  {
13179  JSON_THROW(type_error::create(315, "values in object must be primitive"));
13180  }
13181 
13182  // assign value to reference pointed to by JSON pointer; Note
13183  // that if the JSON pointer is "" (i.e., points to the whole
13184  // value), function get_and_create returns a reference to
13185  // result itself. An assignment will then create a primitive
13186  // value.
13187  json_pointer(element.first).get_and_create(result) = element.second;
13188  }
13189 
13190  return result;
13191  }
13192 
13193  friend bool operator==(json_pointer const& lhs,
13194  json_pointer const& rhs) noexcept
13195  {
13196  return lhs.reference_tokens == rhs.reference_tokens;
13197  }
13198 
13199  friend bool operator!=(json_pointer const& lhs,
13200  json_pointer const& rhs) noexcept
13201  {
13202  return !(lhs == rhs);
13203  }
13204 
13206  std::vector<std::string> reference_tokens {};
13207  };
13208 
13210  // JSON Pointer support //
13212 
13215 
13249  reference operator[](const json_pointer& ptr)
13250  {
13251  return ptr.get_unchecked(this);
13252  }
13253 
13277  const_reference operator[](const json_pointer& ptr) const
13278  {
13279  return ptr.get_unchecked(this);
13280  }
13281 
13317  reference at(const json_pointer& ptr)
13318  {
13319  return ptr.get_checked(this);
13320  }
13321 
13357  const_reference at(const json_pointer& ptr) const
13358  {
13359  return ptr.get_checked(this);
13360  }
13361 
13384  basic_json flatten() const
13385  {
13386  basic_json result(value_t::object);
13387  json_pointer::flatten("", *this, result);
13388  return result;
13389  }
13390 
13421  basic_json unflatten() const
13422  {
13423  return json_pointer::unflatten(*this);
13424  }
13425 
13427 
13429  // JSON Patch functions //
13431 
13434 
13482  basic_json patch(const basic_json& json_patch) const
13483  {
13484  // make a working copy to apply the patch to
13485  basic_json result = *this;
13486 
13487  // the valid JSON Patch operations
13488  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13489 
13490  const auto get_op = [](const std::string & op)
13491  {
13492  if (op == "add")
13493  {
13494  return patch_operations::add;
13495  }
13496  if (op == "remove")
13497  {
13498  return patch_operations::remove;
13499  }
13500  if (op == "replace")
13501  {
13502  return patch_operations::replace;
13503  }
13504  if (op == "move")
13505  {
13506  return patch_operations::move;
13507  }
13508  if (op == "copy")
13509  {
13510  return patch_operations::copy;
13511  }
13512  if (op == "test")
13513  {
13514  return patch_operations::test;
13515  }
13516 
13517  return patch_operations::invalid;
13518  };
13519 
13520  // wrapper for "add" operation; add value at ptr
13521  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
13522  {
13523  // adding to the root of the target document means replacing it
13524  if (ptr.is_root())
13525  {
13526  result = val;
13527  }
13528  else
13529  {
13530  // make sure the top element of the pointer exists
13531  json_pointer top_pointer = ptr.top();
13532  if (top_pointer != ptr)
13533  {
13534  result.at(top_pointer);
13535  }
13536 
13537  // get reference to parent of JSON pointer ptr
13538  const auto last_path = ptr.pop_back();
13539  basic_json& parent = result[ptr];
13540 
13541  switch (parent.m_type)
13542  {
13543  case value_t::null:
13544  case value_t::object:
13545  {
13546  // use operator[] to add value
13547  parent[last_path] = val;
13548  break;
13549  }
13550 
13551  case value_t::array:
13552  {
13553  if (last_path == "-")
13554  {
13555  // special case: append to back
13556  parent.push_back(val);
13557  }
13558  else
13559  {
13560  const auto idx = std::stoi(last_path);
13561  if (static_cast<size_type>(idx) > parent.size())
13562  {
13563  // avoid undefined behavior
13564  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
13565  }
13566  else
13567  {
13568  // default case: insert add offset
13569  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
13570  }
13571  }
13572  break;
13573  }
13574 
13575  default:
13576  {
13577  // if there exists a parent it cannot be primitive
13578  assert(false); // LCOV_EXCL_LINE
13579  }
13580  }
13581  }
13582  };
13583 
13584  // wrapper for "remove" operation; remove value at ptr
13585  const auto operation_remove = [&result](json_pointer & ptr)
13586  {
13587  // get reference to parent of JSON pointer ptr
13588  const auto last_path = ptr.pop_back();
13589  basic_json& parent = result.at(ptr);
13590 
13591  // remove child
13592  if (parent.is_object())
13593  {
13594  // perform range check
13595  auto it = parent.find(last_path);
13596  if (it != parent.end())
13597  {
13598  parent.erase(it);
13599  }
13600  else
13601  {
13602  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
13603  }
13604  }
13605  else if (parent.is_array())
13606  {
13607  // note erase performs range check
13608  parent.erase(static_cast<size_type>(std::stoi(last_path)));
13609  }
13610  };
13611 
13612  // type check: top level value must be an array
13613  if (not json_patch.is_array())
13614  {
13615  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
13616  }
13617 
13618  // iterate and apply the operations
13619  for (const auto& val : json_patch)
13620  {
13621  // wrapper to get a value for an operation
13622  const auto get_value = [&val](const std::string & op,
13623  const std::string & member,
13624  bool string_type) -> basic_json&
13625  {
13626  // find value
13627  auto it = val.m_value.object->find(member);
13628 
13629  // context-sensitive error message
13630  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
13631 
13632  // check if desired value is present
13633  if (it == val.m_value.object->end())
13634  {
13635  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
13636  }
13637 
13638  // check if result is of type string
13639  if (string_type and not it->second.is_string())
13640  {
13641  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
13642  }
13643 
13644  // no error: return value
13645  return it->second;
13646  };
13647 
13648  // type check: every element of the array must be an object
13649  if (not val.is_object())
13650  {
13651  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
13652  }
13653 
13654  // collect mandatory members
13655  const std::string op = get_value("op", "op", true);
13656  const std::string path = get_value(op, "path", true);
13657  json_pointer ptr(path);
13658 
13659  switch (get_op(op))
13660  {
13661  case patch_operations::add:
13662  {
13663  operation_add(ptr, get_value("add", "value", false));
13664  break;
13665  }
13666 
13667  case patch_operations::remove:
13668  {
13669  operation_remove(ptr);
13670  break;
13671  }
13672 
13673  case patch_operations::replace:
13674  {
13675  // the "path" location must exist - use at()
13676  result.at(ptr) = get_value("replace", "value", false);
13677  break;
13678  }
13679 
13680  case patch_operations::move:
13681  {
13682  const std::string from_path = get_value("move", "from", true);
13683  json_pointer from_ptr(from_path);
13684 
13685  // the "from" location must exist - use at()
13686  basic_json v = result.at(from_ptr);
13687 
13688  // The move operation is functionally identical to a
13689  // "remove" operation on the "from" location, followed
13690  // immediately by an "add" operation at the target
13691  // location with the value that was just removed.
13692  operation_remove(from_ptr);
13693  operation_add(ptr, v);
13694  break;
13695  }
13696 
13697  case patch_operations::copy:
13698  {
13699  const std::string from_path = get_value("copy", "from", true);;
13700  const json_pointer from_ptr(from_path);
13701 
13702  // the "from" location must exist - use at()
13703  result[ptr] = result.at(from_ptr);
13704  break;
13705  }
13706 
13707  case patch_operations::test:
13708  {
13709  bool success = false;
13710  JSON_TRY
13711  {
13712  // check if "value" matches the one at "path"
13713  // the "path" location must exist - use at()
13714  success = (result.at(ptr) == get_value("test", "value", false));
13715  }
13716  JSON_CATCH (out_of_range&)
13717  {
13718  // ignore out of range errors: success remains false
13719  }
13720 
13721  // throw an exception if test fails
13722  if (not success)
13723  {
13724  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
13725  }
13726 
13727  break;
13728  }
13729 
13730  case patch_operations::invalid:
13731  {
13732  // op must be "add", "remove", "replace", "move", "copy", or
13733  // "test"
13734  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
13735  }
13736  }
13737  }
13738 
13739  return result;
13740  }
13741 
13774  static basic_json diff(const basic_json& source,
13775  const basic_json& target,
13776  const std::string& path = "")
13777  {
13778  // the patch
13779  basic_json result(value_t::array);
13780 
13781  // if the values are the same, return empty patch
13782  if (source == target)
13783  {
13784  return result;
13785  }
13787  if (source.type() != target.type())
13788  {
13789  // different types: replace value
13790  result.push_back(
13791  {
13792  {"op", "replace"},
13793  {"path", path},
13794  {"value", target}
13795  });
13796  }
13797  else
13798  {
13799  switch (source.type())
13800  {
13801  case value_t::array:
13802  {
13803  // first pass: traverse common elements
13804  size_t i = 0;
13805  while (i < source.size() and i < target.size())
13806  {
13807  // recursive call to compare array values at index i
13808  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
13809  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
13810  ++i;
13811  }
13812 
13813  // i now reached the end of at least one array
13814  // in a second pass, traverse the remaining elements
13815 
13816  // remove my remaining elements
13817  const auto end_index = static_cast<difference_type>(result.size());
13818  while (i < source.size())
13819  {
13820  // add operations in reverse order to avoid invalid
13821  // indices
13822  result.insert(result.begin() + end_index, object(
13823  {
13824  {"op", "remove"},
13825  {"path", path + "/" + std::to_string(i)}
13826  }));
13827  ++i;
13828  }
13829 
13830  // add other remaining elements
13831  while (i < target.size())
13832  {
13833  result.push_back(
13834  {
13835  {"op", "add"},
13836  {"path", path + "/" + std::to_string(i)},
13837  {"value", target[i]}
13838  });
13839  ++i;
13840  }
13841 
13842  break;
13843  }
13844 
13845  case value_t::object:
13846  {
13847  // first pass: traverse this object's elements
13848  for (auto it = source.begin(); it != source.end(); ++it)
13849  {
13850  // escape the key name to be used in a JSON patch
13851  const auto key = json_pointer::escape(it.key());
13852 
13853  if (target.find(it.key()) != target.end())
13854  {
13855  // recursive call to compare object values at key it
13856  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
13857  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
13858  }
13859  else
13860  {
13861  // found a key that is not in o -> remove it
13862  result.push_back(object(
13863  {
13864  {"op", "remove"},
13865  {"path", path + "/" + key}
13866  }));
13867  }
13868  }
13869 
13870  // second pass: traverse other object's elements
13871  for (auto it = target.begin(); it != target.end(); ++it)
13872  {
13873  if (source.find(it.key()) == source.end())
13874  {
13875  // found a key that is not in this -> add it
13876  const auto key = json_pointer::escape(it.key());
13877  result.push_back(
13878  {
13879  {"op", "add"},
13880  {"path", path + "/" + key},
13881  {"value", it.value()}
13882  });
13883  }
13884  }
13885 
13886  break;
13887  }
13888 
13889  default:
13890  {
13891  // both primitive type: replace value
13892  result.push_back(
13893  {
13894  {"op", "replace"},
13895  {"path", path},
13896  {"value", target}
13897  });
13898  break;
13899  }
13900  }
13901  }
13902 
13903  return result;
13904  }
13905 
13907 };
13908 
13910 // presets //
13912 
13921 using json = basic_json<>;
13922 } // namespace nlohmann
13923 
13924 
13926 // nonmember support //
13928 
13929 // specialization of std::swap, and std::hash
13930 namespace std
13931 {
13937 template<>
13938 inline void swap(nlohmann::json& j1,
13939  nlohmann::json& j2) noexcept(
13940  is_nothrow_move_constructible<nlohmann::json>::value and
13941  is_nothrow_move_assignable<nlohmann::json>::value
13942  )
13943 {
13944  j1.swap(j2);
13945 }
13946 
13948 template<>
13949 struct hash<nlohmann::json>
13950 {
13956  std::size_t operator()(const nlohmann::json& j) const
13957  {
13958  // a naive hashing via the string representation
13959  const auto& h = hash<nlohmann::json::string_t>();
13960  return h(j.dump());
13961  }
13962 };
13963 
13965 template <>
13966 struct less<::nlohmann::detail::value_t>
13967 {
13972  bool operator()(nlohmann::detail::value_t lhs,
13973  nlohmann::detail::value_t rhs) const noexcept
13974  {
13975  return nlohmann::detail::operator<(lhs, rhs);
13976  }
13977 };
13978 
13979 } // namespace std
13980 
13994 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
13995 {
13996  return nlohmann::json::parse(s, s + n);
13997 }
13998 
14012 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
14013 {
14014  return nlohmann::json::json_pointer(std::string(s, n));
14015 }
14016 
14017 // restore GCC/clang diagnostic settings
14018 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
14019  #pragma GCC diagnostic pop
14020 #endif
14021 #if defined(__clang__)
14022  #pragma GCC diagnostic pop
14023 #endif
14024 
14025 // clean up
14026 #undef JSON_CATCH
14027 #undef JSON_THROW
14028 #undef JSON_TRY
14029 #undef JSON_DEPRECATED
14030 
14031 #endif
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:1357
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:1304
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:1889
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:1678
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:10322
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4941
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:5012
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2923
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:2208
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:2476
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:2552
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:3679
a class to store JSON values
Definition: json.hpp:1288
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:9721
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:1376
default JSONSerializer template argument
Definition: json.hpp:1160
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:10378
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:4852
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2980
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:1553
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
Definition: json.hpp:7289
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:9725
~basic_json()
destructor
Definition: json.hpp:2816
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:2783
STL namespace.
detail::other_error other_error
exception indicating other errors
Definition: json.hpp:1326
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:9727
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:2352
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3780
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:3054
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:1346
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2953
reference front()
access the first element
Definition: json.hpp:4461
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:1351
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:3692
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:5206
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:1172
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:1750
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:3183
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:1821
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:5334
parse string into a built-in arithmetic type as if the current locale is POSIX.
Definition: json.hpp:11978
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:1324
static basic_json meta()
returns version information on the library
Definition: json.hpp:1404
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:2500
constexpr const auto & from_json
Definition: json.hpp:1148
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:3024
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:1322
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:3602
namespace for Niels Lohmann
Definition: json.hpp:106
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:3083
basic_json(const value_t value_type)
create an empty value with a given type
Definition: json.hpp:2184
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:3161
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:3139
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:5082
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:1318
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:1188
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:2148
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:3205
constexpr const auto & to_json
Definition: json.hpp:1147
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:1599
string_t dump(const int indent=-1) const
serialization
Definition: json.hpp:2888
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:1349
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:1354
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:2274
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:3002
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:1359
StringType string_t
a type for a string
Definition: json.hpp:1652
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:2435
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:2746
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:3111
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:9717
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:3630
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:10324
a template for a reverse iterator class
Definition: json.hpp:1301
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:5529
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:5811
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:1341
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:1316
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:6055
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:2669
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:1320
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:4572
a template for a random access iterator for the basic_json class
Definition: json.hpp:1300
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:3232
parse_event_t
JSON callback events.
Definition: json.hpp:2078
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:5119