00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef NLOHMANN_JSON_HPP
00030 #define NLOHMANN_JSON_HPP
00031
00032 #include <algorithm>
00033 #include <array>
00034 #include <cassert>
00035 #include <cerrno>
00036 #include <ciso646>
00037 #include <cmath>
00038 #include <cstddef>
00039 #include <cstdio>
00040 #include <cstdlib>
00041 #include <functional>
00042 #include <initializer_list>
00043 #include <iomanip>
00044 #include <iostream>
00045 #include <iterator>
00046 #include <limits>
00047 #include <map>
00048 #include <memory>
00049 #include <sstream>
00050 #include <stdexcept>
00051 #include <string>
00052 #include <type_traits>
00053 #include <utility>
00054 #include <vector>
00055
00056
00057 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
00058 #pragma GCC diagnostic push
00059 #pragma GCC diagnostic ignored "-Wfloat-equal"
00060 #endif
00061
00067 namespace nlohmann
00068 {
00069
00070
00075 namespace
00076 {
00081 template<typename T>
00082 struct has_mapped_type
00083 {
00084 private:
00085 template<typename C> static char test(typename C::mapped_type*);
00086 template<typename C> static char (&test(...))[2];
00087 public:
00088 static constexpr bool value = sizeof(test<T>(0)) == 1;
00089 };
00090
00095 class DecimalSeparator : public std::numpunct<char>
00096 {
00097 protected:
00098 char do_decimal_point() const
00099 {
00100 return '.';
00101 }
00102 };
00103
00104 }
00105
00177 template <
00178 template<typename U, typename V, typename... Args> class ObjectType = std::map,
00179 template<typename U, typename... Args> class ArrayType = std::vector,
00180 class StringType = std::string,
00181 class BooleanType = bool,
00182 class NumberIntegerType = std::int64_t,
00183 class NumberUnsignedType = std::uint64_t,
00184 class NumberFloatType = double,
00185 template<typename U> class AllocatorType = std::allocator
00186 >
00187 class basic_json
00188 {
00189 private:
00191 using basic_json_t = basic_json<ObjectType,
00192 ArrayType,
00193 StringType,
00194 BooleanType,
00195 NumberIntegerType,
00196 NumberUnsignedType,
00197 NumberFloatType,
00198 AllocatorType>;
00199
00200 public:
00201
00202 template<typename Base> class json_reverse_iterator;
00203 class json_pointer;
00204
00206
00208
00211
00213 using value_type = basic_json;
00214
00216 using reference = value_type&;
00218 using const_reference = const value_type&;
00219
00221 using difference_type = std::ptrdiff_t;
00223 using size_type = std::size_t;
00224
00226 using allocator_type = AllocatorType<basic_json>;
00227
00229 using pointer = typename std::allocator_traits<allocator_type>::pointer;
00231 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
00232
00234 class iterator;
00236 class const_iterator;
00238 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
00240 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
00241
00243
00244
00248 static allocator_type get_allocator()
00249 {
00250 return allocator_type();
00251 }
00252
00253
00255
00257
00260
00344 using object_t = ObjectType<StringType,
00345 basic_json,
00346 std::less<StringType>,
00347 AllocatorType<std::pair<const StringType,
00348 basic_json>>>;
00349
00394 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
00395
00441 using string_t = StringType;
00442
00467 using boolean_t = BooleanType;
00468
00539 using number_integer_t = NumberIntegerType;
00540
00611 using number_unsigned_t = NumberUnsignedType;
00612
00679 using number_float_t = NumberFloatType;
00680
00682
00683
00685
00687
00698 enum class value_t : uint8_t
00699 {
00700 null,
00701 object,
00702 array,
00703 string,
00704 boolean,
00705 number_integer,
00706 number_unsigned,
00707 number_float,
00708 discarded
00709 };
00710
00711
00712 private:
00713
00715 template<typename T, typename... Args>
00716 static T* create(Args&& ... args)
00717 {
00718 AllocatorType<T> alloc;
00719 auto deleter = [&](T * object)
00720 {
00721 alloc.deallocate(object, 1);
00722 };
00723 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
00724 alloc.construct(object.get(), std::forward<Args>(args)...);
00725 return object.release();
00726 }
00727
00729
00731
00739 union json_value
00740 {
00742 object_t* object;
00744 array_t* array;
00746 string_t* string;
00748 boolean_t boolean;
00750 number_integer_t number_integer;
00752 number_unsigned_t number_unsigned;
00754 number_float_t number_float;
00755
00757 json_value() = default;
00759 json_value(boolean_t v) noexcept : boolean(v) {}
00761 json_value(number_integer_t v) noexcept : number_integer(v) {}
00763 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
00765 json_value(number_float_t v) noexcept : number_float(v) {}
00767 json_value(value_t t)
00768 {
00769 switch (t)
00770 {
00771 case value_t::object:
00772 {
00773 object = create<object_t>();
00774 break;
00775 }
00776
00777 case value_t::array:
00778 {
00779 array = create<array_t>();
00780 break;
00781 }
00782
00783 case value_t::string:
00784 {
00785 string = create<string_t>("");
00786 break;
00787 }
00788
00789 case value_t::boolean:
00790 {
00791 boolean = boolean_t(false);
00792 break;
00793 }
00794
00795 case value_t::number_integer:
00796 {
00797 number_integer = number_integer_t(0);
00798 break;
00799 }
00800
00801 case value_t::number_unsigned:
00802 {
00803 number_unsigned = number_unsigned_t(0);
00804 break;
00805 }
00806
00807 case value_t::number_float:
00808 {
00809 number_float = number_float_t(0.0);
00810 break;
00811 }
00812
00813 default:
00814 {
00815 break;
00816 }
00817 }
00818 }
00819
00821 json_value(const string_t& value)
00822 {
00823 string = create<string_t>(value);
00824 }
00825
00827 json_value(const object_t& value)
00828 {
00829 object = create<object_t>(value);
00830 }
00831
00833 json_value(const array_t& value)
00834 {
00835 array = create<array_t>(value);
00836 }
00837 };
00838
00839
00840 public:
00842
00844
00853 enum class parse_event_t : uint8_t
00854 {
00856 object_start,
00858 object_end,
00860 array_start,
00862 array_end,
00864 key,
00866 value
00867 };
00868
00918 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
00919
00920
00922
00924
00927
00967 basic_json(const value_t value_type)
00968 : m_type(value_type), m_value(value_type)
00969 {}
00970
00995 basic_json() = default;
00996
01019 basic_json(std::nullptr_t) noexcept
01020 : basic_json(value_t::null)
01021 {}
01022
01042 basic_json(const object_t& val)
01043 : m_type(value_t::object), m_value(val)
01044 {}
01045
01072 template <class CompatibleObjectType, typename
01073 std::enable_if<
01074 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
01075 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value, int>::type
01076 = 0>
01077 basic_json(const CompatibleObjectType& val)
01078 : m_type(value_t::object)
01079 {
01080 using std::begin;
01081 using std::end;
01082 m_value.object = create<object_t>(begin(val), end(val));
01083 }
01084
01104 basic_json(const array_t& val)
01105 : m_type(value_t::array), m_value(val)
01106 {}
01107
01134 template <class CompatibleArrayType, typename
01135 std::enable_if<
01136 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
01137 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
01138 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
01139 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
01140 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
01141 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
01142 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value, int>::type
01143 = 0>
01144 basic_json(const CompatibleArrayType& val)
01145 : m_type(value_t::array)
01146 {
01147 using std::begin;
01148 using std::end;
01149 m_value.array = create<array_t>(begin(val), end(val));
01150 }
01151
01173 basic_json(const string_t& val)
01174 : m_type(value_t::string), m_value(val)
01175 {}
01176
01197 basic_json(const typename string_t::value_type* val)
01198 : basic_json(string_t(val))
01199 {}
01200
01224 template <class CompatibleStringType, typename
01225 std::enable_if<
01226 std::is_constructible<string_t, CompatibleStringType>::value, int>::type
01227 = 0>
01228 basic_json(const CompatibleStringType& val)
01229 : basic_json(string_t(val))
01230 {}
01231
01246 basic_json(boolean_t val) noexcept
01247 : m_type(value_t::boolean), m_value(val)
01248 {}
01249
01273 template<typename T,
01274 typename std::enable_if<
01275 not (std::is_same<T, int>::value)
01276 and std::is_same<T, number_integer_t>::value
01277 , int>::type
01278 = 0>
01279 basic_json(const number_integer_t val) noexcept
01280 : m_type(value_t::number_integer), m_value(val)
01281 {}
01282
01308 basic_json(const int val) noexcept
01309 : m_type(value_t::number_integer),
01310 m_value(static_cast<number_integer_t>(val))
01311 {}
01312
01338 template<typename CompatibleNumberIntegerType, typename
01339 std::enable_if<
01340 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
01341 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
01342 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
01343 CompatibleNumberIntegerType>::type
01344 = 0>
01345 basic_json(const CompatibleNumberIntegerType val) noexcept
01346 : m_type(value_t::number_integer),
01347 m_value(static_cast<number_integer_t>(val))
01348 {}
01349
01367 template<typename T,
01368 typename std::enable_if<
01369 not (std::is_same<T, int>::value)
01370 and std::is_same<T, number_unsigned_t>::value
01371 , int>::type
01372 = 0>
01373 basic_json(const number_unsigned_t val) noexcept
01374 : m_type(value_t::number_unsigned), m_value(val)
01375 {}
01376
01397 template <typename CompatibleNumberUnsignedType, typename
01398 std::enable_if <
01399 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
01400 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
01401 not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
01402 CompatibleNumberUnsignedType>::type
01403 = 0>
01404 basic_json(const CompatibleNumberUnsignedType val) noexcept
01405 : m_type(value_t::number_unsigned),
01406 m_value(static_cast<number_unsigned_t>(val))
01407 {}
01408
01433 basic_json(const number_float_t val) noexcept
01434 : m_type(value_t::number_float), m_value(val)
01435 {
01436
01437 if (not std::isfinite(val))
01438 {
01439 m_type = value_t::null;
01440 m_value = json_value();
01441 }
01442 }
01443
01475 template<typename CompatibleNumberFloatType, typename = typename
01476 std::enable_if<
01477 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
01478 std::is_floating_point<CompatibleNumberFloatType>::value>::type
01479 >
01480 basic_json(const CompatibleNumberFloatType val) noexcept
01481 : basic_json(number_float_t(val))
01482 {}
01483
01553 basic_json(std::initializer_list<basic_json> init,
01554 bool type_deduction = true,
01555 value_t manual_type = value_t::array)
01556 {
01557
01558 bool is_an_object = true;
01559
01560
01561
01562 for (const auto& element : init)
01563 {
01564 if (not element.is_array() or element.size() != 2
01565 or not element[0].is_string())
01566 {
01567
01568
01569 is_an_object = false;
01570 break;
01571 }
01572 }
01573
01574
01575 if (not type_deduction)
01576 {
01577
01578 if (manual_type == value_t::array)
01579 {
01580 is_an_object = false;
01581 }
01582
01583
01584 if (manual_type == value_t::object and not is_an_object)
01585 {
01586 throw std::domain_error("cannot create object from initializer list");
01587 }
01588 }
01589
01590 if (is_an_object)
01591 {
01592
01593 m_type = value_t::object;
01594 m_value = value_t::object;
01595
01596 assert(m_value.object != nullptr);
01597
01598 for (auto& element : init)
01599 {
01600 m_value.object->emplace(*(element[0].m_value.string), element[1]);
01601 }
01602 }
01603 else
01604 {
01605
01606 m_type = value_t::array;
01607 m_value.array = create<array_t>(init);
01608 }
01609 }
01610
01645 static basic_json array(std::initializer_list<basic_json> init =
01646 std::initializer_list<basic_json>())
01647 {
01648 return basic_json(init, false, value_t::array);
01649 }
01650
01685 static basic_json object(std::initializer_list<basic_json> init =
01686 std::initializer_list<basic_json>())
01687 {
01688 return basic_json(init, false, value_t::object);
01689 }
01690
01709 basic_json(size_type cnt, const basic_json& val)
01710 : m_type(value_t::array)
01711 {
01712 m_value.array = create<array_t>(cnt, val);
01713 }
01714
01749 template <class InputIT, typename
01750 std::enable_if<
01751 std::is_same<InputIT, typename basic_json_t::iterator>::value or
01752 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
01753 , int>::type
01754 = 0>
01755 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
01756 {
01757
01758 if (first.m_object != last.m_object)
01759 {
01760 throw std::domain_error("iterators are not compatible");
01761 }
01762
01763
01764 switch (m_type)
01765 {
01766 case value_t::boolean:
01767 case value_t::number_float:
01768 case value_t::number_integer:
01769 case value_t::number_unsigned:
01770 case value_t::string:
01771 {
01772 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
01773 {
01774 throw std::out_of_range("iterators out of range");
01775 }
01776 break;
01777 }
01778
01779 default:
01780 {
01781 break;
01782 }
01783 }
01784
01785 switch (m_type)
01786 {
01787 case value_t::number_integer:
01788 {
01789 assert(first.m_object != nullptr);
01790 m_value.number_integer = first.m_object->m_value.number_integer;
01791 break;
01792 }
01793
01794 case value_t::number_unsigned:
01795 {
01796 assert(first.m_object != nullptr);
01797 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
01798 break;
01799 }
01800
01801 case value_t::number_float:
01802 {
01803 assert(first.m_object != nullptr);
01804 m_value.number_float = first.m_object->m_value.number_float;
01805 break;
01806 }
01807
01808 case value_t::boolean:
01809 {
01810 assert(first.m_object != nullptr);
01811 m_value.boolean = first.m_object->m_value.boolean;
01812 break;
01813 }
01814
01815 case value_t::string:
01816 {
01817 assert(first.m_object != nullptr);
01818 m_value = *first.m_object->m_value.string;
01819 break;
01820 }
01821
01822 case value_t::object:
01823 {
01824 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
01825 break;
01826 }
01827
01828 case value_t::array:
01829 {
01830 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
01831 break;
01832 }
01833
01834 default:
01835 {
01836 assert(first.m_object != nullptr);
01837 throw std::domain_error("cannot use construct with iterators from " + first.m_object->type_name());
01838 }
01839 }
01840 }
01841
01862 explicit basic_json(std::istream& i, parser_callback_t cb = nullptr)
01863 {
01864 *this = parser(i, cb).parse();
01865 }
01866
01868
01870
01893 basic_json(const basic_json& other)
01894 : m_type(other.m_type)
01895 {
01896 switch (m_type)
01897 {
01898 case value_t::object:
01899 {
01900 assert(other.m_value.object != nullptr);
01901 m_value = *other.m_value.object;
01902 break;
01903 }
01904
01905 case value_t::array:
01906 {
01907 assert(other.m_value.array != nullptr);
01908 m_value = *other.m_value.array;
01909 break;
01910 }
01911
01912 case value_t::string:
01913 {
01914 assert(other.m_value.string != nullptr);
01915 m_value = *other.m_value.string;
01916 break;
01917 }
01918
01919 case value_t::boolean:
01920 {
01921 m_value = other.m_value.boolean;
01922 break;
01923 }
01924
01925 case value_t::number_integer:
01926 {
01927 m_value = other.m_value.number_integer;
01928 break;
01929 }
01930
01931 case value_t::number_unsigned:
01932 {
01933 m_value = other.m_value.number_unsigned;
01934 break;
01935 }
01936
01937 case value_t::number_float:
01938 {
01939 m_value = other.m_value.number_float;
01940 break;
01941 }
01942
01943 default:
01944 {
01945 break;
01946 }
01947 }
01948 }
01949
01968 basic_json(basic_json&& other) noexcept
01969 : m_type(std::move(other.m_type)),
01970 m_value(std::move(other.m_value))
01971 {
01972
01973 other.m_type = value_t::null;
01974 other.m_value = {};
01975 }
01976
02000 reference& operator=(basic_json other) noexcept (
02001 std::is_nothrow_move_constructible<value_t>::value and
02002 std::is_nothrow_move_assignable<value_t>::value and
02003 std::is_nothrow_move_constructible<json_value>::value and
02004 std::is_nothrow_move_assignable<json_value>::value
02005 )
02006 {
02007 using std::swap;
02008 swap(m_type, other.m_type);
02009 swap(m_value, other.m_value);
02010 return *this;
02011 }
02012
02028 ~basic_json()
02029 {
02030 switch (m_type)
02031 {
02032 case value_t::object:
02033 {
02034 AllocatorType<object_t> alloc;
02035 alloc.destroy(m_value.object);
02036 alloc.deallocate(m_value.object, 1);
02037 break;
02038 }
02039
02040 case value_t::array:
02041 {
02042 AllocatorType<array_t> alloc;
02043 alloc.destroy(m_value.array);
02044 alloc.deallocate(m_value.array, 1);
02045 break;
02046 }
02047
02048 case value_t::string:
02049 {
02050 AllocatorType<string_t> alloc;
02051 alloc.destroy(m_value.string);
02052 alloc.deallocate(m_value.string, 1);
02053 break;
02054 }
02055
02056 default:
02057 {
02058
02059 break;
02060 }
02061 }
02062 }
02063
02065
02066 public:
02068
02070
02073
02097 string_t dump(const int indent = -1) const
02098 {
02099 std::stringstream ss;
02100
02101 if (indent >= 0)
02102 {
02103 dump(ss, true, static_cast<unsigned int>(indent));
02104 }
02105 else
02106 {
02107 dump(ss, false, 0);
02108 }
02109
02110 return ss.str();
02111 }
02112
02131 constexpr value_t type() const noexcept
02132 {
02133 return m_type;
02134 }
02135
02161 constexpr bool is_primitive() const noexcept
02162 {
02163 return is_null() or is_string() or is_boolean() or is_number();
02164 }
02165
02188 constexpr bool is_structured() const noexcept
02189 {
02190 return is_array() or is_object();
02191 }
02192
02210 constexpr bool is_null() const noexcept
02211 {
02212 return m_type == value_t::null;
02213 }
02214
02232 constexpr bool is_boolean() const noexcept
02233 {
02234 return m_type == value_t::boolean;
02235 }
02236
02262 constexpr bool is_number() const noexcept
02263 {
02264 return is_number_integer() or is_number_float();
02265 }
02266
02291 constexpr bool is_number_integer() const noexcept
02292 {
02293 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
02294 }
02295
02319 constexpr bool is_number_unsigned() const noexcept
02320 {
02321 return m_type == value_t::number_unsigned;
02322 }
02323
02347 constexpr bool is_number_float() const noexcept
02348 {
02349 return m_type == value_t::number_float;
02350 }
02351
02369 constexpr bool is_object() const noexcept
02370 {
02371 return m_type == value_t::object;
02372 }
02373
02391 constexpr bool is_array() const noexcept
02392 {
02393 return m_type == value_t::array;
02394 }
02395
02413 constexpr bool is_string() const noexcept
02414 {
02415 return m_type == value_t::string;
02416 }
02417
02440 constexpr bool is_discarded() const noexcept
02441 {
02442 return m_type == value_t::discarded;
02443 }
02444
02463 constexpr operator value_t() const noexcept
02464 {
02465 return m_type;
02466 }
02467
02469
02470 private:
02472
02474
02476 template <class T, typename
02477 std::enable_if<
02478 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
02479 std::is_convertible<basic_json_t, typename T::mapped_type>::value
02480 , int>::type = 0>
02481 T get_impl(T*) const
02482 {
02483 if (is_object())
02484 {
02485 assert(m_value.object != nullptr);
02486 return T(m_value.object->begin(), m_value.object->end());
02487 }
02488 else
02489 {
02490 throw std::domain_error("type must be object, but is " + type_name());
02491 }
02492 }
02493
02495 object_t get_impl(object_t*) const
02496 {
02497 if (is_object())
02498 {
02499 assert(m_value.object != nullptr);
02500 return *(m_value.object);
02501 }
02502 else
02503 {
02504 throw std::domain_error("type must be object, but is " + type_name());
02505 }
02506 }
02507
02509 template <class T, typename
02510 std::enable_if<
02511 std::is_convertible<basic_json_t, typename T::value_type>::value and
02512 not std::is_same<basic_json_t, typename T::value_type>::value and
02513 not std::is_arithmetic<T>::value and
02514 not std::is_convertible<std::string, T>::value and
02515 not has_mapped_type<T>::value
02516 , int>::type = 0>
02517 T get_impl(T*) const
02518 {
02519 if (is_array())
02520 {
02521 T to_vector;
02522 assert(m_value.array != nullptr);
02523 std::transform(m_value.array->begin(), m_value.array->end(),
02524 std::inserter(to_vector, to_vector.end()), [](basic_json i)
02525 {
02526 return i.get<typename T::value_type>();
02527 });
02528 return to_vector;
02529 }
02530 else
02531 {
02532 throw std::domain_error("type must be array, but is " + type_name());
02533 }
02534 }
02535
02537 template <class T, typename
02538 std::enable_if<
02539 std::is_convertible<basic_json_t, T>::value and
02540 not std::is_same<basic_json_t, T>::value
02541 , int>::type = 0>
02542 std::vector<T> get_impl(std::vector<T>*) const
02543 {
02544 if (is_array())
02545 {
02546 std::vector<T> to_vector;
02547 assert(m_value.array != nullptr);
02548 to_vector.reserve(m_value.array->size());
02549 std::transform(m_value.array->begin(), m_value.array->end(),
02550 std::inserter(to_vector, to_vector.end()), [](basic_json i)
02551 {
02552 return i.get<T>();
02553 });
02554 return to_vector;
02555 }
02556 else
02557 {
02558 throw std::domain_error("type must be array, but is " + type_name());
02559 }
02560 }
02561
02563 template <class T, typename
02564 std::enable_if<
02565 std::is_same<basic_json, typename T::value_type>::value and
02566 not has_mapped_type<T>::value
02567 , int>::type = 0>
02568 T get_impl(T*) const
02569 {
02570 if (is_array())
02571 {
02572 assert(m_value.array != nullptr);
02573 return T(m_value.array->begin(), m_value.array->end());
02574 }
02575 else
02576 {
02577 throw std::domain_error("type must be array, but is " + type_name());
02578 }
02579 }
02580
02582 array_t get_impl(array_t*) const
02583 {
02584 if (is_array())
02585 {
02586 assert(m_value.array != nullptr);
02587 return *(m_value.array);
02588 }
02589 else
02590 {
02591 throw std::domain_error("type must be array, but is " + type_name());
02592 }
02593 }
02594
02596 template <typename T, typename
02597 std::enable_if<
02598 std::is_convertible<string_t, T>::value
02599 , int>::type = 0>
02600 T get_impl(T*) const
02601 {
02602 if (is_string())
02603 {
02604 assert(m_value.string != nullptr);
02605 return *m_value.string;
02606 }
02607 else
02608 {
02609 throw std::domain_error("type must be string, but is " + type_name());
02610 }
02611 }
02612
02614 template<typename T, typename
02615 std::enable_if<
02616 std::is_arithmetic<T>::value
02617 , int>::type = 0>
02618 T get_impl(T*) const
02619 {
02620 switch (m_type)
02621 {
02622 case value_t::number_integer:
02623 {
02624 return static_cast<T>(m_value.number_integer);
02625 }
02626
02627 case value_t::number_unsigned:
02628 {
02629 return static_cast<T>(m_value.number_unsigned);
02630 }
02631
02632 case value_t::number_float:
02633 {
02634 return static_cast<T>(m_value.number_float);
02635 }
02636
02637 default:
02638 {
02639 throw std::domain_error("type must be number, but is " + type_name());
02640 }
02641 }
02642 }
02643
02645 constexpr boolean_t get_impl(boolean_t*) const
02646 {
02647 return is_boolean()
02648 ? m_value.boolean
02649 : throw std::domain_error("type must be boolean, but is " + type_name());
02650 }
02651
02653 object_t* get_impl_ptr(object_t*) noexcept
02654 {
02655 return is_object() ? m_value.object : nullptr;
02656 }
02657
02659 constexpr const object_t* get_impl_ptr(const object_t*) const noexcept
02660 {
02661 return is_object() ? m_value.object : nullptr;
02662 }
02663
02665 array_t* get_impl_ptr(array_t*) noexcept
02666 {
02667 return is_array() ? m_value.array : nullptr;
02668 }
02669
02671 constexpr const array_t* get_impl_ptr(const array_t*) const noexcept
02672 {
02673 return is_array() ? m_value.array : nullptr;
02674 }
02675
02677 string_t* get_impl_ptr(string_t*) noexcept
02678 {
02679 return is_string() ? m_value.string : nullptr;
02680 }
02681
02683 constexpr const string_t* get_impl_ptr(const string_t*) const noexcept
02684 {
02685 return is_string() ? m_value.string : nullptr;
02686 }
02687
02689 boolean_t* get_impl_ptr(boolean_t*) noexcept
02690 {
02691 return is_boolean() ? &m_value.boolean : nullptr;
02692 }
02693
02695 constexpr const boolean_t* get_impl_ptr(const boolean_t*) const noexcept
02696 {
02697 return is_boolean() ? &m_value.boolean : nullptr;
02698 }
02699
02701 number_integer_t* get_impl_ptr(number_integer_t*) noexcept
02702 {
02703 return is_number_integer() ? &m_value.number_integer : nullptr;
02704 }
02705
02707 constexpr const number_integer_t* get_impl_ptr(const number_integer_t*) const noexcept
02708 {
02709 return is_number_integer() ? &m_value.number_integer : nullptr;
02710 }
02711
02713 number_unsigned_t* get_impl_ptr(number_unsigned_t*) noexcept
02714 {
02715 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
02716 }
02717
02719 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t*) const noexcept
02720 {
02721 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
02722 }
02723
02725 number_float_t* get_impl_ptr(number_float_t*) noexcept
02726 {
02727 return is_number_float() ? &m_value.number_float : nullptr;
02728 }
02729
02731 constexpr const number_float_t* get_impl_ptr(const number_float_t*) const noexcept
02732 {
02733 return is_number_float() ? &m_value.number_float : nullptr;
02734 }
02735
02747 template<typename ReferenceType, typename ThisType>
02748 static ReferenceType get_ref_impl(ThisType& obj)
02749 {
02750
02751 using PointerType = typename std::add_pointer<ReferenceType>::type;
02752 auto ptr = obj.template get_ptr<PointerType>();
02753
02754 if (ptr != nullptr)
02755 {
02756 return *ptr;
02757 }
02758 else
02759 {
02760 throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
02761 obj.type_name());
02762 }
02763 }
02764
02765 public:
02766
02769
02803 template<typename ValueType, typename
02804 std::enable_if<
02805 not std::is_pointer<ValueType>::value
02806 , int>::type = 0>
02807 ValueType get() const
02808 {
02809 return get_impl(static_cast<ValueType*>(nullptr));
02810 }
02811
02838 template<typename PointerType, typename
02839 std::enable_if<
02840 std::is_pointer<PointerType>::value
02841 , int>::type = 0>
02842 PointerType get() noexcept
02843 {
02844
02845 return get_ptr<PointerType>();
02846 }
02847
02852 template<typename PointerType, typename
02853 std::enable_if<
02854 std::is_pointer<PointerType>::value
02855 , int>::type = 0>
02856 constexpr const PointerType get() const noexcept
02857 {
02858
02859 return get_ptr<PointerType>();
02860 }
02861
02887 template<typename PointerType, typename
02888 std::enable_if<
02889 std::is_pointer<PointerType>::value
02890 , int>::type = 0>
02891 PointerType get_ptr() noexcept
02892 {
02893
02894 return get_impl_ptr(static_cast<PointerType>(nullptr));
02895 }
02896
02901 template<typename PointerType, typename
02902 std::enable_if<
02903 std::is_pointer<PointerType>::value
02904 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
02905 , int>::type = 0>
02906 constexpr const PointerType get_ptr() const noexcept
02907 {
02908
02909 return get_impl_ptr(static_cast<const PointerType>(nullptr));
02910 }
02911
02938 template<typename ReferenceType, typename
02939 std::enable_if<
02940 std::is_reference<ReferenceType>::value
02941 , int>::type = 0>
02942 ReferenceType get_ref()
02943 {
02944
02945 return get_ref_impl<ReferenceType>(*this);
02946 }
02947
02952 template<typename ReferenceType, typename
02953 std::enable_if<
02954 std::is_reference<ReferenceType>::value
02955 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
02956 , int>::type = 0>
02957 ReferenceType get_ref() const
02958 {
02959
02960 return get_ref_impl<ReferenceType>(*this);
02961 }
02962
02991 template < typename ValueType, typename
02992 std::enable_if <
02993 not std::is_pointer<ValueType>::value
02994 and not std::is_same<ValueType, typename string_t::value_type>::value
02995 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015
02996 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
02997 #endif
02998 , int >::type = 0 >
02999 operator ValueType() const
03000 {
03001
03002 return get<ValueType>();
03003 }
03004
03006
03007
03009
03011
03014
03037 reference at(size_type idx)
03038 {
03039
03040 if (is_array())
03041 {
03042 try
03043 {
03044 assert(m_value.array != nullptr);
03045 return m_value.array->at(idx);
03046 }
03047 catch (std::out_of_range&)
03048 {
03049
03050 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
03051 }
03052 }
03053 else
03054 {
03055 throw std::domain_error("cannot use at() with " + type_name());
03056 }
03057 }
03058
03081 const_reference at(size_type idx) const
03082 {
03083
03084 if (is_array())
03085 {
03086 try
03087 {
03088 assert(m_value.array != nullptr);
03089 return m_value.array->at(idx);
03090 }
03091 catch (std::out_of_range&)
03092 {
03093
03094 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
03095 }
03096 }
03097 else
03098 {
03099 throw std::domain_error("cannot use at() with " + type_name());
03100 }
03101 }
03102
03129 reference at(const typename object_t::key_type& key)
03130 {
03131
03132 if (is_object())
03133 {
03134 try
03135 {
03136 assert(m_value.object != nullptr);
03137 return m_value.object->at(key);
03138 }
03139 catch (std::out_of_range&)
03140 {
03141
03142 throw std::out_of_range("key '" + key + "' not found");
03143 }
03144 }
03145 else
03146 {
03147 throw std::domain_error("cannot use at() with " + type_name());
03148 }
03149 }
03150
03177 const_reference at(const typename object_t::key_type& key) const
03178 {
03179
03180 if (is_object())
03181 {
03182 try
03183 {
03184 assert(m_value.object != nullptr);
03185 return m_value.object->at(key);
03186 }
03187 catch (std::out_of_range&)
03188 {
03189
03190 throw std::out_of_range("key '" + key + "' not found");
03191 }
03192 }
03193 else
03194 {
03195 throw std::domain_error("cannot use at() with " + type_name());
03196 }
03197 }
03198
03224 reference operator[](size_type idx)
03225 {
03226
03227 if (is_null())
03228 {
03229 m_type = value_t::array;
03230 m_value.array = create<array_t>();
03231 }
03232
03233
03234 if (is_array())
03235 {
03236
03237 assert(m_value.array != nullptr);
03238 for (size_t i = m_value.array->size(); i <= idx; ++i)
03239 {
03240 m_value.array->push_back(basic_json());
03241 }
03242
03243 return m_value.array->operator[](idx);
03244 }
03245 else
03246 {
03247 throw std::domain_error("cannot use operator[] with " + type_name());
03248 }
03249 }
03250
03270 const_reference operator[](size_type idx) const
03271 {
03272
03273 if (is_array())
03274 {
03275 assert(m_value.array != nullptr);
03276 return m_value.array->operator[](idx);
03277 }
03278 else
03279 {
03280 throw std::domain_error("cannot use operator[] with " + type_name());
03281 }
03282 }
03283
03311 reference operator[](const typename object_t::key_type& key)
03312 {
03313
03314 if (is_null())
03315 {
03316 m_type = value_t::object;
03317 m_value.object = create<object_t>();
03318 }
03319
03320
03321 if (is_object())
03322 {
03323 assert(m_value.object != nullptr);
03324 return m_value.object->operator[](key);
03325 }
03326 else
03327 {
03328 throw std::domain_error("cannot use operator[] with " + type_name());
03329 }
03330 }
03331
03359 const_reference operator[](const typename object_t::key_type& key) const
03360 {
03361
03362 if (is_object())
03363 {
03364 assert(m_value.object != nullptr);
03365 assert(m_value.object->find(key) != m_value.object->end());
03366 return m_value.object->find(key)->second;
03367 }
03368 else
03369 {
03370 throw std::domain_error("cannot use operator[] with " + type_name());
03371 }
03372 }
03373
03401 template<typename T, std::size_t n>
03402 reference operator[](T * (&key)[n])
03403 {
03404 return operator[](static_cast<const T>(key));
03405 }
03406
03436 template<typename T, std::size_t n>
03437 const_reference operator[](T * (&key)[n]) const
03438 {
03439 return operator[](static_cast<const T>(key));
03440 }
03441
03469 template<typename T>
03470 reference operator[](T* key)
03471 {
03472
03473 if (is_null())
03474 {
03475 m_type = value_t::object;
03476 m_value = value_t::object;
03477 }
03478
03479
03480 if (is_object())
03481 {
03482 assert(m_value.object != nullptr);
03483 return m_value.object->operator[](key);
03484 }
03485 else
03486 {
03487 throw std::domain_error("cannot use operator[] with " + type_name());
03488 }
03489 }
03490
03518 template<typename T>
03519 const_reference operator[](T* key) const
03520 {
03521
03522 if (is_object())
03523 {
03524 assert(m_value.object != nullptr);
03525 assert(m_value.object->find(key) != m_value.object->end());
03526 return m_value.object->find(key)->second;
03527 }
03528 else
03529 {
03530 throw std::domain_error("cannot use operator[] with " + type_name());
03531 }
03532 }
03533
03582 template <class ValueType, typename
03583 std::enable_if<
03584 std::is_convertible<basic_json_t, ValueType>::value
03585 , int>::type = 0>
03586 ValueType value(const typename object_t::key_type& key, ValueType default_value) const
03587 {
03588
03589 if (is_object())
03590 {
03591
03592 const auto it = find(key);
03593 if (it != end())
03594 {
03595 return *it;
03596 }
03597 else
03598 {
03599 return default_value;
03600 }
03601 }
03602 else
03603 {
03604 throw std::domain_error("cannot use value() with " + type_name());
03605 }
03606 }
03607
03612 string_t value(const typename object_t::key_type& key, const char* default_value) const
03613 {
03614 return value(key, string_t(default_value));
03615 }
03616
03641 reference front()
03642 {
03643 return *begin();
03644 }
03645
03649 const_reference front() const
03650 {
03651 return *cbegin();
03652 }
03653
03683 reference back()
03684 {
03685 auto tmp = end();
03686 --tmp;
03687 return *tmp;
03688 }
03689
03693 const_reference back() const
03694 {
03695 auto tmp = cend();
03696 --tmp;
03697 return *tmp;
03698 }
03699
03745 template <class InteratorType, typename
03746 std::enable_if<
03747 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
03748 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
03749 , int>::type
03750 = 0>
03751 InteratorType erase(InteratorType pos)
03752 {
03753
03754 if (this != pos.m_object)
03755 {
03756 throw std::domain_error("iterator does not fit current value");
03757 }
03758
03759 InteratorType result = end();
03760
03761 switch (m_type)
03762 {
03763 case value_t::boolean:
03764 case value_t::number_float:
03765 case value_t::number_integer:
03766 case value_t::number_unsigned:
03767 case value_t::string:
03768 {
03769 if (not pos.m_it.primitive_iterator.is_begin())
03770 {
03771 throw std::out_of_range("iterator out of range");
03772 }
03773
03774 if (is_string())
03775 {
03776 delete m_value.string;
03777 m_value.string = nullptr;
03778 }
03779
03780 m_type = value_t::null;
03781 break;
03782 }
03783
03784 case value_t::object:
03785 {
03786 assert(m_value.object != nullptr);
03787 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
03788 break;
03789 }
03790
03791 case value_t::array:
03792 {
03793 assert(m_value.array != nullptr);
03794 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
03795 break;
03796 }
03797
03798 default:
03799 {
03800 throw std::domain_error("cannot use erase() with " + type_name());
03801 }
03802 }
03803
03804 return result;
03805 }
03806
03853 template <class InteratorType, typename
03854 std::enable_if<
03855 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
03856 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
03857 , int>::type
03858 = 0>
03859 InteratorType erase(InteratorType first, InteratorType last)
03860 {
03861
03862 if (this != first.m_object or this != last.m_object)
03863 {
03864 throw std::domain_error("iterators do not fit current value");
03865 }
03866
03867 InteratorType result = end();
03868
03869 switch (m_type)
03870 {
03871 case value_t::boolean:
03872 case value_t::number_float:
03873 case value_t::number_integer:
03874 case value_t::number_unsigned:
03875 case value_t::string:
03876 {
03877 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
03878 {
03879 throw std::out_of_range("iterators out of range");
03880 }
03881
03882 if (is_string())
03883 {
03884 delete m_value.string;
03885 m_value.string = nullptr;
03886 }
03887
03888 m_type = value_t::null;
03889 break;
03890 }
03891
03892 case value_t::object:
03893 {
03894 assert(m_value.object != nullptr);
03895 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
03896 last.m_it.object_iterator);
03897 break;
03898 }
03899
03900 case value_t::array:
03901 {
03902 assert(m_value.array != nullptr);
03903 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
03904 last.m_it.array_iterator);
03905 break;
03906 }
03907
03908 default:
03909 {
03910 throw std::domain_error("cannot use erase() with " + type_name());
03911 }
03912 }
03913
03914 return result;
03915 }
03916
03946 size_type erase(const typename object_t::key_type& key)
03947 {
03948
03949 if (is_object())
03950 {
03951 assert(m_value.object != nullptr);
03952 return m_value.object->erase(key);
03953 }
03954 else
03955 {
03956 throw std::domain_error("cannot use erase() with " + type_name());
03957 }
03958 }
03959
03984 void erase(const size_type idx)
03985 {
03986
03987 if (is_array())
03988 {
03989 if (idx >= size())
03990 {
03991 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
03992 }
03993
03994 assert(m_value.array != nullptr);
03995 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
03996 }
03997 else
03998 {
03999 throw std::domain_error("cannot use erase() with " + type_name());
04000 }
04001 }
04002
04004
04005
04007
04009
04012
04031 iterator find(typename object_t::key_type key)
04032 {
04033 auto result = end();
04034
04035 if (is_object())
04036 {
04037 assert(m_value.object != nullptr);
04038 result.m_it.object_iterator = m_value.object->find(key);
04039 }
04040
04041 return result;
04042 }
04043
04048 const_iterator find(typename object_t::key_type key) const
04049 {
04050 auto result = cend();
04051
04052 if (is_object())
04053 {
04054 assert(m_value.object != nullptr);
04055 result.m_it.object_iterator = m_value.object->find(key);
04056 }
04057
04058 return result;
04059 }
04060
04079 size_type count(typename object_t::key_type key) const
04080 {
04081
04082 assert(not is_object() or m_value.object != nullptr);
04083 return is_object() ? m_value.object->count(key) : 0;
04084 }
04085
04087
04088
04090
04092
04095
04120 iterator begin() noexcept
04121 {
04122 iterator result(this);
04123 result.set_begin();
04124 return result;
04125 }
04126
04130 const_iterator begin() const noexcept
04131 {
04132 return cbegin();
04133 }
04134
04160 const_iterator cbegin() const noexcept
04161 {
04162 const_iterator result(this);
04163 result.set_begin();
04164 return result;
04165 }
04166
04191 iterator end() noexcept
04192 {
04193 iterator result(this);
04194 result.set_end();
04195 return result;
04196 }
04197
04201 const_iterator end() const noexcept
04202 {
04203 return cend();
04204 }
04205
04231 const_iterator cend() const noexcept
04232 {
04233 const_iterator result(this);
04234 result.set_end();
04235 return result;
04236 }
04237
04261 reverse_iterator rbegin() noexcept
04262 {
04263 return reverse_iterator(end());
04264 }
04265
04269 const_reverse_iterator rbegin() const noexcept
04270 {
04271 return crbegin();
04272 }
04273
04298 reverse_iterator rend() noexcept
04299 {
04300 return reverse_iterator(begin());
04301 }
04302
04306 const_reverse_iterator rend() const noexcept
04307 {
04308 return crend();
04309 }
04310
04335 const_reverse_iterator crbegin() const noexcept
04336 {
04337 return const_reverse_iterator(cend());
04338 }
04339
04364 const_reverse_iterator crend() const noexcept
04365 {
04366 return const_reverse_iterator(cbegin());
04367 }
04368
04369 private:
04370
04371 template<typename IteratorType> class iteration_proxy;
04372
04373 public:
04385 static iteration_proxy<iterator> iterator_wrapper(reference cont)
04386 {
04387 return iteration_proxy<iterator>(cont);
04388 }
04389
04393 static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
04394 {
04395 return iteration_proxy<const_iterator>(cont);
04396 }
04397
04399
04400
04402
04404
04407
04441 bool empty() const noexcept
04442 {
04443 switch (m_type)
04444 {
04445 case value_t::null:
04446 {
04447
04448 return true;
04449 }
04450
04451 case value_t::array:
04452 {
04453 assert(m_value.array != nullptr);
04454 return m_value.array->empty();
04455 }
04456
04457 case value_t::object:
04458 {
04459 assert(m_value.object != nullptr);
04460 return m_value.object->empty();
04461 }
04462
04463 default:
04464 {
04465
04466 return false;
04467 }
04468 }
04469 }
04470
04505 size_type size() const noexcept
04506 {
04507 switch (m_type)
04508 {
04509 case value_t::null:
04510 {
04511
04512 return 0;
04513 }
04514
04515 case value_t::array:
04516 {
04517 assert(m_value.array != nullptr);
04518 return m_value.array->size();
04519 }
04520
04521 case value_t::object:
04522 {
04523 assert(m_value.object != nullptr);
04524 return m_value.object->size();
04525 }
04526
04527 default:
04528 {
04529
04530 return 1;
04531 }
04532 }
04533 }
04534
04571 size_type max_size() const noexcept
04572 {
04573 switch (m_type)
04574 {
04575 case value_t::array:
04576 {
04577 assert(m_value.array != nullptr);
04578 return m_value.array->max_size();
04579 }
04580
04581 case value_t::object:
04582 {
04583 assert(m_value.object != nullptr);
04584 return m_value.object->max_size();
04585 }
04586
04587 default:
04588 {
04589
04590 return size();
04591 }
04592 }
04593 }
04594
04596
04597
04599
04601
04604
04630 void clear() noexcept
04631 {
04632 switch (m_type)
04633 {
04634 case value_t::number_integer:
04635 {
04636 m_value.number_integer = 0;
04637 break;
04638 }
04639
04640 case value_t::number_unsigned:
04641 {
04642 m_value.number_unsigned = 0;
04643 break;
04644 }
04645
04646 case value_t::number_float:
04647 {
04648 m_value.number_float = 0.0;
04649 break;
04650 }
04651
04652 case value_t::boolean:
04653 {
04654 m_value.boolean = false;
04655 break;
04656 }
04657
04658 case value_t::string:
04659 {
04660 assert(m_value.string != nullptr);
04661 m_value.string->clear();
04662 break;
04663 }
04664
04665 case value_t::array:
04666 {
04667 assert(m_value.array != nullptr);
04668 m_value.array->clear();
04669 break;
04670 }
04671
04672 case value_t::object:
04673 {
04674 assert(m_value.object != nullptr);
04675 m_value.object->clear();
04676 break;
04677 }
04678
04679 default:
04680 {
04681 break;
04682 }
04683 }
04684 }
04685
04706 void push_back(basic_json&& val)
04707 {
04708
04709 if (not(is_null() or is_array()))
04710 {
04711 throw std::domain_error("cannot use push_back() with " + type_name());
04712 }
04713
04714
04715 if (is_null())
04716 {
04717 m_type = value_t::array;
04718 m_value = value_t::array;
04719 }
04720
04721
04722 assert(m_value.array != nullptr);
04723 m_value.array->push_back(std::move(val));
04724
04725 val.m_type = value_t::null;
04726 }
04727
04732 reference operator+=(basic_json&& val)
04733 {
04734 push_back(std::move(val));
04735 return *this;
04736 }
04737
04742 void push_back(const basic_json& val)
04743 {
04744
04745 if (not(is_null() or is_array()))
04746 {
04747 throw std::domain_error("cannot use push_back() with " + type_name());
04748 }
04749
04750
04751 if (is_null())
04752 {
04753 m_type = value_t::array;
04754 m_value = value_t::array;
04755 }
04756
04757
04758 assert(m_value.array != nullptr);
04759 m_value.array->push_back(val);
04760 }
04761
04766 reference operator+=(const basic_json& val)
04767 {
04768 push_back(val);
04769 return *this;
04770 }
04771
04792 void push_back(const typename object_t::value_type& val)
04793 {
04794
04795 if (not(is_null() or is_object()))
04796 {
04797 throw std::domain_error("cannot use push_back() with " + type_name());
04798 }
04799
04800
04801 if (is_null())
04802 {
04803 m_type = value_t::object;
04804 m_value = value_t::object;
04805 }
04806
04807
04808 assert(m_value.object != nullptr);
04809 m_value.object->insert(val);
04810 }
04811
04816 reference operator+=(const typename object_t::value_type& val)
04817 {
04818 push_back(val);
04819 return *this;
04820 }
04821
04847 void push_back(std::initializer_list<basic_json> init)
04848 {
04849 if (is_object() and init.size() == 2 and init.begin()->is_string())
04850 {
04851 const string_t key = *init.begin();
04852 push_back(typename object_t::value_type(key, *(init.begin() + 1)));
04853 }
04854 else
04855 {
04856 push_back(basic_json(init));
04857 }
04858 }
04859
04864 reference operator+=(std::initializer_list<basic_json> init)
04865 {
04866 push_back(init);
04867 return *this;
04868 }
04869
04892 iterator insert(const_iterator pos, const basic_json& val)
04893 {
04894
04895 if (is_array())
04896 {
04897
04898 if (pos.m_object != this)
04899 {
04900 throw std::domain_error("iterator does not fit current value");
04901 }
04902
04903
04904 iterator result(this);
04905 assert(m_value.array != nullptr);
04906 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
04907 return result;
04908 }
04909 else
04910 {
04911 throw std::domain_error("cannot use insert() with " + type_name());
04912 }
04913 }
04914
04919 iterator insert(const_iterator pos, basic_json&& val)
04920 {
04921 return insert(pos, val);
04922 }
04923
04948 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
04949 {
04950
04951 if (is_array())
04952 {
04953
04954 if (pos.m_object != this)
04955 {
04956 throw std::domain_error("iterator does not fit current value");
04957 }
04958
04959
04960 iterator result(this);
04961 assert(m_value.array != nullptr);
04962 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
04963 return result;
04964 }
04965 else
04966 {
04967 throw std::domain_error("cannot use insert() with " + type_name());
04968 }
04969 }
04970
05001 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
05002 {
05003
05004 if (not is_array())
05005 {
05006 throw std::domain_error("cannot use insert() with " + type_name());
05007 }
05008
05009
05010 if (pos.m_object != this)
05011 {
05012 throw std::domain_error("iterator does not fit current value");
05013 }
05014
05015
05016 if (first.m_object != last.m_object)
05017 {
05018 throw std::domain_error("iterators do not fit");
05019 }
05020
05021 if (first.m_object == this or last.m_object == this)
05022 {
05023 throw std::domain_error("passed iterators may not belong to container");
05024 }
05025
05026
05027 iterator result(this);
05028 assert(m_value.array != nullptr);
05029 result.m_it.array_iterator = m_value.array->insert(
05030 pos.m_it.array_iterator,
05031 first.m_it.array_iterator,
05032 last.m_it.array_iterator);
05033 return result;
05034 }
05035
05060 iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
05061 {
05062
05063 if (not is_array())
05064 {
05065 throw std::domain_error("cannot use insert() with " + type_name());
05066 }
05067
05068
05069 if (pos.m_object != this)
05070 {
05071 throw std::domain_error("iterator does not fit current value");
05072 }
05073
05074
05075 iterator result(this);
05076 assert(m_value.array != nullptr);
05077 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
05078 return result;
05079 }
05080
05098 void swap(reference other) noexcept (
05099 std::is_nothrow_move_constructible<value_t>::value and
05100 std::is_nothrow_move_assignable<value_t>::value and
05101 std::is_nothrow_move_constructible<json_value>::value and
05102 std::is_nothrow_move_assignable<json_value>::value
05103 )
05104 {
05105 std::swap(m_type, other.m_type);
05106 std::swap(m_value, other.m_value);
05107 }
05108
05129 void swap(array_t& other)
05130 {
05131
05132 if (is_array())
05133 {
05134 assert(m_value.array != nullptr);
05135 std::swap(*(m_value.array), other);
05136 }
05137 else
05138 {
05139 throw std::domain_error("cannot use swap() with " + type_name());
05140 }
05141 }
05142
05163 void swap(object_t& other)
05164 {
05165
05166 if (is_object())
05167 {
05168 assert(m_value.object != nullptr);
05169 std::swap(*(m_value.object), other);
05170 }
05171 else
05172 {
05173 throw std::domain_error("cannot use swap() with " + type_name());
05174 }
05175 }
05176
05197 void swap(string_t& other)
05198 {
05199
05200 if (is_string())
05201 {
05202 assert(m_value.string != nullptr);
05203 std::swap(*(m_value.string), other);
05204 }
05205 else
05206 {
05207 throw std::domain_error("cannot use swap() with " + type_name());
05208 }
05209 }
05210
05212
05213
05215
05217
05220
05221 private:
05231 friend bool operator<(const value_t lhs, const value_t rhs) noexcept
05232 {
05233 static constexpr std::array<uint8_t, 8> order = {{
05234 0,
05235 3,
05236 4,
05237 5,
05238 1,
05239 2,
05240 2,
05241 2,
05242 }
05243 };
05244
05245
05246 if (lhs == value_t::discarded or rhs == value_t::discarded)
05247 {
05248 return false;
05249 }
05250
05251 return order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
05252 }
05253
05254 public:
05278 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
05279 {
05280 const auto lhs_type = lhs.type();
05281 const auto rhs_type = rhs.type();
05282
05283 if (lhs_type == rhs_type)
05284 {
05285 switch (lhs_type)
05286 {
05287 case value_t::array:
05288 {
05289 assert(lhs.m_value.array != nullptr);
05290 assert(rhs.m_value.array != nullptr);
05291 return *lhs.m_value.array == *rhs.m_value.array;
05292 }
05293 case value_t::object:
05294 {
05295 assert(lhs.m_value.object != nullptr);
05296 assert(rhs.m_value.object != nullptr);
05297 return *lhs.m_value.object == *rhs.m_value.object;
05298 }
05299 case value_t::null:
05300 {
05301 return true;
05302 }
05303 case value_t::string:
05304 {
05305 assert(lhs.m_value.string != nullptr);
05306 assert(rhs.m_value.string != nullptr);
05307 return *lhs.m_value.string == *rhs.m_value.string;
05308 }
05309 case value_t::boolean:
05310 {
05311 return lhs.m_value.boolean == rhs.m_value.boolean;
05312 }
05313 case value_t::number_integer:
05314 {
05315 return lhs.m_value.number_integer == rhs.m_value.number_integer;
05316 }
05317 case value_t::number_unsigned:
05318 {
05319 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
05320 }
05321 case value_t::number_float:
05322 {
05323 return lhs.m_value.number_float == rhs.m_value.number_float;
05324 }
05325 default:
05326 {
05327 return false;
05328 }
05329 }
05330 }
05331 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
05332 {
05333 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
05334 }
05335 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
05336 {
05337 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
05338 }
05339 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
05340 {
05341 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
05342 }
05343 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
05344 {
05345 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
05346 }
05347 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
05348 {
05349 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
05350 }
05351 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
05352 {
05353 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
05354 }
05355
05356 return false;
05357 }
05358
05377 friend bool operator==(const_reference v, std::nullptr_t) noexcept
05378 {
05379 return v.is_null();
05380 }
05381
05386 friend bool operator==(std::nullptr_t, const_reference v) noexcept
05387 {
05388 return v.is_null();
05389 }
05390
05407 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
05408 {
05409 return not (lhs == rhs);
05410 }
05411
05430 friend bool operator!=(const_reference v, std::nullptr_t) noexcept
05431 {
05432 return not v.is_null();
05433 }
05434
05439 friend bool operator!=(std::nullptr_t, const_reference v) noexcept
05440 {
05441 return not v.is_null();
05442 }
05443
05468 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
05469 {
05470 const auto lhs_type = lhs.type();
05471 const auto rhs_type = rhs.type();
05472
05473 if (lhs_type == rhs_type)
05474 {
05475 switch (lhs_type)
05476 {
05477 case value_t::array:
05478 {
05479 assert(lhs.m_value.array != nullptr);
05480 assert(rhs.m_value.array != nullptr);
05481 return *lhs.m_value.array < *rhs.m_value.array;
05482 }
05483 case value_t::object:
05484 {
05485 assert(lhs.m_value.object != nullptr);
05486 assert(rhs.m_value.object != nullptr);
05487 return *lhs.m_value.object < *rhs.m_value.object;
05488 }
05489 case value_t::null:
05490 {
05491 return false;
05492 }
05493 case value_t::string:
05494 {
05495 assert(lhs.m_value.string != nullptr);
05496 assert(rhs.m_value.string != nullptr);
05497 return *lhs.m_value.string < *rhs.m_value.string;
05498 }
05499 case value_t::boolean:
05500 {
05501 return lhs.m_value.boolean < rhs.m_value.boolean;
05502 }
05503 case value_t::number_integer:
05504 {
05505 return lhs.m_value.number_integer < rhs.m_value.number_integer;
05506 }
05507 case value_t::number_unsigned:
05508 {
05509 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
05510 }
05511 case value_t::number_float:
05512 {
05513 return lhs.m_value.number_float < rhs.m_value.number_float;
05514 }
05515 default:
05516 {
05517 return false;
05518 }
05519 }
05520 }
05521 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
05522 {
05523 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
05524 }
05525 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
05526 {
05527 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
05528 }
05529 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
05530 {
05531 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
05532 }
05533 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
05534 {
05535 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
05536 }
05537 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
05538 {
05539 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
05540 }
05541 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
05542 {
05543 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
05544 }
05545
05546
05547
05548
05549 return operator<(lhs_type, rhs_type);
05550 }
05551
05569 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
05570 {
05571 return not (rhs < lhs);
05572 }
05573
05591 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
05592 {
05593 return not (lhs <= rhs);
05594 }
05595
05613 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
05614 {
05615 return not (lhs < rhs);
05616 }
05617
05619
05620
05622
05624
05627
05650 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
05651 {
05652
05653 const bool pretty_print = (o.width() > 0);
05654 const auto indentation = (pretty_print ? o.width() : 0);
05655
05656
05657 o.width(0);
05658
05659
05660 j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
05661 return o;
05662 }
05663
05668 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
05669 {
05670 return o << j;
05671 }
05672
05674
05675
05677
05679
05682
05707 static basic_json parse(const string_t& s, parser_callback_t cb = nullptr)
05708 {
05709 return parser(s, cb).parse();
05710 }
05711
05736 static basic_json parse(std::istream& i, parser_callback_t cb = nullptr)
05737 {
05738 return parser(i, cb).parse();
05739 }
05740
05744 static basic_json parse(std::istream&& i, parser_callback_t cb = nullptr)
05745 {
05746 return parser(i, cb).parse();
05747 }
05748
05772 friend std::istream& operator<<(basic_json& j, std::istream& i)
05773 {
05774 j = parser(i).parse();
05775 return i;
05776 }
05777
05782 friend std::istream& operator>>(std::istream& i, basic_json& j)
05783 {
05784 j = parser(i).parse();
05785 return i;
05786 }
05787
05789
05790
05791 private:
05793
05795
05797 string_t type_name() const noexcept
05798 {
05799 switch (m_type)
05800 {
05801 case value_t::null:
05802 return "null";
05803 case value_t::object:
05804 return "object";
05805 case value_t::array:
05806 return "array";
05807 case value_t::string:
05808 return "string";
05809 case value_t::boolean:
05810 return "boolean";
05811 case value_t::discarded:
05812 return "discarded";
05813 default:
05814 return "number";
05815 }
05816 }
05817
05826 static std::size_t extra_space(const string_t& s) noexcept
05827 {
05828 std::size_t result = 0;
05829
05830 for (const auto& c : s)
05831 {
05832 switch (c)
05833 {
05834 case '"':
05835 case '\\':
05836 case '\b':
05837 case '\f':
05838 case '\n':
05839 case '\r':
05840 case '\t':
05841 {
05842
05843 result += 1;
05844 break;
05845 }
05846
05847 default:
05848 {
05849 if (c >= 0x00 and c <= 0x1f)
05850 {
05851
05852 result += 5;
05853 }
05854 break;
05855 }
05856 }
05857 }
05858
05859 return result;
05860 }
05861
05875 static string_t escape_string(const string_t& s)
05876 {
05877 const auto space = extra_space(s);
05878 if (space == 0)
05879 {
05880 return s;
05881 }
05882
05883
05884 string_t result(s.size() + space, '\\');
05885 std::size_t pos = 0;
05886
05887 for (const auto& c : s)
05888 {
05889 switch (c)
05890 {
05891
05892 case '"':
05893 {
05894 result[pos + 1] = '"';
05895 pos += 2;
05896 break;
05897 }
05898
05899
05900 case '\\':
05901 {
05902
05903 pos += 2;
05904 break;
05905 }
05906
05907
05908 case '\b':
05909 {
05910 result[pos + 1] = 'b';
05911 pos += 2;
05912 break;
05913 }
05914
05915
05916 case '\f':
05917 {
05918 result[pos + 1] = 'f';
05919 pos += 2;
05920 break;
05921 }
05922
05923
05924 case '\n':
05925 {
05926 result[pos + 1] = 'n';
05927 pos += 2;
05928 break;
05929 }
05930
05931
05932 case '\r':
05933 {
05934 result[pos + 1] = 'r';
05935 pos += 2;
05936 break;
05937 }
05938
05939
05940 case '\t':
05941 {
05942 result[pos + 1] = 't';
05943 pos += 2;
05944 break;
05945 }
05946
05947 default:
05948 {
05949 if (c >= 0x00 and c <= 0x1f)
05950 {
05951
05952
05953 const auto hexify = [](const int v) -> char
05954 {
05955 return (v < 10)
05956 ? ('0' + static_cast<char>(v))
05957 : ('a' + static_cast<char>((v - 10) & 0x1f));
05958 };
05959
05960
05961 for (const char m :
05962 { 'u', '0', '0', hexify(c >> 4), hexify(c & 0x0f)
05963 })
05964 {
05965 result[++pos] = m;
05966 }
05967
05968 ++pos;
05969 }
05970 else
05971 {
05972
05973 result[pos++] = c;
05974 }
05975 break;
05976 }
05977 }
05978 }
05979
05980 return result;
05981 }
05982
06000 void dump(std::ostream& o,
06001 const bool pretty_print,
06002 const unsigned int indent_step,
06003 const unsigned int current_indent = 0) const
06004 {
06005
06006 unsigned int new_indent = current_indent;
06007
06008 switch (m_type)
06009 {
06010 case value_t::object:
06011 {
06012 assert(m_value.object != nullptr);
06013
06014 if (m_value.object->empty())
06015 {
06016 o << "{}";
06017 return;
06018 }
06019
06020 o << "{";
06021
06022
06023 if (pretty_print)
06024 {
06025 new_indent += indent_step;
06026 o << "\n";
06027 }
06028
06029 for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
06030 {
06031 if (i != m_value.object->cbegin())
06032 {
06033 o << (pretty_print ? ",\n" : ",");
06034 }
06035 o << string_t(new_indent, ' ') << "\""
06036 << escape_string(i->first) << "\":"
06037 << (pretty_print ? " " : "");
06038 i->second.dump(o, pretty_print, indent_step, new_indent);
06039 }
06040
06041
06042 if (pretty_print)
06043 {
06044 new_indent -= indent_step;
06045 o << "\n";
06046 }
06047
06048 o << string_t(new_indent, ' ') + "}";
06049 return;
06050 }
06051
06052 case value_t::array:
06053 {
06054 assert(m_value.array != nullptr);
06055
06056 if (m_value.array->empty())
06057 {
06058 o << "[]";
06059 return;
06060 }
06061
06062 o << "[";
06063
06064
06065 if (pretty_print)
06066 {
06067 new_indent += indent_step;
06068 o << "\n";
06069 }
06070
06071 for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
06072 {
06073 if (i != m_value.array->cbegin())
06074 {
06075 o << (pretty_print ? ",\n" : ",");
06076 }
06077 o << string_t(new_indent, ' ');
06078 i->dump(o, pretty_print, indent_step, new_indent);
06079 }
06080
06081
06082 if (pretty_print)
06083 {
06084 new_indent -= indent_step;
06085 o << "\n";
06086 }
06087
06088 o << string_t(new_indent, ' ') << "]";
06089 return;
06090 }
06091
06092 case value_t::string:
06093 {
06094 assert(m_value.string != nullptr);
06095 o << string_t("\"") << escape_string(*m_value.string) << "\"";
06096 return;
06097 }
06098
06099 case value_t::boolean:
06100 {
06101 o << (m_value.boolean ? "true" : "false");
06102 return;
06103 }
06104
06105 case value_t::number_integer:
06106 {
06107 o << m_value.number_integer;
06108 return;
06109 }
06110
06111 case value_t::number_unsigned:
06112 {
06113 o << m_value.number_unsigned;
06114 return;
06115 }
06116
06117 case value_t::number_float:
06118 {
06119 if (m_value.number_float == 0)
06120 {
06121
06122 o << (std::signbit(m_value.number_float) ? "-0.0" : "0.0");
06123 }
06124 else
06125 {
06126
06127
06128
06129
06130
06131 std::stringstream ss;
06132 ss.imbue(std::locale(std::locale(), new DecimalSeparator));
06133 ss << std::setprecision(std::numeric_limits<double>::digits10)
06134 << m_value.number_float;
06135 o << ss.str();
06136 }
06137 return;
06138 }
06139
06140 case value_t::discarded:
06141 {
06142 o << "<discarded>";
06143 return;
06144 }
06145
06146 case value_t::null:
06147 {
06148 o << "null";
06149 return;
06150 }
06151 }
06152 }
06153
06154 private:
06156
06158
06160 value_t m_type = value_t::null;
06161
06163 json_value m_value = {};
06164
06165
06166 private:
06168
06170
06180 class primitive_iterator_t
06181 {
06182 public:
06184 void set_begin() noexcept
06185 {
06186 m_it = begin_value;
06187 }
06188
06190 void set_end() noexcept
06191 {
06192 m_it = end_value;
06193 }
06194
06196 constexpr bool is_begin() const noexcept
06197 {
06198 return (m_it == begin_value);
06199 }
06200
06202 constexpr bool is_end() const noexcept
06203 {
06204 return (m_it == end_value);
06205 }
06206
06208 operator difference_type& () noexcept
06209 {
06210 return m_it;
06211 }
06212
06214 constexpr operator difference_type () const noexcept
06215 {
06216 return m_it;
06217 }
06218
06219 private:
06220 static constexpr difference_type begin_value = 0;
06221 static constexpr difference_type end_value = begin_value + 1;
06222
06224 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
06225 };
06226
06234 struct internal_iterator
06235 {
06237 typename object_t::iterator object_iterator;
06239 typename array_t::iterator array_iterator;
06241 primitive_iterator_t primitive_iterator;
06242
06244 internal_iterator() noexcept
06245 : object_iterator(), array_iterator(), primitive_iterator()
06246 {}
06247 };
06248
06250 template<typename IteratorType>
06251 class iteration_proxy
06252 {
06253 private:
06255 class iteration_proxy_internal
06256 {
06257 private:
06259 IteratorType anchor;
06261 size_t array_index = 0;
06262
06263 public:
06264 explicit iteration_proxy_internal(IteratorType it) noexcept
06265 : anchor(it)
06266 {}
06267
06269 iteration_proxy_internal& operator*()
06270 {
06271 return *this;
06272 }
06273
06275 iteration_proxy_internal& operator++()
06276 {
06277 ++anchor;
06278 ++array_index;
06279
06280 return *this;
06281 }
06282
06284 bool operator!= (const iteration_proxy_internal& o) const
06285 {
06286 return anchor != o.anchor;
06287 }
06288
06290 typename basic_json::string_t key() const
06291 {
06292 assert(anchor.m_object != nullptr);
06293
06294 switch (anchor.m_object->type())
06295 {
06296
06297 case value_t::array:
06298 {
06299 return std::to_string(array_index);
06300 }
06301
06302
06303 case value_t::object:
06304 {
06305 return anchor.key();
06306 }
06307
06308
06309 default:
06310 {
06311 return "";
06312 }
06313 }
06314 }
06315
06317 typename IteratorType::reference value() const
06318 {
06319 return anchor.value();
06320 }
06321 };
06322
06324 typename IteratorType::reference container;
06325
06326 public:
06328 explicit iteration_proxy(typename IteratorType::reference cont)
06329 : container(cont)
06330 {}
06331
06333 iteration_proxy_internal begin() noexcept
06334 {
06335 return iteration_proxy_internal(container.begin());
06336 }
06337
06339 iteration_proxy_internal end() noexcept
06340 {
06341 return iteration_proxy_internal(container.end());
06342 }
06343 };
06344
06345 public:
06359 class const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
06360 {
06362 friend class basic_json;
06363
06364 public:
06366 using value_type = typename basic_json::value_type;
06368 using difference_type = typename basic_json::difference_type;
06370 using pointer = typename basic_json::const_pointer;
06372 using reference = typename basic_json::const_reference;
06374 using iterator_category = std::bidirectional_iterator_tag;
06375
06377 const_iterator() = default;
06378
06380 explicit const_iterator(pointer object) noexcept
06381 : m_object(object)
06382 {
06383 assert(m_object != nullptr);
06384
06385 switch (m_object->m_type)
06386 {
06387 case basic_json::value_t::object:
06388 {
06389 m_it.object_iterator = typename object_t::iterator();
06390 break;
06391 }
06392
06393 case basic_json::value_t::array:
06394 {
06395 m_it.array_iterator = typename array_t::iterator();
06396 break;
06397 }
06398
06399 default:
06400 {
06401 m_it.primitive_iterator = primitive_iterator_t();
06402 break;
06403 }
06404 }
06405 }
06406
06408 explicit const_iterator(const iterator& other) noexcept
06409 : m_object(other.m_object)
06410 {
06411 assert(m_object != nullptr);
06412
06413 switch (m_object->m_type)
06414 {
06415 case basic_json::value_t::object:
06416 {
06417 m_it.object_iterator = other.m_it.object_iterator;
06418 break;
06419 }
06420
06421 case basic_json::value_t::array:
06422 {
06423 m_it.array_iterator = other.m_it.array_iterator;
06424 break;
06425 }
06426
06427 default:
06428 {
06429 m_it.primitive_iterator = other.m_it.primitive_iterator;
06430 break;
06431 }
06432 }
06433 }
06434
06436 const_iterator(const const_iterator& other) noexcept
06437 : m_object(other.m_object), m_it(other.m_it)
06438 {}
06439
06441 const_iterator& operator=(const_iterator other) noexcept(
06442 std::is_nothrow_move_constructible<pointer>::value and
06443 std::is_nothrow_move_assignable<pointer>::value and
06444 std::is_nothrow_move_constructible<internal_iterator>::value and
06445 std::is_nothrow_move_assignable<internal_iterator>::value
06446 )
06447 {
06448 std::swap(m_object, other.m_object);
06449 std::swap(m_it, other.m_it);
06450 return *this;
06451 }
06452
06453 private:
06455 void set_begin() noexcept
06456 {
06457 assert(m_object != nullptr);
06458
06459 switch (m_object->m_type)
06460 {
06461 case basic_json::value_t::object:
06462 {
06463 assert(m_object->m_value.object != nullptr);
06464 m_it.object_iterator = m_object->m_value.object->begin();
06465 break;
06466 }
06467
06468 case basic_json::value_t::array:
06469 {
06470 assert(m_object->m_value.array != nullptr);
06471 m_it.array_iterator = m_object->m_value.array->begin();
06472 break;
06473 }
06474
06475 case basic_json::value_t::null:
06476 {
06477
06478 m_it.primitive_iterator.set_end();
06479 break;
06480 }
06481
06482 default:
06483 {
06484 m_it.primitive_iterator.set_begin();
06485 break;
06486 }
06487 }
06488 }
06489
06491 void set_end() noexcept
06492 {
06493 assert(m_object != nullptr);
06494
06495 switch (m_object->m_type)
06496 {
06497 case basic_json::value_t::object:
06498 {
06499 assert(m_object->m_value.object != nullptr);
06500 m_it.object_iterator = m_object->m_value.object->end();
06501 break;
06502 }
06503
06504 case basic_json::value_t::array:
06505 {
06506 assert(m_object->m_value.array != nullptr);
06507 m_it.array_iterator = m_object->m_value.array->end();
06508 break;
06509 }
06510
06511 default:
06512 {
06513 m_it.primitive_iterator.set_end();
06514 break;
06515 }
06516 }
06517 }
06518
06519 public:
06521 reference operator*() const
06522 {
06523 assert(m_object != nullptr);
06524
06525 switch (m_object->m_type)
06526 {
06527 case basic_json::value_t::object:
06528 {
06529 assert(m_object->m_value.object);
06530 assert(m_it.object_iterator != m_object->m_value.object->end());
06531 return m_it.object_iterator->second;
06532 }
06533
06534 case basic_json::value_t::array:
06535 {
06536 assert(m_object->m_value.array);
06537 assert(m_it.array_iterator != m_object->m_value.array->end());
06538 return *m_it.array_iterator;
06539 }
06540
06541 case basic_json::value_t::null:
06542 {
06543 throw std::out_of_range("cannot get value");
06544 }
06545
06546 default:
06547 {
06548 if (m_it.primitive_iterator.is_begin())
06549 {
06550 return *m_object;
06551 }
06552 else
06553 {
06554 throw std::out_of_range("cannot get value");
06555 }
06556 }
06557 }
06558 }
06559
06561 pointer operator->() const
06562 {
06563 assert(m_object != nullptr);
06564
06565 switch (m_object->m_type)
06566 {
06567 case basic_json::value_t::object:
06568 {
06569 assert(m_object->m_value.object);
06570 assert(m_it.object_iterator != m_object->m_value.object->end());
06571 return &(m_it.object_iterator->second);
06572 }
06573
06574 case basic_json::value_t::array:
06575 {
06576 assert(m_object->m_value.array);
06577 assert(m_it.array_iterator != m_object->m_value.array->end());
06578 return &*m_it.array_iterator;
06579 }
06580
06581 default:
06582 {
06583 if (m_it.primitive_iterator.is_begin())
06584 {
06585 return m_object;
06586 }
06587 else
06588 {
06589 throw std::out_of_range("cannot get value");
06590 }
06591 }
06592 }
06593 }
06594
06596 const_iterator operator++(int)
06597 {
06598 auto result = *this;
06599 ++(*this);
06600 return result;
06601 }
06602
06604 const_iterator& operator++()
06605 {
06606 assert(m_object != nullptr);
06607
06608 switch (m_object->m_type)
06609 {
06610 case basic_json::value_t::object:
06611 {
06612 ++m_it.object_iterator;
06613 break;
06614 }
06615
06616 case basic_json::value_t::array:
06617 {
06618 ++m_it.array_iterator;
06619 break;
06620 }
06621
06622 default:
06623 {
06624 ++m_it.primitive_iterator;
06625 break;
06626 }
06627 }
06628
06629 return *this;
06630 }
06631
06633 const_iterator operator--(int)
06634 {
06635 auto result = *this;
06636 --(*this);
06637 return result;
06638 }
06639
06641 const_iterator& operator--()
06642 {
06643 assert(m_object != nullptr);
06644
06645 switch (m_object->m_type)
06646 {
06647 case basic_json::value_t::object:
06648 {
06649 --m_it.object_iterator;
06650 break;
06651 }
06652
06653 case basic_json::value_t::array:
06654 {
06655 --m_it.array_iterator;
06656 break;
06657 }
06658
06659 default:
06660 {
06661 --m_it.primitive_iterator;
06662 break;
06663 }
06664 }
06665
06666 return *this;
06667 }
06668
06670 bool operator==(const const_iterator& other) const
06671 {
06672
06673 if (m_object != other.m_object)
06674 {
06675 throw std::domain_error("cannot compare iterators of different containers");
06676 }
06677
06678 assert(m_object != nullptr);
06679
06680 switch (m_object->m_type)
06681 {
06682 case basic_json::value_t::object:
06683 {
06684 return (m_it.object_iterator == other.m_it.object_iterator);
06685 }
06686
06687 case basic_json::value_t::array:
06688 {
06689 return (m_it.array_iterator == other.m_it.array_iterator);
06690 }
06691
06692 default:
06693 {
06694 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
06695 }
06696 }
06697 }
06698
06700 bool operator!=(const const_iterator& other) const
06701 {
06702 return not operator==(other);
06703 }
06704
06706 bool operator<(const const_iterator& other) const
06707 {
06708
06709 if (m_object != other.m_object)
06710 {
06711 throw std::domain_error("cannot compare iterators of different containers");
06712 }
06713
06714 assert(m_object != nullptr);
06715
06716 switch (m_object->m_type)
06717 {
06718 case basic_json::value_t::object:
06719 {
06720 throw std::domain_error("cannot compare order of object iterators");
06721 }
06722
06723 case basic_json::value_t::array:
06724 {
06725 return (m_it.array_iterator < other.m_it.array_iterator);
06726 }
06727
06728 default:
06729 {
06730 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
06731 }
06732 }
06733 }
06734
06736 bool operator<=(const const_iterator& other) const
06737 {
06738 return not other.operator < (*this);
06739 }
06740
06742 bool operator>(const const_iterator& other) const
06743 {
06744 return not operator<=(other);
06745 }
06746
06748 bool operator>=(const const_iterator& other) const
06749 {
06750 return not operator<(other);
06751 }
06752
06754 const_iterator& operator+=(difference_type i)
06755 {
06756 assert(m_object != nullptr);
06757
06758 switch (m_object->m_type)
06759 {
06760 case basic_json::value_t::object:
06761 {
06762 throw std::domain_error("cannot use offsets with object iterators");
06763 }
06764
06765 case basic_json::value_t::array:
06766 {
06767 m_it.array_iterator += i;
06768 break;
06769 }
06770
06771 default:
06772 {
06773 m_it.primitive_iterator += i;
06774 break;
06775 }
06776 }
06777
06778 return *this;
06779 }
06780
06782 const_iterator& operator-=(difference_type i)
06783 {
06784 return operator+=(-i);
06785 }
06786
06788 const_iterator operator+(difference_type i)
06789 {
06790 auto result = *this;
06791 result += i;
06792 return result;
06793 }
06794
06796 const_iterator operator-(difference_type i)
06797 {
06798 auto result = *this;
06799 result -= i;
06800 return result;
06801 }
06802
06804 difference_type operator-(const const_iterator& other) const
06805 {
06806 assert(m_object != nullptr);
06807
06808 switch (m_object->m_type)
06809 {
06810 case basic_json::value_t::object:
06811 {
06812 throw std::domain_error("cannot use offsets with object iterators");
06813 }
06814
06815 case basic_json::value_t::array:
06816 {
06817 return m_it.array_iterator - other.m_it.array_iterator;
06818 }
06819
06820 default:
06821 {
06822 return m_it.primitive_iterator - other.m_it.primitive_iterator;
06823 }
06824 }
06825 }
06826
06828 reference operator[](difference_type n) const
06829 {
06830 assert(m_object != nullptr);
06831
06832 switch (m_object->m_type)
06833 {
06834 case basic_json::value_t::object:
06835 {
06836 throw std::domain_error("cannot use operator[] for object iterators");
06837 }
06838
06839 case basic_json::value_t::array:
06840 {
06841 return *(m_it.array_iterator + n);
06842 }
06843
06844 case basic_json::value_t::null:
06845 {
06846 throw std::out_of_range("cannot get value");
06847 }
06848
06849 default:
06850 {
06851 if (m_it.primitive_iterator == -n)
06852 {
06853 return *m_object;
06854 }
06855 else
06856 {
06857 throw std::out_of_range("cannot get value");
06858 }
06859 }
06860 }
06861 }
06862
06864 typename object_t::key_type key() const
06865 {
06866 assert(m_object != nullptr);
06867
06868 if (m_object->is_object())
06869 {
06870 return m_it.object_iterator->first;
06871 }
06872 else
06873 {
06874 throw std::domain_error("cannot use key() for non-object iterators");
06875 }
06876 }
06877
06879 reference value() const
06880 {
06881 return operator*();
06882 }
06883
06884 private:
06886 pointer m_object = nullptr;
06888 internal_iterator m_it = internal_iterator();
06889 };
06890
06903 class iterator : public const_iterator
06904 {
06905 public:
06906 using base_iterator = const_iterator;
06907 using pointer = typename basic_json::pointer;
06908 using reference = typename basic_json::reference;
06909
06911 iterator() = default;
06912
06914 explicit iterator(pointer object) noexcept
06915 : base_iterator(object)
06916 {}
06917
06919 iterator(const iterator& other) noexcept
06920 : base_iterator(other)
06921 {}
06922
06924 iterator& operator=(iterator other) noexcept(
06925 std::is_nothrow_move_constructible<pointer>::value and
06926 std::is_nothrow_move_assignable<pointer>::value and
06927 std::is_nothrow_move_constructible<internal_iterator>::value and
06928 std::is_nothrow_move_assignable<internal_iterator>::value
06929 )
06930 {
06931 base_iterator::operator=(other);
06932 return *this;
06933 }
06934
06936 reference operator*() const
06937 {
06938 return const_cast<reference>(base_iterator::operator*());
06939 }
06940
06942 pointer operator->() const
06943 {
06944 return const_cast<pointer>(base_iterator::operator->());
06945 }
06946
06948 iterator operator++(int)
06949 {
06950 iterator result = *this;
06951 base_iterator::operator++();
06952 return result;
06953 }
06954
06956 iterator& operator++()
06957 {
06958 base_iterator::operator++();
06959 return *this;
06960 }
06961
06963 iterator operator--(int)
06964 {
06965 iterator result = *this;
06966 base_iterator::operator--();
06967 return result;
06968 }
06969
06971 iterator& operator--()
06972 {
06973 base_iterator::operator--();
06974 return *this;
06975 }
06976
06978 iterator& operator+=(difference_type i)
06979 {
06980 base_iterator::operator+=(i);
06981 return *this;
06982 }
06983
06985 iterator& operator-=(difference_type i)
06986 {
06987 base_iterator::operator-=(i);
06988 return *this;
06989 }
06990
06992 iterator operator+(difference_type i)
06993 {
06994 auto result = *this;
06995 result += i;
06996 return result;
06997 }
06998
07000 iterator operator-(difference_type i)
07001 {
07002 auto result = *this;
07003 result -= i;
07004 return result;
07005 }
07006
07008 difference_type operator-(const iterator& other) const
07009 {
07010 return base_iterator::operator-(other);
07011 }
07012
07014 reference operator[](difference_type n) const
07015 {
07016 return const_cast<reference>(base_iterator::operator[](n));
07017 }
07018
07020 reference value() const
07021 {
07022 return const_cast<reference>(base_iterator::value());
07023 }
07024 };
07025
07043 template<typename Base>
07044 class json_reverse_iterator : public std::reverse_iterator<Base>
07045 {
07046 public:
07048 using base_iterator = std::reverse_iterator<Base>;
07050 using reference = typename Base::reference;
07051
07053 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
07054 : base_iterator(it)
07055 {}
07056
07058 json_reverse_iterator(const base_iterator& it) noexcept
07059 : base_iterator(it)
07060 {}
07061
07063 json_reverse_iterator operator++(int)
07064 {
07065 return base_iterator::operator++(1);
07066 }
07067
07069 json_reverse_iterator& operator++()
07070 {
07071 base_iterator::operator++();
07072 return *this;
07073 }
07074
07076 json_reverse_iterator operator--(int)
07077 {
07078 return base_iterator::operator--(1);
07079 }
07080
07082 json_reverse_iterator& operator--()
07083 {
07084 base_iterator::operator--();
07085 return *this;
07086 }
07087
07089 json_reverse_iterator& operator+=(difference_type i)
07090 {
07091 base_iterator::operator+=(i);
07092 return *this;
07093 }
07094
07096 json_reverse_iterator operator+(difference_type i) const
07097 {
07098 auto result = *this;
07099 result += i;
07100 return result;
07101 }
07102
07104 json_reverse_iterator operator-(difference_type i) const
07105 {
07106 auto result = *this;
07107 result -= i;
07108 return result;
07109 }
07110
07112 difference_type operator-(const json_reverse_iterator& other) const
07113 {
07114 return this->base() - other.base();
07115 }
07116
07118 reference operator[](difference_type n) const
07119 {
07120 return *(this->operator+(n));
07121 }
07122
07124 typename object_t::key_type key() const
07125 {
07126 auto it = --this->base();
07127 return it.key();
07128 }
07129
07131 reference value() const
07132 {
07133 auto it = --this->base();
07134 return it.operator * ();
07135 }
07136 };
07137
07138
07139 private:
07141
07143
07151 class lexer
07152 {
07153 public:
07155 enum class token_type
07156 {
07157 uninitialized,
07158 literal_true,
07159 literal_false,
07160 literal_null,
07161 value_string,
07162 value_number,
07163 begin_array,
07164 begin_object,
07165 end_array,
07166 end_object,
07167 name_separator,
07168 value_separator,
07169 parse_error,
07170 end_of_input
07171 };
07172
07174 using lexer_char_t = unsigned char;
07175
07177 explicit lexer(const string_t& s) noexcept
07178 : m_stream(nullptr), m_buffer(s)
07179 {
07180 m_content = reinterpret_cast<const lexer_char_t*>(s.c_str());
07181 assert(m_content != nullptr);
07182 m_start = m_cursor = m_content;
07183 m_limit = m_content + s.size();
07184 }
07185
07187 explicit lexer(std::istream* s) noexcept
07188 : m_stream(s), m_buffer()
07189 {
07190 assert(m_stream != nullptr);
07191 getline(*m_stream, m_buffer);
07192 m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
07193 assert(m_content != nullptr);
07194 m_start = m_cursor = m_content;
07195 m_limit = m_content + m_buffer.size();
07196 }
07197
07199 lexer() = default;
07200
07201
07202 lexer(const lexer&) = delete;
07203 lexer operator=(const lexer&) = delete;
07204
07220 static string_t to_unicode(const std::size_t codepoint1,
07221 const std::size_t codepoint2 = 0)
07222 {
07223
07224 std::size_t codepoint = codepoint1;
07225
07226
07227 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
07228 {
07229
07230 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
07231 {
07232 codepoint =
07233
07234 (codepoint1 << 10)
07235
07236 + codepoint2
07237
07238
07239
07240 - 0x35FDC00;
07241 }
07242 else
07243 {
07244 throw std::invalid_argument("missing or wrong low surrogate");
07245 }
07246 }
07247
07248 string_t result;
07249
07250 if (codepoint < 0x80)
07251 {
07252
07253 result.append(1, static_cast<typename string_t::value_type>(codepoint));
07254 }
07255 else if (codepoint <= 0x7ff)
07256 {
07257
07258 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
07259 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
07260 }
07261 else if (codepoint <= 0xffff)
07262 {
07263
07264 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
07265 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
07266 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
07267 }
07268 else if (codepoint <= 0x10ffff)
07269 {
07270
07271 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
07272 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
07273 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
07274 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
07275 }
07276 else
07277 {
07278 throw std::out_of_range("code points above 0x10FFFF are invalid");
07279 }
07280
07281 return result;
07282 }
07283
07285 static std::string token_type_name(token_type t)
07286 {
07287 switch (t)
07288 {
07289 case token_type::uninitialized:
07290 return "<uninitialized>";
07291 case token_type::literal_true:
07292 return "true literal";
07293 case token_type::literal_false:
07294 return "false literal";
07295 case token_type::literal_null:
07296 return "null literal";
07297 case token_type::value_string:
07298 return "string literal";
07299 case token_type::value_number:
07300 return "number literal";
07301 case token_type::begin_array:
07302 return "'['";
07303 case token_type::begin_object:
07304 return "'{'";
07305 case token_type::end_array:
07306 return "']'";
07307 case token_type::end_object:
07308 return "'}'";
07309 case token_type::name_separator:
07310 return "':'";
07311 case token_type::value_separator:
07312 return "','";
07313 case token_type::parse_error:
07314 return "<parse error>";
07315 case token_type::end_of_input:
07316 return "end of input";
07317 default:
07318 {
07319
07320 return "unknown token";
07321 }
07322 }
07323 }
07324
07335 token_type scan() noexcept
07336 {
07337
07338 m_marker = nullptr;
07339
07340
07341 m_start = m_cursor;
07342 assert(m_start != nullptr);
07343
07344
07345 {
07346 lexer_char_t yych;
07347 unsigned int yyaccept = 0;
07348 static const unsigned char yybm[] =
07349 {
07350 0, 0, 0, 0, 0, 0, 0, 0,
07351 0, 32, 32, 0, 0, 32, 0, 0,
07352 128, 128, 128, 128, 128, 128, 128, 128,
07353 128, 128, 128, 128, 128, 128, 128, 128,
07354 160, 128, 0, 128, 128, 128, 128, 128,
07355 128, 128, 128, 128, 128, 128, 128, 128,
07356 192, 192, 192, 192, 192, 192, 192, 192,
07357 192, 192, 128, 128, 128, 128, 128, 128,
07358 128, 128, 128, 128, 128, 128, 128, 128,
07359 128, 128, 128, 128, 128, 128, 128, 128,
07360 128, 128, 128, 128, 128, 128, 128, 128,
07361 128, 128, 128, 128, 0, 128, 128, 128,
07362 128, 128, 128, 128, 128, 128, 128, 128,
07363 128, 128, 128, 128, 128, 128, 128, 128,
07364 128, 128, 128, 128, 128, 128, 128, 128,
07365 128, 128, 128, 128, 128, 128, 128, 128,
07366 128, 128, 128, 128, 128, 128, 128, 128,
07367 128, 128, 128, 128, 128, 128, 128, 128,
07368 128, 128, 128, 128, 128, 128, 128, 128,
07369 128, 128, 128, 128, 128, 128, 128, 128,
07370 128, 128, 128, 128, 128, 128, 128, 128,
07371 128, 128, 128, 128, 128, 128, 128, 128,
07372 128, 128, 128, 128, 128, 128, 128, 128,
07373 128, 128, 128, 128, 128, 128, 128, 128,
07374 128, 128, 128, 128, 128, 128, 128, 128,
07375 128, 128, 128, 128, 128, 128, 128, 128,
07376 128, 128, 128, 128, 128, 128, 128, 128,
07377 128, 128, 128, 128, 128, 128, 128, 128,
07378 128, 128, 128, 128, 128, 128, 128, 128,
07379 128, 128, 128, 128, 128, 128, 128, 128,
07380 128, 128, 128, 128, 128, 128, 128, 128,
07381 128, 128, 128, 128, 128, 128, 128, 128,
07382 };
07383 if ((m_limit - m_cursor) < 5)
07384 {
07385 yyfill();
07386 }
07387 yych = *m_cursor;
07388 if (yybm[0 + yych] & 32)
07389 {
07390 goto basic_json_parser_6;
07391 }
07392 if (yych <= '\\')
07393 {
07394 if (yych <= '-')
07395 {
07396 if (yych <= '"')
07397 {
07398 if (yych <= 0x00)
07399 {
07400 goto basic_json_parser_2;
07401 }
07402 if (yych <= '!')
07403 {
07404 goto basic_json_parser_4;
07405 }
07406 goto basic_json_parser_9;
07407 }
07408 else
07409 {
07410 if (yych <= '+')
07411 {
07412 goto basic_json_parser_4;
07413 }
07414 if (yych <= ',')
07415 {
07416 goto basic_json_parser_10;
07417 }
07418 goto basic_json_parser_12;
07419 }
07420 }
07421 else
07422 {
07423 if (yych <= '9')
07424 {
07425 if (yych <= '/')
07426 {
07427 goto basic_json_parser_4;
07428 }
07429 if (yych <= '0')
07430 {
07431 goto basic_json_parser_13;
07432 }
07433 goto basic_json_parser_15;
07434 }
07435 else
07436 {
07437 if (yych <= ':')
07438 {
07439 goto basic_json_parser_17;
07440 }
07441 if (yych == '[')
07442 {
07443 goto basic_json_parser_19;
07444 }
07445 goto basic_json_parser_4;
07446 }
07447 }
07448 }
07449 else
07450 {
07451 if (yych <= 't')
07452 {
07453 if (yych <= 'f')
07454 {
07455 if (yych <= ']')
07456 {
07457 goto basic_json_parser_21;
07458 }
07459 if (yych <= 'e')
07460 {
07461 goto basic_json_parser_4;
07462 }
07463 goto basic_json_parser_23;
07464 }
07465 else
07466 {
07467 if (yych == 'n')
07468 {
07469 goto basic_json_parser_24;
07470 }
07471 if (yych <= 's')
07472 {
07473 goto basic_json_parser_4;
07474 }
07475 goto basic_json_parser_25;
07476 }
07477 }
07478 else
07479 {
07480 if (yych <= '|')
07481 {
07482 if (yych == '{')
07483 {
07484 goto basic_json_parser_26;
07485 }
07486 goto basic_json_parser_4;
07487 }
07488 else
07489 {
07490 if (yych <= '}')
07491 {
07492 goto basic_json_parser_28;
07493 }
07494 if (yych == 0xEF)
07495 {
07496 goto basic_json_parser_30;
07497 }
07498 goto basic_json_parser_4;
07499 }
07500 }
07501 }
07502 basic_json_parser_2:
07503 ++m_cursor;
07504 {
07505 return token_type::end_of_input;
07506 }
07507 basic_json_parser_4:
07508 ++m_cursor;
07509 basic_json_parser_5:
07510 {
07511 return token_type::parse_error;
07512 }
07513 basic_json_parser_6:
07514 ++m_cursor;
07515 if (m_limit <= m_cursor)
07516 {
07517 yyfill();
07518 }
07519 yych = *m_cursor;
07520 if (yybm[0 + yych] & 32)
07521 {
07522 goto basic_json_parser_6;
07523 }
07524 {
07525 return scan();
07526 }
07527 basic_json_parser_9:
07528 yyaccept = 0;
07529 yych = *(m_marker = ++m_cursor);
07530 if (yych <= 0x0F)
07531 {
07532 goto basic_json_parser_5;
07533 }
07534 goto basic_json_parser_32;
07535 basic_json_parser_10:
07536 ++m_cursor;
07537 {
07538 return token_type::value_separator;
07539 }
07540 basic_json_parser_12:
07541 yych = *++m_cursor;
07542 if (yych <= '/')
07543 {
07544 goto basic_json_parser_5;
07545 }
07546 if (yych <= '0')
07547 {
07548 goto basic_json_parser_13;
07549 }
07550 if (yych <= '9')
07551 {
07552 goto basic_json_parser_15;
07553 }
07554 goto basic_json_parser_5;
07555 basic_json_parser_13:
07556 yyaccept = 1;
07557 yych = *(m_marker = ++m_cursor);
07558 if (yych <= 'D')
07559 {
07560 if (yych == '.')
07561 {
07562 goto basic_json_parser_37;
07563 }
07564 }
07565 else
07566 {
07567 if (yych <= 'E')
07568 {
07569 goto basic_json_parser_38;
07570 }
07571 if (yych == 'e')
07572 {
07573 goto basic_json_parser_38;
07574 }
07575 }
07576 basic_json_parser_14:
07577 {
07578 return token_type::value_number;
07579 }
07580 basic_json_parser_15:
07581 yyaccept = 1;
07582 m_marker = ++m_cursor;
07583 if ((m_limit - m_cursor) < 3)
07584 {
07585 yyfill();
07586 }
07587 yych = *m_cursor;
07588 if (yybm[0 + yych] & 64)
07589 {
07590 goto basic_json_parser_15;
07591 }
07592 if (yych <= 'D')
07593 {
07594 if (yych == '.')
07595 {
07596 goto basic_json_parser_37;
07597 }
07598 goto basic_json_parser_14;
07599 }
07600 else
07601 {
07602 if (yych <= 'E')
07603 {
07604 goto basic_json_parser_38;
07605 }
07606 if (yych == 'e')
07607 {
07608 goto basic_json_parser_38;
07609 }
07610 goto basic_json_parser_14;
07611 }
07612 basic_json_parser_17:
07613 ++m_cursor;
07614 {
07615 return token_type::name_separator;
07616 }
07617 basic_json_parser_19:
07618 ++m_cursor;
07619 {
07620 return token_type::begin_array;
07621 }
07622 basic_json_parser_21:
07623 ++m_cursor;
07624 {
07625 return token_type::end_array;
07626 }
07627 basic_json_parser_23:
07628 yyaccept = 0;
07629 yych = *(m_marker = ++m_cursor);
07630 if (yych == 'a')
07631 {
07632 goto basic_json_parser_39;
07633 }
07634 goto basic_json_parser_5;
07635 basic_json_parser_24:
07636 yyaccept = 0;
07637 yych = *(m_marker = ++m_cursor);
07638 if (yych == 'u')
07639 {
07640 goto basic_json_parser_40;
07641 }
07642 goto basic_json_parser_5;
07643 basic_json_parser_25:
07644 yyaccept = 0;
07645 yych = *(m_marker = ++m_cursor);
07646 if (yych == 'r')
07647 {
07648 goto basic_json_parser_41;
07649 }
07650 goto basic_json_parser_5;
07651 basic_json_parser_26:
07652 ++m_cursor;
07653 {
07654 return token_type::begin_object;
07655 }
07656 basic_json_parser_28:
07657 ++m_cursor;
07658 {
07659 return token_type::end_object;
07660 }
07661 basic_json_parser_30:
07662 yyaccept = 0;
07663 yych = *(m_marker = ++m_cursor);
07664 if (yych == 0xBB)
07665 {
07666 goto basic_json_parser_42;
07667 }
07668 goto basic_json_parser_5;
07669 basic_json_parser_31:
07670 ++m_cursor;
07671 if (m_limit <= m_cursor)
07672 {
07673 yyfill();
07674 }
07675 yych = *m_cursor;
07676 basic_json_parser_32:
07677 if (yybm[0 + yych] & 128)
07678 {
07679 goto basic_json_parser_31;
07680 }
07681 if (yych <= 0x0F)
07682 {
07683 goto basic_json_parser_33;
07684 }
07685 if (yych <= '"')
07686 {
07687 goto basic_json_parser_34;
07688 }
07689 goto basic_json_parser_36;
07690 basic_json_parser_33:
07691 m_cursor = m_marker;
07692 if (yyaccept == 0)
07693 {
07694 goto basic_json_parser_5;
07695 }
07696 else
07697 {
07698 goto basic_json_parser_14;
07699 }
07700 basic_json_parser_34:
07701 ++m_cursor;
07702 {
07703 return token_type::value_string;
07704 }
07705 basic_json_parser_36:
07706 ++m_cursor;
07707 if (m_limit <= m_cursor)
07708 {
07709 yyfill();
07710 }
07711 yych = *m_cursor;
07712 if (yych <= 'e')
07713 {
07714 if (yych <= '/')
07715 {
07716 if (yych == '"')
07717 {
07718 goto basic_json_parser_31;
07719 }
07720 if (yych <= '.')
07721 {
07722 goto basic_json_parser_33;
07723 }
07724 goto basic_json_parser_31;
07725 }
07726 else
07727 {
07728 if (yych <= '\\')
07729 {
07730 if (yych <= '[')
07731 {
07732 goto basic_json_parser_33;
07733 }
07734 goto basic_json_parser_31;
07735 }
07736 else
07737 {
07738 if (yych == 'b')
07739 {
07740 goto basic_json_parser_31;
07741 }
07742 goto basic_json_parser_33;
07743 }
07744 }
07745 }
07746 else
07747 {
07748 if (yych <= 'q')
07749 {
07750 if (yych <= 'f')
07751 {
07752 goto basic_json_parser_31;
07753 }
07754 if (yych == 'n')
07755 {
07756 goto basic_json_parser_31;
07757 }
07758 goto basic_json_parser_33;
07759 }
07760 else
07761 {
07762 if (yych <= 's')
07763 {
07764 if (yych <= 'r')
07765 {
07766 goto basic_json_parser_31;
07767 }
07768 goto basic_json_parser_33;
07769 }
07770 else
07771 {
07772 if (yych <= 't')
07773 {
07774 goto basic_json_parser_31;
07775 }
07776 if (yych <= 'u')
07777 {
07778 goto basic_json_parser_43;
07779 }
07780 goto basic_json_parser_33;
07781 }
07782 }
07783 }
07784 basic_json_parser_37:
07785 yych = *++m_cursor;
07786 if (yych <= '/')
07787 {
07788 goto basic_json_parser_33;
07789 }
07790 if (yych <= '9')
07791 {
07792 goto basic_json_parser_44;
07793 }
07794 goto basic_json_parser_33;
07795 basic_json_parser_38:
07796 yych = *++m_cursor;
07797 if (yych <= ',')
07798 {
07799 if (yych == '+')
07800 {
07801 goto basic_json_parser_46;
07802 }
07803 goto basic_json_parser_33;
07804 }
07805 else
07806 {
07807 if (yych <= '-')
07808 {
07809 goto basic_json_parser_46;
07810 }
07811 if (yych <= '/')
07812 {
07813 goto basic_json_parser_33;
07814 }
07815 if (yych <= '9')
07816 {
07817 goto basic_json_parser_47;
07818 }
07819 goto basic_json_parser_33;
07820 }
07821 basic_json_parser_39:
07822 yych = *++m_cursor;
07823 if (yych == 'l')
07824 {
07825 goto basic_json_parser_49;
07826 }
07827 goto basic_json_parser_33;
07828 basic_json_parser_40:
07829 yych = *++m_cursor;
07830 if (yych == 'l')
07831 {
07832 goto basic_json_parser_50;
07833 }
07834 goto basic_json_parser_33;
07835 basic_json_parser_41:
07836 yych = *++m_cursor;
07837 if (yych == 'u')
07838 {
07839 goto basic_json_parser_51;
07840 }
07841 goto basic_json_parser_33;
07842 basic_json_parser_42:
07843 yych = *++m_cursor;
07844 if (yych == 0xBF)
07845 {
07846 goto basic_json_parser_52;
07847 }
07848 goto basic_json_parser_33;
07849 basic_json_parser_43:
07850 ++m_cursor;
07851 if (m_limit <= m_cursor)
07852 {
07853 yyfill();
07854 }
07855 yych = *m_cursor;
07856 if (yych <= '@')
07857 {
07858 if (yych <= '/')
07859 {
07860 goto basic_json_parser_33;
07861 }
07862 if (yych <= '9')
07863 {
07864 goto basic_json_parser_54;
07865 }
07866 goto basic_json_parser_33;
07867 }
07868 else
07869 {
07870 if (yych <= 'F')
07871 {
07872 goto basic_json_parser_54;
07873 }
07874 if (yych <= '`')
07875 {
07876 goto basic_json_parser_33;
07877 }
07878 if (yych <= 'f')
07879 {
07880 goto basic_json_parser_54;
07881 }
07882 goto basic_json_parser_33;
07883 }
07884 basic_json_parser_44:
07885 yyaccept = 1;
07886 m_marker = ++m_cursor;
07887 if ((m_limit - m_cursor) < 3)
07888 {
07889 yyfill();
07890 }
07891 yych = *m_cursor;
07892 if (yych <= 'D')
07893 {
07894 if (yych <= '/')
07895 {
07896 goto basic_json_parser_14;
07897 }
07898 if (yych <= '9')
07899 {
07900 goto basic_json_parser_44;
07901 }
07902 goto basic_json_parser_14;
07903 }
07904 else
07905 {
07906 if (yych <= 'E')
07907 {
07908 goto basic_json_parser_38;
07909 }
07910 if (yych == 'e')
07911 {
07912 goto basic_json_parser_38;
07913 }
07914 goto basic_json_parser_14;
07915 }
07916 basic_json_parser_46:
07917 yych = *++m_cursor;
07918 if (yych <= '/')
07919 {
07920 goto basic_json_parser_33;
07921 }
07922 if (yych >= ':')
07923 {
07924 goto basic_json_parser_33;
07925 }
07926 basic_json_parser_47:
07927 ++m_cursor;
07928 if (m_limit <= m_cursor)
07929 {
07930 yyfill();
07931 }
07932 yych = *m_cursor;
07933 if (yych <= '/')
07934 {
07935 goto basic_json_parser_14;
07936 }
07937 if (yych <= '9')
07938 {
07939 goto basic_json_parser_47;
07940 }
07941 goto basic_json_parser_14;
07942 basic_json_parser_49:
07943 yych = *++m_cursor;
07944 if (yych == 's')
07945 {
07946 goto basic_json_parser_55;
07947 }
07948 goto basic_json_parser_33;
07949 basic_json_parser_50:
07950 yych = *++m_cursor;
07951 if (yych == 'l')
07952 {
07953 goto basic_json_parser_56;
07954 }
07955 goto basic_json_parser_33;
07956 basic_json_parser_51:
07957 yych = *++m_cursor;
07958 if (yych == 'e')
07959 {
07960 goto basic_json_parser_58;
07961 }
07962 goto basic_json_parser_33;
07963 basic_json_parser_52:
07964 ++m_cursor;
07965 {
07966 return scan();
07967 }
07968 basic_json_parser_54:
07969 ++m_cursor;
07970 if (m_limit <= m_cursor)
07971 {
07972 yyfill();
07973 }
07974 yych = *m_cursor;
07975 if (yych <= '@')
07976 {
07977 if (yych <= '/')
07978 {
07979 goto basic_json_parser_33;
07980 }
07981 if (yych <= '9')
07982 {
07983 goto basic_json_parser_60;
07984 }
07985 goto basic_json_parser_33;
07986 }
07987 else
07988 {
07989 if (yych <= 'F')
07990 {
07991 goto basic_json_parser_60;
07992 }
07993 if (yych <= '`')
07994 {
07995 goto basic_json_parser_33;
07996 }
07997 if (yych <= 'f')
07998 {
07999 goto basic_json_parser_60;
08000 }
08001 goto basic_json_parser_33;
08002 }
08003 basic_json_parser_55:
08004 yych = *++m_cursor;
08005 if (yych == 'e')
08006 {
08007 goto basic_json_parser_61;
08008 }
08009 goto basic_json_parser_33;
08010 basic_json_parser_56:
08011 ++m_cursor;
08012 {
08013 return token_type::literal_null;
08014 }
08015 basic_json_parser_58:
08016 ++m_cursor;
08017 {
08018 return token_type::literal_true;
08019 }
08020 basic_json_parser_60:
08021 ++m_cursor;
08022 if (m_limit <= m_cursor)
08023 {
08024 yyfill();
08025 }
08026 yych = *m_cursor;
08027 if (yych <= '@')
08028 {
08029 if (yych <= '/')
08030 {
08031 goto basic_json_parser_33;
08032 }
08033 if (yych <= '9')
08034 {
08035 goto basic_json_parser_63;
08036 }
08037 goto basic_json_parser_33;
08038 }
08039 else
08040 {
08041 if (yych <= 'F')
08042 {
08043 goto basic_json_parser_63;
08044 }
08045 if (yych <= '`')
08046 {
08047 goto basic_json_parser_33;
08048 }
08049 if (yych <= 'f')
08050 {
08051 goto basic_json_parser_63;
08052 }
08053 goto basic_json_parser_33;
08054 }
08055 basic_json_parser_61:
08056 ++m_cursor;
08057 {
08058 return token_type::literal_false;
08059 }
08060 basic_json_parser_63:
08061 ++m_cursor;
08062 if (m_limit <= m_cursor)
08063 {
08064 yyfill();
08065 }
08066 yych = *m_cursor;
08067 if (yych <= '@')
08068 {
08069 if (yych <= '/')
08070 {
08071 goto basic_json_parser_33;
08072 }
08073 if (yych <= '9')
08074 {
08075 goto basic_json_parser_31;
08076 }
08077 goto basic_json_parser_33;
08078 }
08079 else
08080 {
08081 if (yych <= 'F')
08082 {
08083 goto basic_json_parser_31;
08084 }
08085 if (yych <= '`')
08086 {
08087 goto basic_json_parser_33;
08088 }
08089 if (yych <= 'f')
08090 {
08091 goto basic_json_parser_31;
08092 }
08093 goto basic_json_parser_33;
08094 }
08095 }
08096
08097 }
08098
08100 void yyfill() noexcept
08101 {
08102 if (m_stream == nullptr or not * m_stream)
08103 {
08104 return;
08105 }
08106
08107 const auto offset_start = m_start - m_content;
08108 const auto offset_marker = m_marker - m_start;
08109 const auto offset_cursor = m_cursor - m_start;
08110
08111 m_buffer.erase(0, static_cast<size_t>(offset_start));
08112 std::string line;
08113 assert(m_stream != nullptr);
08114 std::getline(*m_stream, line);
08115 m_buffer += "\n" + line;
08116
08117 m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
08118 assert(m_content != nullptr);
08119 m_start = m_content;
08120 m_marker = m_start + offset_marker;
08121 m_cursor = m_start + offset_cursor;
08122 m_limit = m_start + m_buffer.size() - 1;
08123 }
08124
08126 string_t get_token() const
08127 {
08128 assert(m_start != nullptr);
08129 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
08130 static_cast<size_t>(m_cursor - m_start));
08131 }
08132
08155 string_t get_string() const
08156 {
08157 string_t result;
08158 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
08159
08160
08161 for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
08162 {
08163
08164 if (*i == '\\')
08165 {
08166
08167 ++i;
08168
08169 switch (*i)
08170 {
08171
08172 case 't':
08173 {
08174 result += "\t";
08175 break;
08176 }
08177 case 'b':
08178 {
08179 result += "\b";
08180 break;
08181 }
08182 case 'f':
08183 {
08184 result += "\f";
08185 break;
08186 }
08187 case 'n':
08188 {
08189 result += "\n";
08190 break;
08191 }
08192 case 'r':
08193 {
08194 result += "\r";
08195 break;
08196 }
08197 case '\\':
08198 {
08199 result += "\\";
08200 break;
08201 }
08202 case '/':
08203 {
08204 result += "/";
08205 break;
08206 }
08207 case '"':
08208 {
08209 result += "\"";
08210 break;
08211 }
08212
08213
08214 case 'u':
08215 {
08216
08217 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
08218 4).c_str(), nullptr, 16);
08219
08220
08221 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
08222 {
08223
08224 if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
08225 {
08226 throw std::invalid_argument("missing low surrogate");
08227 }
08228
08229
08230 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
08231 (i + 7), 4).c_str(), nullptr, 16);
08232 result += to_unicode(codepoint, codepoint2);
08233
08234 i += 10;
08235 }
08236 else
08237 {
08238
08239 result += to_unicode(codepoint);
08240
08241 i += 4;
08242 }
08243 break;
08244 }
08245 }
08246 }
08247 else
08248 {
08249
08250
08251 result.append(1, static_cast<typename string_t::value_type>(*i));
08252 }
08253 }
08254
08255 return result;
08256 }
08257
08278 long double str_to_float_t(long double* , char** endptr) const
08279 {
08280 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
08281 }
08282
08298 double str_to_float_t(double* , char** endptr) const
08299 {
08300 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
08301 }
08302
08318 float str_to_float_t(float* , char** endptr) const
08319 {
08320 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
08321 }
08322
08344 void get_number(basic_json& result) const
08345 {
08346 assert(m_start != nullptr);
08347
08348 const lexer::lexer_char_t* curptr = m_start;
08349
08350
08351 number_unsigned_t value = 0;
08352
08353
08354 number_unsigned_t max;
08355
08356
08357 value_t type;
08358
08359
08360 if (*curptr == '-')
08361 {
08362 type = value_t::number_integer;
08363 max = static_cast<uint64_t>((std::numeric_limits<number_integer_t>::max)()) + 1;
08364 curptr++;
08365 }
08366 else
08367 {
08368 type = value_t::number_unsigned;
08369 max = static_cast<uint64_t>((std::numeric_limits<number_unsigned_t>::max)());
08370 }
08371
08372
08373 for (; curptr < m_cursor; curptr++)
08374 {
08375
08376 if (*curptr < '0' || *curptr > '9')
08377 {
08378 if (*curptr == '.')
08379 {
08380
08381 type = value_t::number_float;
08382 continue;
08383 }
08384
08385
08386 type = value_t::number_float;
08387 break;
08388 }
08389
08390
08391 if (type != value_t::number_float)
08392 {
08393
08394 auto temp = value * 10 + *curptr - 0x30;
08395
08396
08397 if (temp < value || temp > max)
08398 {
08399
08400 type = value_t::number_float;
08401 }
08402 else
08403 {
08404
08405 value = temp;
08406 }
08407 }
08408 }
08409
08410
08411 if (type == value_t::number_unsigned)
08412 {
08413 result.m_value.number_unsigned = value;
08414 }
08415 else if (type == value_t::number_integer)
08416 {
08417 result.m_value.number_integer = -static_cast<number_integer_t>(value);
08418 }
08419 else
08420 {
08421
08422 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(nullptr), NULL);
08423 }
08424
08425
08426 result.m_type = type;
08427 }
08428
08429 private:
08431 std::istream* m_stream = nullptr;
08433 string_t m_buffer;
08435 const lexer_char_t* m_content = nullptr;
08437 const lexer_char_t* m_start = nullptr;
08439 const lexer_char_t* m_marker = nullptr;
08441 const lexer_char_t* m_cursor = nullptr;
08443 const lexer_char_t* m_limit = nullptr;
08444 };
08445
08451 class parser
08452 {
08453 public:
08455 parser(const string_t& s, parser_callback_t cb = nullptr) noexcept
08456 : callback(cb), m_lexer(s)
08457 {
08458
08459 get_token();
08460 }
08461
08463 parser(std::istream& _is, parser_callback_t cb = nullptr) noexcept
08464 : callback(cb), m_lexer(&_is)
08465 {
08466
08467 get_token();
08468 }
08469
08471 basic_json parse()
08472 {
08473 basic_json result = parse_internal(true);
08474
08475 expect(lexer::token_type::end_of_input);
08476
08477
08478
08479 return result.is_discarded() ? basic_json() : result;
08480 }
08481
08482 private:
08484 basic_json parse_internal(bool keep)
08485 {
08486 auto result = basic_json(value_t::discarded);
08487
08488 switch (last_token)
08489 {
08490 case lexer::token_type::begin_object:
08491 {
08492 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
08493 {
08494
08495 result.m_type = value_t::object;
08496 result.m_value = json_value(value_t::object);
08497 }
08498
08499
08500 get_token();
08501
08502
08503 if (last_token == lexer::token_type::end_object)
08504 {
08505 get_token();
08506 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
08507 {
08508 result = basic_json(value_t::discarded);
08509 }
08510 return result;
08511 }
08512
08513
08514 unexpect(lexer::token_type::value_separator);
08515
08516
08517 do
08518 {
08519
08520 if (last_token == lexer::token_type::value_separator)
08521 {
08522 get_token();
08523 }
08524
08525
08526 expect(lexer::token_type::value_string);
08527 const auto key = m_lexer.get_string();
08528
08529 bool keep_tag = false;
08530 if (keep)
08531 {
08532 if (callback)
08533 {
08534 basic_json k(key);
08535 keep_tag = callback(depth, parse_event_t::key, k);
08536 }
08537 else
08538 {
08539 keep_tag = true;
08540 }
08541 }
08542
08543
08544 get_token();
08545 expect(lexer::token_type::name_separator);
08546
08547
08548 get_token();
08549 auto value = parse_internal(keep);
08550 if (keep and keep_tag and not value.is_discarded())
08551 {
08552 result[key] = std::move(value);
08553 }
08554 }
08555 while (last_token == lexer::token_type::value_separator);
08556
08557
08558 expect(lexer::token_type::end_object);
08559 get_token();
08560 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
08561 {
08562 result = basic_json(value_t::discarded);
08563 }
08564
08565 return result;
08566 }
08567
08568 case lexer::token_type::begin_array:
08569 {
08570 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
08571 {
08572
08573 result.m_type = value_t::array;
08574 result.m_value = json_value(value_t::array);
08575 }
08576
08577
08578 get_token();
08579
08580
08581 if (last_token == lexer::token_type::end_array)
08582 {
08583 get_token();
08584 if (callback and not callback(--depth, parse_event_t::array_end, result))
08585 {
08586 result = basic_json(value_t::discarded);
08587 }
08588 return result;
08589 }
08590
08591
08592 unexpect(lexer::token_type::value_separator);
08593
08594
08595 do
08596 {
08597
08598 if (last_token == lexer::token_type::value_separator)
08599 {
08600 get_token();
08601 }
08602
08603
08604 auto value = parse_internal(keep);
08605 if (keep and not value.is_discarded())
08606 {
08607 result.push_back(std::move(value));
08608 }
08609 }
08610 while (last_token == lexer::token_type::value_separator);
08611
08612
08613 expect(lexer::token_type::end_array);
08614 get_token();
08615 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
08616 {
08617 result = basic_json(value_t::discarded);
08618 }
08619
08620 return result;
08621 }
08622
08623 case lexer::token_type::literal_null:
08624 {
08625 get_token();
08626 result.m_type = value_t::null;
08627 break;
08628 }
08629
08630 case lexer::token_type::value_string:
08631 {
08632 const auto s = m_lexer.get_string();
08633 get_token();
08634 result = basic_json(s);
08635 break;
08636 }
08637
08638 case lexer::token_type::literal_true:
08639 {
08640 get_token();
08641 result.m_type = value_t::boolean;
08642 result.m_value = true;
08643 break;
08644 }
08645
08646 case lexer::token_type::literal_false:
08647 {
08648 get_token();
08649 result.m_type = value_t::boolean;
08650 result.m_value = false;
08651 break;
08652 }
08653
08654 case lexer::token_type::value_number:
08655 {
08656 m_lexer.get_number(result);
08657 get_token();
08658 break;
08659 }
08660
08661 default:
08662 {
08663
08664 unexpect(last_token);
08665 }
08666 }
08667
08668 if (keep and callback and not callback(depth, parse_event_t::value, result))
08669 {
08670 result = basic_json(value_t::discarded);
08671 }
08672 return result;
08673 }
08674
08676 typename lexer::token_type get_token() noexcept
08677 {
08678 last_token = m_lexer.scan();
08679 return last_token;
08680 }
08681
08682 void expect(typename lexer::token_type t) const
08683 {
08684 if (t != last_token)
08685 {
08686 std::string error_msg = "parse error - unexpected ";
08687 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token() + "'") :
08688 lexer::token_type_name(last_token));
08689 error_msg += "; expected " + lexer::token_type_name(t);
08690 throw std::invalid_argument(error_msg);
08691 }
08692 }
08693
08694 void unexpect(typename lexer::token_type t) const
08695 {
08696 if (t == last_token)
08697 {
08698 std::string error_msg = "parse error - unexpected ";
08699 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token() + "'") :
08700 lexer::token_type_name(last_token));
08701 throw std::invalid_argument(error_msg);
08702 }
08703 }
08704
08705 private:
08707 int depth = 0;
08709 parser_callback_t callback;
08711 typename lexer::token_type last_token = lexer::token_type::uninitialized;
08713 lexer m_lexer;
08714 };
08715
08716 public:
08728 class json_pointer
08729 {
08731 friend class basic_json;
08732
08733 public:
08756 explicit json_pointer(const std::string& s = "")
08757 : reference_tokens(split(s))
08758 {}
08759
08775 std::string to_string() const noexcept
08776 {
08777 std::string result;
08778
08779 for (const auto& reference_token : reference_tokens)
08780 {
08781 result += "/" + escape(reference_token);
08782 }
08783
08784 return result;
08785 }
08786
08788 operator std::string() const
08789 {
08790 return to_string();
08791 }
08792
08793 private:
08795 std::string pop_back()
08796 {
08797 if (is_root())
08798 {
08799 throw std::domain_error("JSON pointer has no parent");
08800 }
08801
08802 auto last = reference_tokens.back();
08803 reference_tokens.pop_back();
08804 return last;
08805 }
08806
08808 bool is_root() const
08809 {
08810 return reference_tokens.empty();
08811 }
08812
08813 json_pointer top() const
08814 {
08815 if (is_root())
08816 {
08817 throw std::domain_error("JSON pointer has no parent");
08818 }
08819
08820 json_pointer result = *this;
08821 result.reference_tokens = {reference_tokens[0]};
08822 return result;
08823 }
08824
08828 reference get_and_create(reference j) const
08829 {
08830 pointer result = &j;
08831
08832
08833
08834 for (const auto& reference_token : reference_tokens)
08835 {
08836 switch (result->m_type)
08837 {
08838 case value_t::null:
08839 {
08840 if (reference_token == "0")
08841 {
08842
08843 result = &result->operator[](0);
08844 }
08845 else
08846 {
08847
08848 result = &result->operator[](reference_token);
08849 }
08850 break;
08851 }
08852
08853 case value_t::object:
08854 {
08855
08856 result = &result->operator[](reference_token);
08857 break;
08858 }
08859
08860 case value_t::array:
08861 {
08862
08863 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
08864 break;
08865 }
08866
08867
08868
08869
08870
08871
08872
08873
08874 default:
08875 {
08876 throw std::domain_error("invalid value to unflatten");
08877 }
08878 }
08879 }
08880
08881 return *result;
08882 }
08883
08897 reference get_unchecked(pointer ptr) const
08898 {
08899 for (const auto& reference_token : reference_tokens)
08900 {
08901 switch (ptr->m_type)
08902 {
08903 case value_t::object:
08904 {
08905
08906 ptr = &ptr->operator[](reference_token);
08907 break;
08908 }
08909
08910 case value_t::array:
08911 {
08912
08913 if (reference_token.size() > 1 and reference_token[0] == '0')
08914 {
08915 throw std::domain_error("array index must not begin with '0'");
08916 }
08917
08918 if (reference_token == "-")
08919 {
08920
08921 ptr = &ptr->operator[](ptr->m_value.array->size());
08922 }
08923 else
08924 {
08925
08926 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
08927 }
08928 break;
08929 }
08930
08931 default:
08932 {
08933 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
08934 }
08935 }
08936 }
08937
08938 return *ptr;
08939 }
08940
08941 reference get_checked(pointer ptr) const
08942 {
08943 for (const auto& reference_token : reference_tokens)
08944 {
08945 switch (ptr->m_type)
08946 {
08947 case value_t::object:
08948 {
08949
08950 ptr = &ptr->at(reference_token);
08951 break;
08952 }
08953
08954 case value_t::array:
08955 {
08956 if (reference_token == "-")
08957 {
08958
08959 throw std::out_of_range("array index '-' (" +
08960 std::to_string(ptr->m_value.array->size()) +
08961 ") is out of range");
08962 }
08963
08964
08965 if (reference_token.size() > 1 and reference_token[0] == '0')
08966 {
08967 throw std::domain_error("array index must not begin with '0'");
08968 }
08969
08970
08971 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
08972 break;
08973 }
08974
08975 default:
08976 {
08977 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
08978 }
08979 }
08980 }
08981
08982 return *ptr;
08983 }
08984
08993 const_reference get_unchecked(const_pointer ptr) const
08994 {
08995 for (const auto& reference_token : reference_tokens)
08996 {
08997 switch (ptr->m_type)
08998 {
08999 case value_t::object:
09000 {
09001
09002 ptr = &ptr->operator[](reference_token);
09003 break;
09004 }
09005
09006 case value_t::array:
09007 {
09008 if (reference_token == "-")
09009 {
09010
09011 throw std::out_of_range("array index '-' (" +
09012 std::to_string(ptr->m_value.array->size()) +
09013 ") is out of range");
09014 }
09015
09016
09017 if (reference_token.size() > 1 and reference_token[0] == '0')
09018 {
09019 throw std::domain_error("array index must not begin with '0'");
09020 }
09021
09022
09023 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
09024 break;
09025 }
09026
09027 default:
09028 {
09029 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
09030 }
09031 }
09032 }
09033
09034 return *ptr;
09035 }
09036
09037 const_reference get_checked(const_pointer ptr) const
09038 {
09039 for (const auto& reference_token : reference_tokens)
09040 {
09041 switch (ptr->m_type)
09042 {
09043 case value_t::object:
09044 {
09045
09046 ptr = &ptr->at(reference_token);
09047 break;
09048 }
09049
09050 case value_t::array:
09051 {
09052 if (reference_token == "-")
09053 {
09054
09055 throw std::out_of_range("array index '-' (" +
09056 std::to_string(ptr->m_value.array->size()) +
09057 ") is out of range");
09058 }
09059
09060
09061 if (reference_token.size() > 1 and reference_token[0] == '0')
09062 {
09063 throw std::domain_error("array index must not begin with '0'");
09064 }
09065
09066
09067 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
09068 break;
09069 }
09070
09071 default:
09072 {
09073 throw std::out_of_range("unresolved reference token '" + reference_token + "'");
09074 }
09075 }
09076 }
09077
09078 return *ptr;
09079 }
09080
09082 static std::vector<std::string> split(std::string reference_string)
09083 {
09084 std::vector<std::string> result;
09085
09086
09087 if (reference_string.empty())
09088 {
09089 return result;
09090 }
09091
09092
09093 if (reference_string[0] != '/')
09094 {
09095 throw std::domain_error("JSON pointer must be empty or begin with '/'");
09096 }
09097
09098
09099
09100
09101 for (
09102
09103 size_t slash = reference_string.find_first_of("/", 1),
09104
09105 start = 1;
09106
09107 start != 0;
09108
09109
09110 start = slash + 1,
09111
09112 slash = reference_string.find_first_of("/", start))
09113 {
09114
09115
09116 auto reference_token = reference_string.substr(start, slash - start);
09117
09118
09119 for (size_t pos = reference_token.find_first_of("~");
09120 pos != std::string::npos;
09121 pos = reference_token.find_first_of("~", pos + 1))
09122 {
09123 assert(reference_token[pos] == '~');
09124
09125
09126 if (pos == reference_token.size() - 1 or
09127 (reference_token[pos + 1] != '0' and
09128 reference_token[pos + 1] != '1'))
09129 {
09130 throw std::domain_error("escape error: '~' must be followed with '0' or '1'");
09131 }
09132 }
09133
09134
09135 unescape(reference_token);
09136 result.push_back(reference_token);
09137 }
09138
09139 return result;
09140 }
09141
09142 private:
09157 static void replace_substring(std::string& s,
09158 const std::string& f,
09159 const std::string& t)
09160 {
09161 assert(not f.empty());
09162
09163 for (
09164 size_t pos = s.find(f);
09165 pos != std::string::npos;
09166 s.replace(pos, f.size(), t),
09167 pos = s.find(f, pos + t.size())
09168 );
09169 }
09170
09172 static std::string escape(std::string s)
09173 {
09174
09175 replace_substring(s, "~", "~0");
09176 replace_substring(s, "/", "~1");
09177 return s;
09178 }
09179
09181 static void unescape(std::string& s)
09182 {
09183
09184 replace_substring(s, "~1", "/");
09185
09186 replace_substring(s, "~0", "~");
09187 }
09188
09196 static void flatten(const std::string& reference_string,
09197 const basic_json& value,
09198 basic_json& result)
09199 {
09200 switch (value.m_type)
09201 {
09202 case value_t::array:
09203 {
09204 if (value.m_value.array->empty())
09205 {
09206
09207 result[reference_string] = nullptr;
09208 }
09209 else
09210 {
09211
09212 for (size_t i = 0; i < value.m_value.array->size(); ++i)
09213 {
09214 flatten(reference_string + "/" + std::to_string(i),
09215 value.m_value.array->operator[](i), result);
09216 }
09217 }
09218 break;
09219 }
09220
09221 case value_t::object:
09222 {
09223 if (value.m_value.object->empty())
09224 {
09225
09226 result[reference_string] = nullptr;
09227 }
09228 else
09229 {
09230
09231 for (const auto& element : *value.m_value.object)
09232 {
09233 flatten(reference_string + "/" + escape(element.first),
09234 element.second, result);
09235 }
09236 }
09237 break;
09238 }
09239
09240 default:
09241 {
09242
09243 result[reference_string] = value;
09244 break;
09245 }
09246 }
09247 }
09248
09254 static basic_json unflatten(const basic_json& value)
09255 {
09256 if (not value.is_object())
09257 {
09258 throw std::domain_error("only objects can be unflattened");
09259 }
09260
09261 basic_json result;
09262
09263
09264 for (const auto& element : *value.m_value.object)
09265 {
09266 if (not element.second.is_primitive())
09267 {
09268 throw std::domain_error("values in object must be primitive");
09269 }
09270
09271
09272
09273
09274
09275
09276 json_pointer(element.first).get_and_create(result) = element.second;
09277 }
09278
09279 return result;
09280 }
09281
09282 private:
09284 std::vector<std::string> reference_tokens {};
09285 };
09286
09288
09290
09293
09327 reference operator[](const json_pointer& ptr)
09328 {
09329 return ptr.get_unchecked(this);
09330 }
09331
09354 const_reference operator[](const json_pointer& ptr) const
09355 {
09356 return ptr.get_unchecked(this);
09357 }
09358
09379 reference at(const json_pointer& ptr)
09380 {
09381 return ptr.get_checked(this);
09382 }
09383
09404 const_reference at(const json_pointer& ptr) const
09405 {
09406 return ptr.get_checked(this);
09407 }
09408
09431 basic_json flatten() const
09432 {
09433 basic_json result(value_t::object);
09434 json_pointer::flatten("", *this, result);
09435 return result;
09436 }
09437
09465 basic_json unflatten() const
09466 {
09467 return json_pointer::unflatten(*this);
09468 }
09469
09471
09473
09475
09478
09515 basic_json patch(const basic_json& json_patch) const
09516 {
09517
09518 basic_json result = *this;
09519
09520
09521 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
09522
09523 const auto get_op = [](const std::string op)
09524 {
09525 if (op == "add")
09526 {
09527 return patch_operations::add;
09528 }
09529 if (op == "remove")
09530 {
09531 return patch_operations::remove;
09532 }
09533 if (op == "replace")
09534 {
09535 return patch_operations::replace;
09536 }
09537 if (op == "move")
09538 {
09539 return patch_operations::move;
09540 }
09541 if (op == "copy")
09542 {
09543 return patch_operations::copy;
09544 }
09545 if (op == "test")
09546 {
09547 return patch_operations::test;
09548 }
09549
09550 return patch_operations::invalid;
09551 };
09552
09553
09554 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
09555 {
09556
09557 if (ptr.is_root())
09558 {
09559 result = val;
09560 }
09561 else
09562 {
09563
09564 json_pointer top_pointer = ptr.top();
09565 if (top_pointer != ptr)
09566 {
09567 basic_json& x = result.at(top_pointer);
09568 }
09569
09570
09571 const auto last_path = ptr.pop_back();
09572 basic_json& parent = result[ptr];
09573
09574 switch (parent.m_type)
09575 {
09576 case value_t::null:
09577 case value_t::object:
09578 {
09579
09580 parent[last_path] = val;
09581 break;
09582 }
09583
09584 case value_t::array:
09585 {
09586 if (last_path == "-")
09587 {
09588
09589 parent.push_back(val);
09590 }
09591 else
09592 {
09593 const auto idx = std::stoi(last_path);
09594 if (static_cast<size_type>(idx) > parent.size())
09595 {
09596
09597 throw std::out_of_range("array index " + std::to_string(idx) + " is out of range");
09598 }
09599 else
09600 {
09601
09602 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
09603 }
09604 }
09605 break;
09606 }
09607
09608 default:
09609 {
09610
09611 assert(false);
09612 }
09613 }
09614 }
09615 };
09616
09617
09618 const auto operation_remove = [&result](json_pointer & ptr)
09619 {
09620
09621 const auto last_path = ptr.pop_back();
09622 basic_json& parent = result.at(ptr);
09623
09624
09625 if (parent.is_object())
09626 {
09627
09628 auto it = parent.find(last_path);
09629 if (it != parent.end())
09630 {
09631 parent.erase(it);
09632 }
09633 else
09634 {
09635 throw std::out_of_range("key '" + last_path + "' not found");
09636 }
09637 }
09638 else if (parent.is_array())
09639 {
09640
09641 parent.erase(static_cast<size_type>(std::stoi(last_path)));
09642 }
09643 };
09644
09645
09646 if (not json_patch.is_array())
09647 {
09648
09649 throw std::invalid_argument("JSON patch must be an array of objects");
09650 }
09651
09652
09653 for (const auto& val : json_patch)
09654 {
09655
09656 const auto get_value = [&val](const std::string & op,
09657 const std::string & member,
09658 bool string_type) -> basic_json&
09659 {
09660
09661 auto it = val.m_value.object->find(member);
09662
09663
09664 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
09665
09666
09667 if (it == val.m_value.object->end())
09668 {
09669 throw std::invalid_argument(error_msg + " must have member '" + member + "'");
09670 }
09671
09672
09673 if (string_type and not it->second.is_string())
09674 {
09675 throw std::invalid_argument(error_msg + " must have string member '" + member + "'");
09676 }
09677
09678
09679 return it->second;
09680 };
09681
09682
09683 if (not val.is_object())
09684 {
09685 throw std::invalid_argument("JSON patch must be an array of objects");
09686 }
09687
09688
09689 const std::string op = get_value("op", "op", true);
09690 const std::string path = get_value(op, "path", true);
09691 json_pointer ptr(path);
09692
09693 switch (get_op(op))
09694 {
09695 case patch_operations::add:
09696 {
09697 operation_add(ptr, get_value("add", "value", false));
09698 break;
09699 }
09700
09701 case patch_operations::remove:
09702 {
09703 operation_remove(ptr);
09704 break;
09705 }
09706
09707 case patch_operations::replace:
09708 {
09709
09710 result.at(ptr) = get_value("replace", "value", false);
09711 break;
09712 }
09713
09714 case patch_operations::move:
09715 {
09716 const std::string from_path = get_value("move", "from", true);
09717 json_pointer from_ptr(from_path);
09718
09719
09720 basic_json v = result.at(from_ptr);
09721
09722
09723
09724
09725
09726 operation_remove(from_ptr);
09727 operation_add(ptr, v);
09728 break;
09729 }
09730
09731 case patch_operations::copy:
09732 {
09733 const std::string from_path = get_value("copy", "from", true);;
09734 const json_pointer from_ptr(from_path);
09735
09736
09737 result[ptr] = result.at(from_ptr);
09738 break;
09739 }
09740
09741 case patch_operations::test:
09742 {
09743 bool success = false;
09744 try
09745 {
09746
09747
09748 success = (result.at(ptr) == get_value("test", "value", false));
09749 }
09750 catch (std::out_of_range&)
09751 {
09752
09753 }
09754
09755
09756 if (not success)
09757 {
09758 throw std::domain_error("unsuccessful: " + val.dump());
09759 }
09760
09761 break;
09762 }
09763
09764 case patch_operations::invalid:
09765 {
09766
09767
09768 throw std::invalid_argument("operation value '" + op + "' is invalid");
09769 }
09770 }
09771 }
09772
09773 return result;
09774 }
09775
09808 static basic_json diff(const basic_json& source,
09809 const basic_json& target,
09810 std::string path = "")
09811 {
09812
09813 basic_json result(value_t::array);
09814
09815
09816 if (source == target)
09817 {
09818 return result;
09819 }
09820
09821 if (source.type() != target.type())
09822 {
09823
09824 result.push_back(
09825 {
09826 {"op", "replace"},
09827 {"path", path},
09828 {"value", target}
09829 });
09830 }
09831 else
09832 {
09833 switch (source.type())
09834 {
09835 case value_t::array:
09836 {
09837
09838 size_t i = 0;
09839 while (i < source.size() and i < target.size())
09840 {
09841
09842 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
09843 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
09844 ++i;
09845 }
09846
09847
09848
09849
09850
09851 const auto end_index = static_cast<difference_type>(result.size());
09852 while (i < source.size())
09853 {
09854
09855
09856 result.insert(result.begin() + end_index, object(
09857 {
09858 {"op", "remove"},
09859 {"path", path + "/" + std::to_string(i)}
09860 }));
09861 ++i;
09862 }
09863
09864
09865 while (i < target.size())
09866 {
09867 result.push_back(
09868 {
09869 {"op", "add"},
09870 {"path", path + "/" + std::to_string(i)},
09871 {"value", target[i]}
09872 });
09873 ++i;
09874 }
09875
09876 break;
09877 }
09878
09879 case value_t::object:
09880 {
09881
09882 for (auto it = source.begin(); it != source.end(); ++it)
09883 {
09884
09885 const auto key = json_pointer::escape(it.key());
09886
09887 if (target.find(it.key()) != target.end())
09888 {
09889
09890 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
09891 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
09892 }
09893 else
09894 {
09895
09896 result.push_back(object(
09897 {
09898 {"op", "remove"},
09899 {"path", path + "/" + key}
09900 }));
09901 }
09902 }
09903
09904
09905 for (auto it = target.begin(); it != target.end(); ++it)
09906 {
09907 if (source.find(it.key()) == source.end())
09908 {
09909
09910 const auto key = json_pointer::escape(it.key());
09911 result.push_back(
09912 {
09913 {"op", "add"},
09914 {"path", path + "/" + key},
09915 {"value", it.value()}
09916 });
09917 }
09918 }
09919
09920 break;
09921 }
09922
09923 default:
09924 {
09925
09926 result.push_back(
09927 {
09928 {"op", "replace"},
09929 {"path", path},
09930 {"value", target}
09931 });
09932 break;
09933 }
09934 }
09935 }
09936
09937 return result;
09938 }
09939
09941 };
09942
09943
09945
09947
09956 using json = basic_json<>;
09957 }
09958
09959
09961
09963
09964
09965 namespace std
09966 {
09972 template <>
09973 inline void swap(nlohmann::json& j1,
09974 nlohmann::json& j2) noexcept(
09975 is_nothrow_move_constructible<nlohmann::json>::value and
09976 is_nothrow_move_assignable<nlohmann::json>::value
09977 )
09978 {
09979 j1.swap(j2);
09980 }
09981
09983 template <>
09984 struct hash<nlohmann::json>
09985 {
09991 std::size_t operator()(const nlohmann::json& j) const
09992 {
09993
09994 const auto& h = hash<nlohmann::json::string_t>();
09995 return h(j.dump());
09996 }
09997 };
09998 }
09999
10012 inline nlohmann::json operator "" _json(const char* s, std::size_t)
10013 {
10014 return nlohmann::json::parse(reinterpret_cast<const nlohmann::json::string_t::value_type*>(s));
10015 }
10016
10022 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t)
10023 {
10024 return nlohmann::json::json_pointer(s);
10025 }
10026
10027
10028 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
10029 #pragma GCC diagnostic pop
10030 #endif
10031
10032 #endif