29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
42 #include <initializer_list>
52 #include <type_traits>
57 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
58 #pragma GCC diagnostic push
59 #pragma GCC diagnostic ignored "-Wfloat-equal"
82 struct has_mapped_type
85 template<
typename C>
static char test(
typename C::mapped_type*);
86 template<
typename C>
static char (&test(...))[2];
88 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
165 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
166 template<
typename U,
typename... Args>
class ArrayType = std::vector,
167 class StringType = std::string,
168 class BooleanType = bool,
169 class NumberIntegerType = std::int64_t,
170 class NumberUnsignedType = std::uint64_t,
171 class NumberFloatType = double,
172 template<
typename U>
class AllocatorType = std::allocator
213 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
215 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
330 using object_t = ObjectType<StringType,
332 std::less<StringType>,
333 AllocatorType<std::pair<
const StringType,
380 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
699 template<
typename T,
typename... Args>
700 static T* create(Args&& ... args)
702 AllocatorType<T> alloc;
703 auto deleter = [&](T *
object)
705 alloc.deallocate(
object, 1);
707 std::unique_ptr<T, decltype(deleter)>
object(alloc.allocate(1), deleter);
708 alloc.construct(
object.
get(), std::forward<Args>(args)...);
709 return object.release();
741 json_value() =
default;
743 json_value(
boolean_t v) noexcept : boolean(v) {}
757 object = create<object_t>();
763 array = create<array_t>();
769 string = create<string_t>(
"");
807 string = create<string_t>(
value);
813 object = create<object_t>(
value);
819 array = create<array_t>(
value);
902 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
952 : m_type(value_type), m_value(value_type)
1027 : m_type(
value_t::object), m_value(val)
1056 template <
class CompatibleObjectType,
typename
1058 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1059 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>
::type
1066 m_value.object = create<object_t>(
begin(val),
end(val));
1089 : m_type(
value_t::array), m_value(val)
1118 template <
class CompatibleArrayType,
typename
1120 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1121 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1122 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1123 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1124 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1125 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1126 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1133 m_value.array = create<array_t>(
begin(val),
end(val));
1158 : m_type(
value_t::string), m_value(val)
1208 template <
class CompatibleStringType,
typename
1210 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1257 template<
typename T,
1258 typename std::enable_if<
1259 not (std::is_same<T, int>::value)
1264 : m_type(
value_t::number_integer), m_value(val)
1294 m_value(static_cast<number_integer_t>(val))
1322 template<
typename CompatibleNumberIntegerType,
typename
1324 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1325 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1326 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1327 CompatibleNumberIntegerType>::type
1331 m_value(static_cast<number_integer_t>(val))
1351 template<
typename T,
1352 typename std::enable_if<
1353 not (std::is_same<T, int>::value)
1358 : m_type(
value_t::number_unsigned), m_value(val)
1381 template <
typename CompatibleNumberUnsignedType,
typename
1383 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1384 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1385 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1386 CompatibleNumberUnsignedType >::type
1390 m_value(static_cast<number_unsigned_t>(val))
1421 if (not std::isfinite(val))
1424 m_value = json_value();
1458 template<
typename CompatibleNumberFloatType,
typename =
typename
1460 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1461 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1537 bool type_deduction =
true,
1541 bool is_an_object =
true;
1545 for (
const auto& element : init)
1547 if (not element.is_array() or element.size() != 2
1548 or not element[0].is_string())
1552 is_an_object =
false;
1558 if (not type_deduction)
1563 is_an_object =
false;
1569 throw std::domain_error(
"cannot create object from initializer list");
1579 assert(m_value.object !=
nullptr);
1581 for (
auto& element : init)
1583 m_value.object->emplace(*(element[0].m_value.string), element[1]);
1590 m_value.array = create<array_t>(init);
1628 static basic_json
array(std::initializer_list<basic_json> init =
1629 std::initializer_list<basic_json>())
1668 static basic_json
object(std::initializer_list<basic_json> init =
1669 std::initializer_list<basic_json>())
1695 m_value.array = create<array_t>(cnt, val);
1732 template <
class InputIT,
typename
1734 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1735 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1738 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1741 if (first.m_object != last.m_object)
1743 throw std::domain_error(
"iterators are not compatible");
1755 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1757 throw std::out_of_range(
"iterators out of range");
1772 assert(first.m_object !=
nullptr);
1773 m_value.number_integer = first.m_object->m_value.number_integer;
1779 assert(first.m_object !=
nullptr);
1780 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1786 assert(first.m_object !=
nullptr);
1787 m_value.number_float = first.m_object->m_value.number_float;
1793 assert(first.m_object !=
nullptr);
1794 m_value.boolean = first.m_object->m_value.boolean;
1800 assert(first.m_object !=
nullptr);
1801 m_value = *first.m_object->m_value.string;
1807 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1813 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1819 assert(first.m_object !=
nullptr);
1820 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1847 *
this = parser(i, cb).parse();
1877 : m_type(other.m_type)
1883 assert(other.m_value.object !=
nullptr);
1884 m_value = *other.m_value.object;
1890 assert(other.m_value.array !=
nullptr);
1891 m_value = *other.m_value.array;
1897 assert(other.m_value.string !=
nullptr);
1898 m_value = *other.m_value.string;
1904 m_value = other.m_value.boolean;
1910 m_value = other.m_value.number_integer;
1916 m_value = other.m_value.number_unsigned;
1922 m_value = other.m_value.number_float;
1952 : m_type(
std::move(other.m_type)),
1953 m_value(
std::move(other.m_value))
1984 std::is_nothrow_move_constructible<value_t>::value and
1985 std::is_nothrow_move_assignable<value_t>::value and
1986 std::is_nothrow_move_constructible<json_value>::value and
1987 std::is_nothrow_move_assignable<json_value>::value
1991 swap(m_type, other.m_type);
1992 swap(m_value, other.m_value);
2017 AllocatorType<object_t> alloc;
2018 alloc.destroy(m_value.object);
2019 alloc.deallocate(m_value.object, 1);
2025 AllocatorType<array_t> alloc;
2026 alloc.destroy(m_value.array);
2027 alloc.deallocate(m_value.array, 1);
2033 AllocatorType<string_t> alloc;
2034 alloc.destroy(m_value.string);
2035 alloc.deallocate(m_value.string, 1);
2082 std::stringstream ss;
2086 dump(ss,
true, static_cast<unsigned int>(indent));
2459 template <
class T,
typename
2461 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2462 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2464 T get_impl(T*)
const
2468 assert(m_value.object !=
nullptr);
2469 return T(m_value.object->begin(), m_value.object->end());
2473 throw std::domain_error(
"type must be object, but is " + type_name());
2482 assert(m_value.object !=
nullptr);
2483 return *(m_value.object);
2487 throw std::domain_error(
"type must be object, but is " + type_name());
2492 template <
class T,
typename
2494 std::is_convertible<basic_json_t, typename T::value_type>::value and
2495 not std::is_same<basic_json_t, typename T::value_type>::value and
2496 not std::is_arithmetic<T>::value and
2497 not std::is_convertible<std::string, T>::value and
2498 not has_mapped_type<T>::value
2500 T get_impl(T*)
const
2505 assert(m_value.array !=
nullptr);
2506 std::transform(m_value.array->begin(), m_value.array->end(),
2507 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2509 return i.get<
typename T::value_type>();
2515 throw std::domain_error(
"type must be array, but is " + type_name());
2520 template <
class T,
typename
2522 std::is_convertible<basic_json_t, T>::value and
2523 not std::is_same<basic_json_t, T>::value
2525 std::vector<T> get_impl(std::vector<T>*)
const
2529 std::vector<T> to_vector;
2530 assert(m_value.array !=
nullptr);
2531 to_vector.reserve(m_value.array->size());
2532 std::transform(m_value.array->begin(), m_value.array->end(),
2533 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2541 throw std::domain_error(
"type must be array, but is " + type_name());
2546 template <
class T,
typename
2548 std::is_same<basic_json, typename T::value_type>::value and
2549 not has_mapped_type<T>::value
2551 T get_impl(T*)
const
2555 assert(m_value.array !=
nullptr);
2556 return T(m_value.array->begin(), m_value.array->end());
2560 throw std::domain_error(
"type must be array, but is " + type_name());
2569 assert(m_value.array !=
nullptr);
2570 return *(m_value.array);
2574 throw std::domain_error(
"type must be array, but is " + type_name());
2579 template <
typename T,
typename
2581 std::is_convertible<string_t, T>::value
2583 T get_impl(T*)
const
2587 assert(m_value.string !=
nullptr);
2588 return *m_value.string;
2592 throw std::domain_error(
"type must be string, but is " + type_name());
2597 template<
typename T,
typename
2599 std::is_arithmetic<T>::value
2601 T get_impl(T*)
const
2607 return static_cast<T
>(m_value.number_integer);
2612 return static_cast<T
>(m_value.number_unsigned);
2617 return static_cast<T
>(m_value.number_float);
2622 throw std::domain_error(
"type must be number, but is " + type_name());
2632 :
throw std::domain_error(
"type must be boolean, but is " + type_name());
2638 return is_object() ? m_value.object :
nullptr;
2644 return is_object() ? m_value.object :
nullptr;
2650 return is_array() ? m_value.array :
nullptr;
2654 constexpr
const array_t* get_impl_ptr(
const array_t*) const noexcept
2656 return is_array() ? m_value.array :
nullptr;
2662 return is_string() ? m_value.string :
nullptr;
2668 return is_string() ? m_value.string :
nullptr;
2674 return is_boolean() ? &m_value.boolean :
nullptr;
2680 return is_boolean() ? &m_value.boolean :
nullptr;
2730 template<
typename ReferenceType,
typename ThisType>
2731 static ReferenceType get_ref_impl(ThisType& obj)
2734 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2735 auto ptr = obj.template get_ptr<PointerType>();
2743 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2786 template<
typename ValueType,
typename
2788 not std::is_pointer<ValueType>::value
2790 ValueType
get()
const
2792 return get_impl(static_cast<ValueType*>(
nullptr));
2821 template<
typename PointerType,
typename
2823 std::is_pointer<PointerType>::value
2825 PointerType
get() noexcept
2828 return get_ptr<PointerType>();
2835 template<
typename PointerType,
typename
2837 std::is_pointer<PointerType>::value
2839 constexpr
const PointerType
get()
const noexcept
2842 return get_ptr<PointerType>();
2870 template<
typename PointerType,
typename
2872 std::is_pointer<PointerType>::value
2877 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2884 template<
typename PointerType,
typename
2886 std::is_pointer<PointerType>::value
2887 and std::is_const<typename std::remove_pointer<PointerType>::type>
::value
2889 constexpr
const PointerType
get_ptr() const noexcept
2892 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2921 template<
typename ReferenceType,
typename
2923 std::is_reference<ReferenceType>::value
2928 return get_ref_impl<ReferenceType>(*this);
2935 template<
typename ReferenceType,
typename
2937 std::is_reference<ReferenceType>::value
2938 and std::is_const<typename std::remove_reference<ReferenceType>::type>
::value
2943 return get_ref_impl<ReferenceType>(*this);
2974 template <
typename ValueType,
typename
2976 not std::is_pointer<ValueType>::value
2977 and not std::is_same<ValueType, typename string_t::value_type>::value
2978 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015
2979 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2982 operator ValueType()
const
2985 return get<ValueType>();
3027 assert(m_value.array !=
nullptr);
3028 return m_value.array->at(idx);
3030 catch (std::out_of_range&)
3033 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3038 throw std::domain_error(
"cannot use at() with " + type_name());
3071 assert(m_value.array !=
nullptr);
3072 return m_value.array->at(idx);
3074 catch (std::out_of_range&)
3077 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3082 throw std::domain_error(
"cannot use at() with " + type_name());
3119 assert(m_value.object !=
nullptr);
3120 return m_value.object->at(key);
3122 catch (std::out_of_range&)
3125 throw std::out_of_range(
"key '" + key +
"' not found");
3130 throw std::domain_error(
"cannot use at() with " + type_name());
3167 assert(m_value.object !=
nullptr);
3168 return m_value.object->at(key);
3170 catch (std::out_of_range&)
3173 throw std::out_of_range(
"key '" + key +
"' not found");
3178 throw std::domain_error(
"cannot use at() with " + type_name());
3213 m_value.array = create<array_t>();
3220 assert(m_value.array !=
nullptr);
3221 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3226 return m_value.array->operator[](idx);
3230 throw std::domain_error(
"cannot use operator[] with " + type_name());
3258 assert(m_value.array !=
nullptr);
3259 return m_value.array->operator[](idx);
3263 throw std::domain_error(
"cannot use operator[] with " + type_name());
3300 m_value.object = create<object_t>();
3306 assert(m_value.object !=
nullptr);
3307 return m_value.object->operator[](key);
3311 throw std::domain_error(
"cannot use operator[] with " + type_name());
3347 assert(m_value.object !=
nullptr);
3348 assert(m_value.object->find(key) != m_value.object->end());
3349 return m_value.object->find(key)->second;
3353 throw std::domain_error(
"cannot use operator[] with " + type_name());
3384 template<
typename T, std::
size_t n>
3387 return operator[](static_cast<const T>(key));
3419 template<
typename T, std::
size_t n>
3422 return operator[](static_cast<const T>(key));
3452 template<
typename T>
3465 assert(m_value.object !=
nullptr);
3466 return m_value.object->operator[](key);
3470 throw std::domain_error(
"cannot use operator[] with " + type_name());
3501 template<
typename T>
3507 assert(m_value.object !=
nullptr);
3508 assert(m_value.object->find(key) != m_value.object->end());
3509 return m_value.object->find(key)->second;
3513 throw std::domain_error(
"cannot use operator[] with " + type_name());
3565 template <
class ValueType,
typename
3567 std::is_convertible<basic_json_t, ValueType>::value
3569 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const
3575 const auto it =
find(key);
3582 return default_value;
3587 throw std::domain_error(
"cannot use value() with " + type_name());
3595 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
3728 template <
class InteratorType,
typename
3730 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3731 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3737 if (
this != pos.m_object)
3739 throw std::domain_error(
"iterator does not fit current value");
3742 InteratorType result =
end();
3752 if (not pos.m_it.primitive_iterator.is_begin())
3754 throw std::out_of_range(
"iterator out of range");
3759 delete m_value.string;
3760 m_value.string =
nullptr;
3769 assert(m_value.object !=
nullptr);
3770 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3776 assert(m_value.array !=
nullptr);
3777 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3783 throw std::domain_error(
"cannot use erase() with " + type_name());
3836 template <
class InteratorType,
typename
3838 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3839 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3842 InteratorType
erase(InteratorType first, InteratorType last)
3845 if (
this != first.m_object or
this != last.m_object)
3847 throw std::domain_error(
"iterators do not fit current value");
3850 InteratorType result =
end();
3860 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3862 throw std::out_of_range(
"iterators out of range");
3867 delete m_value.string;
3868 m_value.string =
nullptr;
3877 assert(m_value.object !=
nullptr);
3878 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3879 last.m_it.object_iterator);
3885 assert(m_value.array !=
nullptr);
3886 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3887 last.m_it.array_iterator);
3893 throw std::domain_error(
"cannot use erase() with " + type_name());
3934 assert(m_value.object !=
nullptr);
3935 return m_value.object->erase(key);
3939 throw std::domain_error(
"cannot use erase() with " + type_name());
3974 throw std::out_of_range(
"index out of range");
3977 assert(m_value.array !=
nullptr);
3978 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3982 throw std::domain_error(
"cannot use erase() with " + type_name());
4015 auto result =
end();
4019 assert(m_value.object !=
nullptr);
4020 result.m_it.object_iterator = m_value.object->find(key);
4032 auto result =
cend();
4036 assert(m_value.object !=
nullptr);
4037 result.m_it.object_iterator = m_value.object->find(key);
4064 assert(not
is_object() or m_value.object !=
nullptr);
4065 return is_object() ? m_value.object->count(key) : 0;
4353 template<
typename IteratorType>
class iteration_proxy;
4369 return iteration_proxy<iterator>(cont);
4377 return iteration_proxy<const_iterator>(cont);
4435 assert(m_value.array !=
nullptr);
4436 return m_value.array->empty();
4441 assert(m_value.object !=
nullptr);
4442 return m_value.object->empty();
4498 assert(m_value.array !=
nullptr);
4499 return m_value.array->size();
4504 assert(m_value.object !=
nullptr);
4505 return m_value.object->size();
4558 assert(m_value.array !=
nullptr);
4559 return m_value.array->max_size();
4564 assert(m_value.object !=
nullptr);
4565 return m_value.object->max_size();
4617 m_value.number_integer = 0;
4623 m_value.number_unsigned = 0;
4629 m_value.number_float = 0.0;
4635 m_value.boolean =
false;
4641 assert(m_value.string !=
nullptr);
4642 m_value.string->clear();
4648 assert(m_value.array !=
nullptr);
4649 m_value.array->clear();
4655 assert(m_value.object !=
nullptr);
4656 m_value.object->clear();
4692 throw std::domain_error(
"cannot use push_back() with " + type_name());
4703 assert(m_value.array !=
nullptr);
4704 m_value.array->push_back(std::move(val));
4728 throw std::domain_error(
"cannot use push_back() with " + type_name());
4739 assert(m_value.array !=
nullptr);
4740 m_value.array->push_back(val);
4778 throw std::domain_error(
"cannot use push_back() with " + type_name());
4789 assert(m_value.object !=
nullptr);
4790 m_value.object->insert(val);
4831 if (pos.m_object !=
this)
4833 throw std::domain_error(
"iterator does not fit current value");
4838 assert(m_value.array !=
nullptr);
4839 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4844 throw std::domain_error(
"cannot use insert() with " + type_name());
4887 if (pos.m_object !=
this)
4889 throw std::domain_error(
"iterator does not fit current value");
4894 assert(m_value.array !=
nullptr);
4895 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4900 throw std::domain_error(
"cannot use insert() with " + type_name());
4939 throw std::domain_error(
"cannot use insert() with " + type_name());
4943 if (pos.m_object !=
this)
4945 throw std::domain_error(
"iterator does not fit current value");
4948 if (first.m_object != last.m_object)
4950 throw std::domain_error(
"iterators do not fit");
4953 if (first.m_object ==
this or last.m_object ==
this)
4955 throw std::domain_error(
"passed iterators may not belong to container");
4960 assert(m_value.array !=
nullptr);
4961 result.m_it.array_iterator = m_value.array->insert(
4962 pos.m_it.array_iterator,
4963 first.m_it.array_iterator,
4964 last.m_it.array_iterator);
4997 throw std::domain_error(
"cannot use insert() with " + type_name());
5001 if (pos.m_object !=
this)
5003 throw std::domain_error(
"iterator does not fit current value");
5008 assert(m_value.array !=
nullptr);
5009 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5031 std::is_nothrow_move_constructible<value_t>::value and
5032 std::is_nothrow_move_assignable<value_t>::value and
5033 std::is_nothrow_move_constructible<json_value>::value and
5034 std::is_nothrow_move_assignable<json_value>::value
5037 std::swap(m_type, other.m_type);
5038 std::swap(m_value, other.m_value);
5066 assert(m_value.array !=
nullptr);
5067 std::swap(*(m_value.array), other);
5071 throw std::domain_error(
"cannot use swap() with " + type_name());
5100 assert(m_value.object !=
nullptr);
5101 std::swap(*(m_value.object), other);
5105 throw std::domain_error(
"cannot use swap() with " + type_name());
5134 assert(m_value.string !=
nullptr);
5135 std::swap(*(m_value.string), other);
5139 throw std::domain_error(
"cannot use swap() with " + type_name());
5165 static constexpr std::array<uint8_t, 8> order = {{
5183 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5212 const auto lhs_type = lhs.type();
5213 const auto rhs_type = rhs.type();
5215 if (lhs_type == rhs_type)
5221 assert(lhs.m_value.array !=
nullptr);
5222 assert(rhs.m_value.array !=
nullptr);
5223 return *lhs.m_value.array == *rhs.m_value.array;
5227 assert(lhs.m_value.object !=
nullptr);
5228 assert(rhs.m_value.object !=
nullptr);
5229 return *lhs.m_value.object == *rhs.m_value.object;
5237 assert(lhs.m_value.string !=
nullptr);
5238 assert(rhs.m_value.string !=
nullptr);
5239 return *lhs.m_value.string == *rhs.m_value.string;
5243 return lhs.m_value.boolean == rhs.m_value.boolean;
5247 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5251 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5255 return lhs.m_value.number_float == rhs.m_value.number_float;
5265 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5269 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5273 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5277 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5281 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5285 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5341 return not (lhs == rhs);
5373 return not v.is_null();
5402 const auto lhs_type = lhs.type();
5403 const auto rhs_type = rhs.type();
5405 if (lhs_type == rhs_type)
5411 assert(lhs.m_value.array !=
nullptr);
5412 assert(rhs.m_value.array !=
nullptr);
5413 return *lhs.m_value.array < *rhs.m_value.array;
5417 assert(lhs.m_value.object !=
nullptr);
5418 assert(rhs.m_value.object !=
nullptr);
5419 return *lhs.m_value.object < *rhs.m_value.object;
5427 assert(lhs.m_value.string !=
nullptr);
5428 assert(rhs.m_value.string !=
nullptr);
5429 return *lhs.m_value.string < *rhs.m_value.string;
5433 return lhs.m_value.boolean < rhs.m_value.boolean;
5437 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5441 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5445 return lhs.m_value.number_float < rhs.m_value.number_float;
5455 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5459 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5463 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5467 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5471 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5475 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5503 return not (rhs < lhs);
5525 return not (lhs <= rhs);
5547 return not (lhs < rhs);
5582 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5585 const bool pretty_print = (o.width() > 0);
5586 const auto indentation = (pretty_print ? o.width() : 0);
5592 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5600 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5641 return parser(s, cb).
parse();
5670 return parser(i, cb).
parse();
5678 return parser(i, cb).
parse();
5706 j = parser(i).
parse();
5716 j = parser(i).
parse();
5729 string_t type_name() const noexcept
5758 static std::size_t extra_space(
const string_t& s) noexcept
5760 std::size_t result = 0;
5762 for (
const auto& c : s)
5781 if (c >= 0x00 and c <= 0x1f)
5809 const auto space = extra_space(s);
5816 string_t result(s.size() + space,
'\\');
5817 std::size_t pos = 0;
5819 for (
const auto& c : s)
5826 result[pos + 1] =
'"';
5842 result[pos + 1] =
'b';
5850 result[pos + 1] =
'f';
5858 result[pos + 1] =
'n';
5866 result[pos + 1] =
'r';
5874 result[pos + 1] =
't';
5881 if (c >= 0x00 and c <= 0x1f)
5885 auto hexify = [](
const char v) ->
char
5887 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5892 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5930 void dump(std::ostream& o,
5931 const bool pretty_print,
5932 const unsigned int indent_step,
5933 const unsigned int current_indent = 0)
const
5936 unsigned int new_indent = current_indent;
5942 assert(m_value.object !=
nullptr);
5944 if (m_value.object->empty())
5955 new_indent += indent_step;
5959 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5961 if (i != m_value.object->cbegin())
5963 o << (pretty_print ?
",\n" :
",");
5965 o <<
string_t(new_indent,
' ') <<
"\""
5966 << escape_string(i->first) <<
"\":"
5967 << (pretty_print ?
" " :
"");
5968 i->second.dump(o, pretty_print, indent_step, new_indent);
5974 new_indent -= indent_step;
5978 o <<
string_t(new_indent,
' ') +
"}";
5984 assert(m_value.array !=
nullptr);
5986 if (m_value.array->empty())
5997 new_indent += indent_step;
6001 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
6003 if (i != m_value.array->cbegin())
6005 o << (pretty_print ?
",\n" :
",");
6008 i->dump(o, pretty_print, indent_step, new_indent);
6014 new_indent -= indent_step;
6018 o <<
string_t(new_indent,
' ') <<
"]";
6024 assert(m_value.string !=
nullptr);
6025 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
6031 o << (m_value.boolean ?
"true" :
"false");
6037 o << m_value.number_integer;
6043 o << m_value.number_unsigned;
6055 if (std::fmod(m_value.number_float, 1) == 0)
6057 o << std::fixed << std::setprecision(1);
6062 o.unsetf(std::ios_base::floatfield);
6063 o << std::setprecision(std::numeric_limits<double>::digits10);
6065 o << m_value.number_float;
6092 json_value m_value = {};
6109 class primitive_iterator_t
6113 void set_begin() noexcept
6119 void set_end() noexcept
6125 constexpr
bool is_begin() const noexcept
6127 return (m_it == begin_value);
6131 constexpr
bool is_end() const noexcept
6133 return (m_it == end_value);
6153 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6163 struct internal_iterator
6166 typename object_t::iterator object_iterator;
6168 typename array_t::iterator array_iterator;
6170 primitive_iterator_t primitive_iterator;
6173 internal_iterator() noexcept
6174 : object_iterator(), array_iterator(), primitive_iterator()
6179 template<
typename IteratorType>
6180 class iteration_proxy
6184 class iteration_proxy_internal
6188 IteratorType anchor;
6190 size_t array_index = 0;
6193 explicit iteration_proxy_internal(IteratorType it) noexcept
6198 iteration_proxy_internal& operator*()
6204 iteration_proxy_internal& operator++()
6213 bool operator!= (
const iteration_proxy_internal& o)
const
6215 return anchor != o.anchor;
6221 assert(anchor.m_object !=
nullptr);
6223 switch (anchor.m_object->type())
6228 return std::to_string(array_index);
6234 return anchor.key();
6246 typename IteratorType::reference
value()
const
6248 return anchor.value();
6253 typename IteratorType::reference container;
6257 explicit iteration_proxy(
typename IteratorType::reference cont)
6262 iteration_proxy_internal
begin() noexcept
6264 return iteration_proxy_internal(container.begin());
6268 iteration_proxy_internal
end() noexcept
6270 return iteration_proxy_internal(container.end());
6288 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6291 friend class basic_json;
6312 assert(m_object !=
nullptr);
6314 switch (m_object->m_type)
6318 m_it.object_iterator =
typename object_t::iterator();
6324 m_it.array_iterator =
typename array_t::iterator();
6330 m_it.primitive_iterator = primitive_iterator_t();
6338 : m_object(other.m_object)
6340 assert(m_object !=
nullptr);
6342 switch (m_object->m_type)
6346 m_it.object_iterator = other.m_it.object_iterator;
6352 m_it.array_iterator = other.m_it.array_iterator;
6358 m_it.primitive_iterator = other.m_it.primitive_iterator;
6366 : m_object(other.m_object), m_it(other.m_it)
6371 std::is_nothrow_move_constructible<pointer>::value and
6372 std::is_nothrow_move_assignable<pointer>::value and
6373 std::is_nothrow_move_constructible<internal_iterator>::value and
6374 std::is_nothrow_move_assignable<internal_iterator>::value
6377 std::swap(m_object, other.m_object);
6378 std::swap(m_it, other.m_it);
6384 void set_begin() noexcept
6386 assert(m_object !=
nullptr);
6388 switch (m_object->m_type)
6392 assert(m_object->m_value.object !=
nullptr);
6393 m_it.object_iterator = m_object->m_value.object->begin();
6399 assert(m_object->m_value.array !=
nullptr);
6400 m_it.array_iterator = m_object->m_value.array->begin();
6407 m_it.primitive_iterator.set_end();
6413 m_it.primitive_iterator.set_begin();
6420 void set_end() noexcept
6422 assert(m_object !=
nullptr);
6424 switch (m_object->m_type)
6428 assert(m_object->m_value.object !=
nullptr);
6429 m_it.object_iterator = m_object->m_value.object->end();
6435 assert(m_object->m_value.array !=
nullptr);
6436 m_it.array_iterator = m_object->m_value.array->end();
6442 m_it.primitive_iterator.set_end();
6452 assert(m_object !=
nullptr);
6454 switch (m_object->m_type)
6458 assert(m_object->m_value.object);
6459 assert(m_it.object_iterator != m_object->m_value.object->end());
6460 return m_it.object_iterator->second;
6465 assert(m_object->m_value.array);
6466 assert(m_it.array_iterator != m_object->m_value.array->end());
6467 return *m_it.array_iterator;
6472 throw std::out_of_range(
"cannot get value");
6477 if (m_it.primitive_iterator.is_begin())
6483 throw std::out_of_range(
"cannot get value");
6492 assert(m_object !=
nullptr);
6494 switch (m_object->m_type)
6498 assert(m_object->m_value.object);
6499 assert(m_it.object_iterator != m_object->m_value.object->end());
6500 return &(m_it.object_iterator->second);
6505 assert(m_object->m_value.array);
6506 assert(m_it.array_iterator != m_object->m_value.array->end());
6507 return &*m_it.array_iterator;
6512 if (m_it.primitive_iterator.is_begin())
6518 throw std::out_of_range(
"cannot get value");
6527 auto result = *
this;
6535 assert(m_object !=
nullptr);
6537 switch (m_object->m_type)
6541 ++m_it.object_iterator;
6547 ++m_it.array_iterator;
6553 ++m_it.primitive_iterator;
6564 auto result = *
this;
6572 assert(m_object !=
nullptr);
6574 switch (m_object->m_type)
6578 --m_it.object_iterator;
6584 --m_it.array_iterator;
6590 --m_it.primitive_iterator;
6602 if (m_object != other.m_object)
6604 throw std::domain_error(
"cannot compare iterators of different containers");
6607 assert(m_object !=
nullptr);
6609 switch (m_object->m_type)
6613 return (m_it.object_iterator == other.m_it.object_iterator);
6618 return (m_it.array_iterator == other.m_it.array_iterator);
6623 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6638 if (m_object != other.m_object)
6640 throw std::domain_error(
"cannot compare iterators of different containers");
6643 assert(m_object !=
nullptr);
6645 switch (m_object->m_type)
6649 throw std::domain_error(
"cannot compare order of object iterators");
6654 return (m_it.array_iterator < other.m_it.array_iterator);
6659 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6667 return not other.operator < (*this);
6685 assert(m_object !=
nullptr);
6687 switch (m_object->m_type)
6691 throw std::domain_error(
"cannot use offsets with object iterators");
6696 m_it.array_iterator += i;
6702 m_it.primitive_iterator += i;
6719 auto result = *
this;
6727 auto result = *
this;
6735 assert(m_object !=
nullptr);
6737 switch (m_object->m_type)
6741 throw std::domain_error(
"cannot use offsets with object iterators");
6746 return m_it.array_iterator - other.m_it.array_iterator;
6751 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6759 assert(m_object !=
nullptr);
6761 switch (m_object->m_type)
6765 throw std::domain_error(
"cannot use operator[] for object iterators");
6770 return *(m_it.array_iterator + n);
6775 throw std::out_of_range(
"cannot get value");
6780 if (m_it.primitive_iterator == -n)
6786 throw std::out_of_range(
"cannot get value");
6793 typename object_t::key_type
key()
const
6795 assert(m_object !=
nullptr);
6797 if (m_object->is_object())
6799 return m_it.object_iterator->first;
6803 throw std::domain_error(
"cannot use key() for non-object iterators");
6817 internal_iterator m_it = internal_iterator();
6854 std::is_nothrow_move_constructible<pointer>::value and
6855 std::is_nothrow_move_assignable<pointer>::value and
6856 std::is_nothrow_move_constructible<internal_iterator>::value and
6857 std::is_nothrow_move_assignable<internal_iterator>::value
6923 auto result = *
this;
6931 auto result = *
this;
6972 template<
typename Base>
6973 class json_reverse_iterator :
public std::reverse_iterator<Base>
6994 return base_iterator::operator++(1);
7000 base_iterator::operator++();
7007 return base_iterator::operator--(1);
7013 base_iterator::operator--();
7020 base_iterator::operator+=(i);
7027 auto result = *
this;
7035 auto result = *
this;
7043 return this->base() - other.base();
7053 typename object_t::key_type
key()
const
7055 auto it = --this->base();
7062 auto it = --this->base();
7063 return it.operator * ();
7084 enum class token_type
7103 using lexer_char_t =
unsigned char;
7106 explicit lexer(
const string_t& s) noexcept
7107 : m_stream(
nullptr), m_buffer(s)
7109 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7110 assert(m_content !=
nullptr);
7111 m_start = m_cursor = m_content;
7112 m_limit = m_content + s.size();
7116 explicit lexer(std::istream* s) noexcept
7117 : m_stream(s), m_buffer()
7119 assert(m_stream !=
nullptr);
7120 getline(*m_stream, m_buffer);
7121 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7122 assert(m_content !=
nullptr);
7123 m_start = m_cursor = m_content;
7124 m_limit = m_content + m_buffer.size();
7131 lexer(
const lexer&) =
delete;
7149 static string_t to_unicode(
const std::size_t codepoint1,
7150 const std::size_t codepoint2 = 0)
7153 std::size_t codepoint = codepoint1;
7156 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7159 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7173 throw std::invalid_argument(
"missing or wrong low surrogate");
7179 if (codepoint < 0x80)
7182 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7184 else if (codepoint <= 0x7ff)
7187 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7188 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7190 else if (codepoint <= 0xffff)
7193 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7194 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7195 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7197 else if (codepoint <= 0x10ffff)
7200 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7201 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7202 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7203 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7207 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7214 static std::string token_type_name(token_type t)
7218 case token_type::uninitialized:
7219 return "<uninitialized>";
7220 case token_type::literal_true:
7221 return "true literal";
7222 case token_type::literal_false:
7223 return "false literal";
7224 case token_type::literal_null:
7225 return "null literal";
7226 case token_type::value_string:
7227 return "string literal";
7228 case token_type::value_number:
7229 return "number literal";
7230 case token_type::begin_array:
7232 case token_type::begin_object:
7234 case token_type::end_array:
7236 case token_type::end_object:
7238 case token_type::name_separator:
7240 case token_type::value_separator:
7242 case token_type::parse_error:
7243 return "<parse error>";
7244 case token_type::end_of_input:
7245 return "end of input";
7249 return "unknown token";
7264 token_type scan() noexcept
7271 assert(m_start !=
nullptr);
7276 unsigned int yyaccept = 0;
7277 static const unsigned char yybm[] =
7279 0, 0, 0, 0, 0, 0, 0, 0,
7280 0, 32, 32, 0, 0, 32, 0, 0,
7281 128, 128, 128, 128, 128, 128, 128, 128,
7282 128, 128, 128, 128, 128, 128, 128, 128,
7283 160, 128, 0, 128, 128, 128, 128, 128,
7284 128, 128, 128, 128, 128, 128, 128, 128,
7285 192, 192, 192, 192, 192, 192, 192, 192,
7286 192, 192, 128, 128, 128, 128, 128, 128,
7287 128, 128, 128, 128, 128, 128, 128, 128,
7288 128, 128, 128, 128, 128, 128, 128, 128,
7289 128, 128, 128, 128, 128, 128, 128, 128,
7290 128, 128, 128, 128, 0, 128, 128, 128,
7291 128, 128, 128, 128, 128, 128, 128, 128,
7292 128, 128, 128, 128, 128, 128, 128, 128,
7293 128, 128, 128, 128, 128, 128, 128, 128,
7294 128, 128, 128, 128, 128, 128, 128, 128,
7295 128, 128, 128, 128, 128, 128, 128, 128,
7296 128, 128, 128, 128, 128, 128, 128, 128,
7297 128, 128, 128, 128, 128, 128, 128, 128,
7298 128, 128, 128, 128, 128, 128, 128, 128,
7299 128, 128, 128, 128, 128, 128, 128, 128,
7300 128, 128, 128, 128, 128, 128, 128, 128,
7301 128, 128, 128, 128, 128, 128, 128, 128,
7302 128, 128, 128, 128, 128, 128, 128, 128,
7303 128, 128, 128, 128, 128, 128, 128, 128,
7304 128, 128, 128, 128, 128, 128, 128, 128,
7305 128, 128, 128, 128, 128, 128, 128, 128,
7306 128, 128, 128, 128, 128, 128, 128, 128,
7307 128, 128, 128, 128, 128, 128, 128, 128,
7308 128, 128, 128, 128, 128, 128, 128, 128,
7309 128, 128, 128, 128, 128, 128, 128, 128,
7310 128, 128, 128, 128, 128, 128, 128, 128,
7312 if ((m_limit - m_cursor) < 5)
7317 if (yybm[0 + yych] & 32)
7319 goto basic_json_parser_6;
7329 goto basic_json_parser_2;
7333 goto basic_json_parser_4;
7335 goto basic_json_parser_9;
7341 goto basic_json_parser_4;
7345 goto basic_json_parser_10;
7347 goto basic_json_parser_12;
7356 goto basic_json_parser_4;
7360 goto basic_json_parser_13;
7362 goto basic_json_parser_15;
7368 goto basic_json_parser_17;
7372 goto basic_json_parser_19;
7374 goto basic_json_parser_4;
7386 goto basic_json_parser_21;
7390 goto basic_json_parser_4;
7392 goto basic_json_parser_23;
7398 goto basic_json_parser_24;
7402 goto basic_json_parser_4;
7404 goto basic_json_parser_25;
7413 goto basic_json_parser_26;
7415 goto basic_json_parser_4;
7421 goto basic_json_parser_28;
7425 goto basic_json_parser_30;
7427 goto basic_json_parser_4;
7431 basic_json_parser_2:
7434 return token_type::end_of_input;
7436 basic_json_parser_4:
7438 basic_json_parser_5:
7440 return token_type::parse_error;
7442 basic_json_parser_6:
7444 if (m_limit <= m_cursor)
7449 if (yybm[0 + yych] & 32)
7451 goto basic_json_parser_6;
7456 basic_json_parser_9:
7458 yych = *(m_marker = ++m_cursor);
7461 goto basic_json_parser_5;
7463 goto basic_json_parser_32;
7464 basic_json_parser_10:
7467 return token_type::value_separator;
7469 basic_json_parser_12:
7473 goto basic_json_parser_5;
7477 goto basic_json_parser_13;
7481 goto basic_json_parser_15;
7483 goto basic_json_parser_5;
7484 basic_json_parser_13:
7486 yych = *(m_marker = ++m_cursor);
7491 goto basic_json_parser_37;
7498 goto basic_json_parser_38;
7502 goto basic_json_parser_38;
7505 basic_json_parser_14:
7507 return token_type::value_number;
7509 basic_json_parser_15:
7511 m_marker = ++m_cursor;
7512 if ((m_limit - m_cursor) < 3)
7517 if (yybm[0 + yych] & 64)
7519 goto basic_json_parser_15;
7525 goto basic_json_parser_37;
7527 goto basic_json_parser_14;
7533 goto basic_json_parser_38;
7537 goto basic_json_parser_38;
7539 goto basic_json_parser_14;
7541 basic_json_parser_17:
7544 return token_type::name_separator;
7546 basic_json_parser_19:
7549 return token_type::begin_array;
7551 basic_json_parser_21:
7554 return token_type::end_array;
7556 basic_json_parser_23:
7558 yych = *(m_marker = ++m_cursor);
7561 goto basic_json_parser_39;
7563 goto basic_json_parser_5;
7564 basic_json_parser_24:
7566 yych = *(m_marker = ++m_cursor);
7569 goto basic_json_parser_40;
7571 goto basic_json_parser_5;
7572 basic_json_parser_25:
7574 yych = *(m_marker = ++m_cursor);
7577 goto basic_json_parser_41;
7579 goto basic_json_parser_5;
7580 basic_json_parser_26:
7583 return token_type::begin_object;
7585 basic_json_parser_28:
7588 return token_type::end_object;
7590 basic_json_parser_30:
7592 yych = *(m_marker = ++m_cursor);
7595 goto basic_json_parser_42;
7597 goto basic_json_parser_5;
7598 basic_json_parser_31:
7600 if (m_limit <= m_cursor)
7605 basic_json_parser_32:
7606 if (yybm[0 + yych] & 128)
7608 goto basic_json_parser_31;
7612 goto basic_json_parser_33;
7616 goto basic_json_parser_34;
7618 goto basic_json_parser_36;
7619 basic_json_parser_33:
7620 m_cursor = m_marker;
7623 goto basic_json_parser_5;
7627 goto basic_json_parser_14;
7629 basic_json_parser_34:
7632 return token_type::value_string;
7634 basic_json_parser_36:
7636 if (m_limit <= m_cursor)
7647 goto basic_json_parser_31;
7651 goto basic_json_parser_33;
7653 goto basic_json_parser_31;
7661 goto basic_json_parser_33;
7663 goto basic_json_parser_31;
7669 goto basic_json_parser_31;
7671 goto basic_json_parser_33;
7681 goto basic_json_parser_31;
7685 goto basic_json_parser_31;
7687 goto basic_json_parser_33;
7695 goto basic_json_parser_31;
7697 goto basic_json_parser_33;
7703 goto basic_json_parser_31;
7707 goto basic_json_parser_43;
7709 goto basic_json_parser_33;
7713 basic_json_parser_37:
7717 goto basic_json_parser_33;
7721 goto basic_json_parser_44;
7723 goto basic_json_parser_33;
7724 basic_json_parser_38:
7730 goto basic_json_parser_46;
7732 goto basic_json_parser_33;
7738 goto basic_json_parser_46;
7742 goto basic_json_parser_33;
7746 goto basic_json_parser_47;
7748 goto basic_json_parser_33;
7750 basic_json_parser_39:
7754 goto basic_json_parser_49;
7756 goto basic_json_parser_33;
7757 basic_json_parser_40:
7761 goto basic_json_parser_50;
7763 goto basic_json_parser_33;
7764 basic_json_parser_41:
7768 goto basic_json_parser_51;
7770 goto basic_json_parser_33;
7771 basic_json_parser_42:
7775 goto basic_json_parser_52;
7777 goto basic_json_parser_33;
7778 basic_json_parser_43:
7780 if (m_limit <= m_cursor)
7789 goto basic_json_parser_33;
7793 goto basic_json_parser_54;
7795 goto basic_json_parser_33;
7801 goto basic_json_parser_54;
7805 goto basic_json_parser_33;
7809 goto basic_json_parser_54;
7811 goto basic_json_parser_33;
7813 basic_json_parser_44:
7815 m_marker = ++m_cursor;
7816 if ((m_limit - m_cursor) < 3)
7825 goto basic_json_parser_14;
7829 goto basic_json_parser_44;
7831 goto basic_json_parser_14;
7837 goto basic_json_parser_38;
7841 goto basic_json_parser_38;
7843 goto basic_json_parser_14;
7845 basic_json_parser_46:
7849 goto basic_json_parser_33;
7853 goto basic_json_parser_33;
7855 basic_json_parser_47:
7857 if (m_limit <= m_cursor)
7864 goto basic_json_parser_14;
7868 goto basic_json_parser_47;
7870 goto basic_json_parser_14;
7871 basic_json_parser_49:
7875 goto basic_json_parser_55;
7877 goto basic_json_parser_33;
7878 basic_json_parser_50:
7882 goto basic_json_parser_56;
7884 goto basic_json_parser_33;
7885 basic_json_parser_51:
7889 goto basic_json_parser_58;
7891 goto basic_json_parser_33;
7892 basic_json_parser_52:
7897 basic_json_parser_54:
7899 if (m_limit <= m_cursor)
7908 goto basic_json_parser_33;
7912 goto basic_json_parser_60;
7914 goto basic_json_parser_33;
7920 goto basic_json_parser_60;
7924 goto basic_json_parser_33;
7928 goto basic_json_parser_60;
7930 goto basic_json_parser_33;
7932 basic_json_parser_55:
7936 goto basic_json_parser_61;
7938 goto basic_json_parser_33;
7939 basic_json_parser_56:
7942 return token_type::literal_null;
7944 basic_json_parser_58:
7947 return token_type::literal_true;
7949 basic_json_parser_60:
7951 if (m_limit <= m_cursor)
7960 goto basic_json_parser_33;
7964 goto basic_json_parser_63;
7966 goto basic_json_parser_33;
7972 goto basic_json_parser_63;
7976 goto basic_json_parser_33;
7980 goto basic_json_parser_63;
7982 goto basic_json_parser_33;
7984 basic_json_parser_61:
7987 return token_type::literal_false;
7989 basic_json_parser_63:
7991 if (m_limit <= m_cursor)
8000 goto basic_json_parser_33;
8004 goto basic_json_parser_31;
8006 goto basic_json_parser_33;
8012 goto basic_json_parser_31;
8016 goto basic_json_parser_33;
8020 goto basic_json_parser_31;
8022 goto basic_json_parser_33;
8029 void yyfill() noexcept
8031 if (m_stream ==
nullptr or not * m_stream)
8036 const auto offset_start = m_start - m_content;
8037 const auto offset_marker = m_marker - m_start;
8038 const auto offset_cursor = m_cursor - m_start;
8040 m_buffer.erase(0, static_cast<size_t>(offset_start));
8042 assert(m_stream !=
nullptr);
8043 std::getline(*m_stream, line);
8044 m_buffer +=
"\n" + line;
8046 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
8047 assert(m_content !=
nullptr);
8048 m_start = m_content;
8049 m_marker = m_start + offset_marker;
8050 m_cursor = m_start + offset_cursor;
8051 m_limit = m_start + m_buffer.size() - 1;
8057 assert(m_start !=
nullptr);
8058 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
8059 static_cast<size_t>(m_cursor - m_start));
8086 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8089 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8145 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8146 4).c_str(),
nullptr, 16);
8149 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8152 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8154 throw std::invalid_argument(
"missing low surrogate");
8158 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8159 (i + 7), 4).c_str(),
nullptr, 16);
8160 result += to_unicode(codepoint, codepoint2);
8167 result += to_unicode(codepoint);
8179 result.append(1, static_cast<typename string_t::value_type>(*i));
8206 long double str_to_float_t(
long double* ,
char** endptr)
const
8208 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8226 double str_to_float_t(
double* ,
char** endptr)
const
8228 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8246 float str_to_float_t(
float* ,
char** endptr)
const
8248 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8263 template <
typename T_A,
typename T_B>
8264 static bool attempt_cast(T_A source, T_B& dest)
8266 dest =
static_cast<T_B
>(source);
8267 return (source == static_cast<T_A>(dest));
8308 void get_number(basic_json& result)
const
8310 typename string_t::value_type* endptr;
8311 assert(m_start !=
nullptr);
8316 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8320 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8321 10), result.m_value.number_unsigned))
8335 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8336 10), result.m_value.number_integer))
8349 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8361 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8364 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8366 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8373 std::istream* m_stream =
nullptr;
8377 const lexer_char_t* m_content =
nullptr;
8379 const lexer_char_t* m_start =
nullptr;
8381 const lexer_char_t* m_marker =
nullptr;
8383 const lexer_char_t* m_cursor =
nullptr;
8385 const lexer_char_t* m_limit =
nullptr;
8398 : callback(cb), m_lexer(s)
8406 : callback(cb), m_lexer(&_is)
8415 basic_json result = parse_internal(
true);
8417 expect(lexer::token_type::end_of_input);
8421 return result.is_discarded() ?
basic_json() : result;
8426 basic_json parse_internal(
bool keep)
8432 case lexer::token_type::begin_object:
8445 if (last_token == lexer::token_type::end_object)
8456 unexpect(lexer::token_type::value_separator);
8462 if (last_token == lexer::token_type::value_separator)
8468 expect(lexer::token_type::value_string);
8469 const auto key = m_lexer.get_string();
8471 bool keep_tag =
false;
8487 expect(lexer::token_type::name_separator);
8491 auto value = parse_internal(keep);
8492 if (keep and keep_tag and not
value.is_discarded())
8494 result[key] = std::move(
value);
8497 while (last_token == lexer::token_type::value_separator);
8500 expect(lexer::token_type::end_object);
8510 case lexer::token_type::begin_array:
8523 if (last_token == lexer::token_type::end_array)
8534 unexpect(lexer::token_type::value_separator);
8540 if (last_token == lexer::token_type::value_separator)
8546 auto value = parse_internal(keep);
8547 if (keep and not
value.is_discarded())
8549 result.push_back(std::move(
value));
8552 while (last_token == lexer::token_type::value_separator);
8555 expect(lexer::token_type::end_array);
8565 case lexer::token_type::literal_null:
8572 case lexer::token_type::value_string:
8574 const auto s = m_lexer.get_string();
8580 case lexer::token_type::literal_true:
8584 result.m_value =
true;
8588 case lexer::token_type::literal_false:
8592 result.m_value =
false;
8596 case lexer::token_type::value_number:
8598 m_lexer.get_number(result);
8606 unexpect(last_token);
8618 typename lexer::token_type get_token() noexcept
8620 last_token = m_lexer.scan();
8624 void expect(
typename lexer::token_type t)
const
8626 if (t != last_token)
8628 std::string error_msg =
"parse error - unexpected ";
8629 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8630 lexer::token_type_name(last_token));
8631 error_msg +=
"; expected " + lexer::token_type_name(t);
8632 throw std::invalid_argument(error_msg);
8636 void unexpect(
typename lexer::token_type t)
const
8638 if (t == last_token)
8640 std::string error_msg =
"parse error - unexpected ";
8641 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8642 lexer::token_type_name(last_token));
8643 throw std::invalid_argument(error_msg);
8653 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8691 is_nothrow_move_constructible<nlohmann::json>::value and
8692 is_nothrow_move_assignable<nlohmann::json>::value
8710 const auto& h = hash<nlohmann::json::string_t>();
8728 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8734 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
8735 #pragma GCC diagnostic pop
the parser read ] and finished processing a JSON array
const_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:6683
iterator operator++(int)
post-increment (it++)
Definition: json.hpp:6877
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:6943
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:3112
iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:6907
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
Definition: json.hpp:6677
const_iterator()=default
default constructor
void swap(string_t &other)
exchanges the values
Definition: json.hpp:5129
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4183
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:4552
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:202
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:4934
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:6297
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:6303
bool operator>(const const_iterator &other) const
comparison: greater than
Definition: json.hpp:6671
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2171
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:7033
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:4825
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:5400
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:3595
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:205
iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:6900
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:6979
const_iterator(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:6309
number value (unsigned integer)
const_reference front() const
access the first element
Definition: json.hpp:3632
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2144
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
Definition: json.hpp:1003
pointer operator->()
dereference the iterator
Definition: json.hpp:6871
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:210
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:4723
basic_json(const number_float_t val) noexcept
create a floating-point number (explicit)
Definition: json.hpp:1417
const_reference back() const
access the last element
Definition: json.hpp:3676
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4213
a class to store JSON values
Definition: json.hpp:174
iterator & operator=(iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
Definition: json.hpp:6853
basic_json(const CompatibleStringType &val)
create a string (implicit)
Definition: json.hpp:1212
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:1738
basic_json(std::istream &i, parser_callback_t cb=nullptr)
construct a JSON value given an input stream
Definition: json.hpp:1845
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:2423
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:2889
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:5582
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:2302
InteratorType erase(InteratorType pos)
remove element given an iterator
Definition: json.hpp:3734
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:6987
iterator(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:6843
a mutable random access iterator for the basic_json class
Definition: json.hpp:6832
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:2352
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:2874
Definition: json.hpp:8681
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
Definition: json.hpp:334
iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:6914
const_iterator & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:6711
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:4486
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:3342
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:1983
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:235
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:2374
basic_json()=default
create a null object (implicitly)
const_iterator & operator=(const_iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
Definition: json.hpp:6370
pointer operator->() const
dereference the iterator
Definition: json.hpp:6490
const_iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:6725
basic_json(const CompatibleObjectType &val)
create an object (implicit)
Definition: json.hpp:1061
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
Definition: json.hpp:1463
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
Definition: json.hpp:5309
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:5030
reference value() const
return the value of an iterator
Definition: json.hpp:6808
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:4173
const_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:6562
basic_json(const int val) noexcept
create an integer number from an enum type (explicit)
Definition: json.hpp:1292
basic_json(const CompatibleArrayType &val)
create an array (implicit)
Definition: json.hpp:1128
reference back()
access the last element
Definition: json.hpp:3666
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:4280
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
Definition: json.hpp:3569
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:6757
iterator()=default
default constructor
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
Definition: json.hpp:1668
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:225
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:4747
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4375
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:664
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:6299
basic_json(const value_t value_type)
create an empty value with a given type
Definition: json.hpp:951
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:3160
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:7047
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4288
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
Definition: json.hpp:4030
a template for a reverse iterator class
Definition: json.hpp:218
basic_json(const object_t &val)
create an object (explicit)
Definition: json.hpp:1026
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:8707
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:4243
basic_json(const string_t &val)
create a string (explicit)
Definition: json.hpp:1157
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:4013
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:2245
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:7018
difference_type operator-(const const_iterator &other) const
return difference
Definition: json.hpp:6733
void swap(object_t &other)
exchanges the values
Definition: json.hpp:5095
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:453
reference operator[](T *(&key)[n])
access specified object element
Definition: json.hpp:3385
const_iterator(const iterator &other) noexcept
copy constructor given a nonconst iterator
Definition: json.hpp:6337
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:7025
namespace for Niels Lohmann
Definition: json.hpp:67
parse_event_t
JSON callback events.
Definition: json.hpp:837
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2114
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:5676
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:1692
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4346
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:902
const_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:6570
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:2396
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:197
basic_json(boolean_t val) noexcept
create a boolean (explicit)
Definition: json.hpp:1230
the parser read } and finished processing a JSON object
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:1951
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
Definition: json.hpp:1628
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:5714
basic_json(const typename string_t::value_type *val)
create a string (explicit)
Definition: json.hpp:1181
json_reverse_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:6992
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:5210
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:3064
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:5600
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:5704
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:6998
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:4797
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:207
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4367
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:4713
bool operator!=(const const_iterator &other) const
comparison: not equal
Definition: json.hpp:6629
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:3207
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4112
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
Definition: json.hpp:5362
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:6295
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4317
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:2330
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4142
array (ordered collection of values)
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:2274
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:7053
basic_json(const CompatibleNumberUnsignedType val) noexcept
create an unsigned number (implicit)
Definition: json.hpp:1388
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:2215
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:4687
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:215
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:2925
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:5523
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4251
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:524
iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:6892
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:6450
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:4852
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:4423
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:6982
bool operator==(const const_iterator &other) const
comparison: equal
Definition: json.hpp:6599
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:2193
the parser finished reading a JSON value
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:4061
iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:6921
difference_type operator-(const iterator &other) const
return difference
Definition: json.hpp:6937
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:1536
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:3502
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:213
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:227
value_t
the JSON type enumeration
Definition: json.hpp:683
reference value() const
return the value of an iterator
Definition: json.hpp:6949
iterator & operator++()
pre-increment (++it)
Definition: json.hpp:6885
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3020
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
Definition: json.hpp:1329
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:4773
string_t dump(const int indent=-1) const
serialization
Definition: json.hpp:2080
iterator operator-(difference_type i)
subtract from iterator
Definition: json.hpp:6929
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:6977
object (unordered set of name/value pairs)
the parser read { and started to process a JSON object
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:2940
friend bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:5163
number value (floating-point)
const_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:6533
basic_json(const array_t &val)
create an array (explicit)
Definition: json.hpp:1088
reference operator*()
return a reference to the value pointed to by the iterator
Definition: json.hpp:6865
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:6301
discarded by the the parser callback function
iterator(const iterator &other) noexcept
copy constructor
Definition: json.hpp:6848
the parser read a key of a value in an object
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
Definition: json.hpp:3420
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
Definition: json.hpp:4992
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:7011
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:3929
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:3967
void clear() noexcept
clears the contents
Definition: json.hpp:4611
a const random access iterator for the basic_json class
Definition: json.hpp:6288
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:596
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:6793
const_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:6525
reference operator[](T *key)
access specified object element
Definition: json.hpp:3453
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
Definition: json.hpp:5371
bool operator<=(const const_iterator &other) const
comparison: less than or equal
Definition: json.hpp:6665
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:5501
bool operator<(const const_iterator &other) const
comparison: smaller
Definition: json.hpp:6635
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:5545
const_iterator operator+(difference_type i)
add to iterator
Definition: json.hpp:6717
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:5668
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:5339
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4102
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
Definition: json.hpp:3842
StringType string_t
a type for a string
Definition: json.hpp:427
reference front()
access the first element
Definition: json.hpp:3624
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:4881
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
Definition: json.hpp:5318
value_type & reference
the type of an element reference
Definition: json.hpp:200
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:1876
the parser read [ and started to process a JSON array
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
Definition: json.hpp:380
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:7041
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:3253
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
Definition: json.hpp:5639
json_reverse_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:7005
~basic_json()
destructor
Definition: json.hpp:2011
const_iterator(const const_iterator &other) noexcept
copy constructor
Definition: json.hpp:6365
void swap(array_t &other)
exchanges the values
Definition: json.hpp:5061
reference value() const
return the value of an iterator
Definition: json.hpp:7060
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:3294