38 #ifndef NLOHMANN_JSON_HPP 39 #define NLOHMANN_JSON_HPP 48 #include <initializer_list> 57 #include <type_traits> 64 #include <sys/types.h> 71 using ssize_t = SSIZE_T;
94 struct has_mapped_type
97 template<
typename C>
static char test(
typename C::mapped_type*);
98 template<
typename C>
static char (&test(...))[2];
100 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
105 static bool approx(
const T a,
const T b)
107 return not (a > b or a < b);
180 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
181 template<
typename U,
typename... Args>
class ArrayType = std::vector,
182 class StringType = std::string,
183 class BooleanType = bool,
184 class NumberIntegerType = int64_t,
185 class NumberFloatType = double,
186 template<
typename U>
class AllocatorType = std::allocator
228 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
230 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
337 using object_t = ObjectType<StringType,
339 std::less<StringType>,
340 AllocatorType<std::pair<
const StringType,
387 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
627 template<
typename T,
typename... Args>
628 static T* create(Args&& ... args)
630 AllocatorType<T> alloc;
631 auto deleter = [&](T * object)
633 alloc.deallocate(
object, 1);
635 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
636 alloc.construct(
object.
get(), std::forward<Args>(args)...);
637 return object.release();
667 json_value() noexcept =
default;
669 json_value(
boolean_t v) noexcept : boolean(v) {}
679 case value_t::object:
681 object = create<object_t>();
687 array = create<array_t>();
691 case value_t::string:
693 string = create<string_t>(
"");
697 case value_t::boolean:
703 case value_t::number_integer:
709 case value_t::number_float:
725 string = create<string_t>(value);
731 object = create<object_t>(value);
735 json_value(
const array_t& value)
737 array = create<array_t>(value);
820 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
868 : m_type(value_type), m_value(value_type)
890 basic_json() noexcept =
default;
935 : m_type(
value_t::object), m_value(val)
961 template <
class CompatibleObjectType,
typename 963 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
964 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
971 m_value.object = create<object_t>(begin(val), end(val));
994 : m_type(
value_t::array), m_value(val)
1020 template <
class CompatibleArrayType,
typename 1022 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1023 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1024 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1025 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1026 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1027 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1028 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1035 m_value.array = create<array_t>(begin(val), end(val));
1060 : m_type(
value_t::string), m_value(val)
1110 template <
class CompatibleStringType,
typename 1112 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1133 : m_type(
value_t::boolean), m_value(val)
1161 template<
typename T,
1162 typename std::enable_if<
1163 not (std::is_same<T, int>::value)
1164 and std::is_same<T, number_integer_t>::value
1167 : m_type(
value_t::number_integer), m_value(val)
1196 : m_type(
value_t::number_integer),
1225 template<
typename CompatibleNumberIntegerType,
typename 1227 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1228 std::numeric_limits<CompatibleNumberIntegerType>::is_integer, CompatibleNumberIntegerType>::type
1231 : m_type(value_t::number_integer),
1232 m_value(static_cast<number_integer_t>(val))
1260 : m_type(
value_t::number_float), m_value(val)
1263 if (not std::isfinite(val))
1265 m_type = value_t::null;
1266 m_value = json_value();
1300 template<
typename CompatibleNumberFloatType,
typename =
typename 1302 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1303 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1379 bool type_deduction =
true,
1380 value_t manual_type = value_t::array)
1383 bool is_an_object =
true;
1387 for (
const auto& element : init)
1389 if (not element.is_array() or element.size() != 2
1390 or not element[0].is_string())
1394 is_an_object =
false;
1400 if (not type_deduction)
1403 if (manual_type == value_t::array)
1405 is_an_object =
false;
1409 if (manual_type == value_t::object and not is_an_object)
1411 throw std::domain_error(
"cannot create object from initializer list");
1418 m_type = value_t::object;
1419 m_value = value_t::object;
1421 assert(m_value.object !=
nullptr);
1423 for (
auto& element : init)
1425 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1431 m_type = value_t::array;
1432 m_value.array = create<array_t>(std::move(init));
1470 static basic_json
array(std::initializer_list<basic_json> init =
1471 std::initializer_list<basic_json>())
1473 return basic_json(init,
false, value_t::array);
1510 static basic_json
object(std::initializer_list<basic_json> init =
1511 std::initializer_list<basic_json>())
1513 return basic_json(init,
false, value_t::object);
1537 m_value.array = create<array_t>(cnt, val);
1574 template <
class InputIT,
typename 1576 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1577 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1580 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1583 if (first.m_object != last.m_object)
1585 throw std::domain_error(
"iterators are not compatible");
1591 case value_t::boolean:
1592 case value_t::number_float:
1593 case value_t::number_integer:
1594 case value_t::string:
1596 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1598 throw std::out_of_range(
"iterators out of range");
1611 case value_t::number_integer:
1613 assert(first.m_object !=
nullptr);
1614 m_value.number_integer = first.m_object->m_value.number_integer;
1618 case value_t::number_float:
1620 assert(first.m_object !=
nullptr);
1621 m_value.number_float = first.m_object->m_value.number_float;
1625 case value_t::boolean:
1627 assert(first.m_object !=
nullptr);
1628 m_value.boolean = first.m_object->m_value.boolean;
1632 case value_t::string:
1634 assert(first.m_object !=
nullptr);
1635 m_value = *first.m_object->m_value.string;
1639 case value_t::object:
1641 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1645 case value_t::array:
1647 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1653 assert(first.m_object !=
nullptr);
1654 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1684 : m_type(other.m_type)
1688 case value_t::object:
1690 assert(other.m_value.object !=
nullptr);
1691 m_value = *other.m_value.object;
1695 case value_t::array:
1697 assert(other.m_value.array !=
nullptr);
1698 m_value = *other.m_value.array;
1702 case value_t::string:
1704 assert(other.m_value.string !=
nullptr);
1705 m_value = *other.m_value.string;
1709 case value_t::boolean:
1711 m_value = other.m_value.boolean;
1715 case value_t::number_integer:
1717 m_value = other.m_value.number_integer;
1721 case value_t::number_float:
1723 m_value = other.m_value.number_float;
1753 : m_type(
std::move(other.m_type)),
1754 m_value(
std::move(other.m_value))
1757 other.m_type = value_t::null;
1783 std::is_nothrow_move_constructible<value_t>::value and
1784 std::is_nothrow_move_assignable<value_t>::value and
1785 std::is_nothrow_move_constructible<json_value>::value and
1786 std::is_nothrow_move_assignable<json_value>::value
1790 swap(m_type, other.m_type);
1791 swap(m_value, other.m_value);
1812 case value_t::object:
1814 AllocatorType<object_t> alloc;
1815 alloc.destroy(m_value.object);
1816 alloc.deallocate(m_value.object, 1);
1820 case value_t::array:
1822 AllocatorType<array_t> alloc;
1823 alloc.destroy(m_value.array);
1824 alloc.deallocate(m_value.array, 1);
1828 case value_t::string:
1830 AllocatorType<string_t> alloc;
1831 alloc.destroy(m_value.string);
1832 alloc.deallocate(m_value.string, 1);
1879 std::stringstream ss;
1883 dump(ss,
true, static_cast<unsigned int>(indent));
1931 return is_null() or is_string() or is_boolean() or is_number();
1951 return is_array() or is_object();
1970 return m_type == value_t::null;
1989 return m_type == value_t::boolean;
2013 return is_number_integer() or is_number_float();
2036 return m_type == value_t::number_integer;
2059 return m_type == value_t::number_float;
2078 return m_type == value_t::object;
2097 return m_type == value_t::array;
2116 return m_type == value_t::string;
2140 return m_type == value_t::discarded;
2171 template <
class T,
typename 2173 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2174 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2176 T get_impl(T*)
const 2180 assert(m_value.object !=
nullptr);
2181 return T(m_value.object->begin(), m_value.object->end());
2185 throw std::domain_error(
"type must be object, but is " + type_name());
2194 assert(m_value.object !=
nullptr);
2195 return *(m_value.object);
2199 throw std::domain_error(
"type must be object, but is " + type_name());
2204 template <
class T,
typename 2206 std::is_convertible<basic_json_t, typename T::value_type>::value and
2207 not std::is_same<basic_json_t, typename T::value_type>::value and
2208 not std::is_arithmetic<T>::value and
2209 not std::is_convertible<std::string, T>::value and
2210 not has_mapped_type<T>::value
2212 T get_impl(T*)
const 2217 assert(m_value.array !=
nullptr);
2218 std::transform(m_value.array->begin(), m_value.array->end(),
2219 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2221 return i.
get<
typename T::value_type>();
2227 throw std::domain_error(
"type must be array, but is " + type_name());
2232 template <
class T,
typename 2234 std::is_convertible<basic_json_t, T>::value and
2235 not std::is_same<basic_json_t, T>::value
2237 std::vector<T> get_impl(std::vector<T>*)
const 2241 std::vector<T> to_vector;
2242 assert(m_value.array !=
nullptr);
2243 to_vector.reserve(m_value.array->size());
2244 std::transform(m_value.array->begin(), m_value.array->end(),
2245 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2253 throw std::domain_error(
"type must be array, but is " + type_name());
2258 template <
class T,
typename 2260 std::is_same<basic_json, typename T::value_type>::value and
2261 not has_mapped_type<T>::value
2263 T get_impl(T*)
const 2267 assert(m_value.array !=
nullptr);
2268 return T(m_value.array->begin(), m_value.array->end());
2272 throw std::domain_error(
"type must be array, but is " + type_name());
2281 assert(m_value.array !=
nullptr);
2282 return *(m_value.array);
2286 throw std::domain_error(
"type must be array, but is " + type_name());
2291 template <
typename T,
typename 2293 std::is_convertible<string_t, T>::value
2295 T get_impl(T*)
const 2299 assert(m_value.string !=
nullptr);
2300 return *m_value.string;
2304 throw std::domain_error(
"type must be string, but is " + type_name());
2309 template<
typename T,
typename 2311 std::is_arithmetic<T>::value
2313 T get_impl(T*)
const 2317 case value_t::number_integer:
2319 return static_cast<T
>(m_value.number_integer);
2322 case value_t::number_float:
2324 return static_cast<T
>(m_value.number_float);
2329 throw std::domain_error(
"type must be number, but is " + type_name());
2339 return m_value.boolean;
2343 throw std::domain_error(
"type must be boolean, but is " + type_name());
2350 return is_object() ? m_value.object :
nullptr;
2356 return is_object() ? m_value.object :
nullptr;
2362 return is_array() ? m_value.array :
nullptr;
2368 return is_array() ? m_value.array :
nullptr;
2374 return is_string() ? m_value.string :
nullptr;
2380 return is_string() ? m_value.string :
nullptr;
2386 return is_boolean() ? &m_value.boolean :
nullptr;
2392 return is_boolean() ? &m_value.boolean :
nullptr;
2398 return is_number_integer() ? &m_value.number_integer :
nullptr;
2404 return is_number_integer() ? &m_value.number_integer :
nullptr;
2410 return is_number_float() ? &m_value.number_float :
nullptr;
2416 return is_number_float() ? &m_value.number_float :
nullptr;
2430 template<
typename ReferenceType,
typename ThisType>
2431 static ReferenceType get_ref_impl(ThisType& obj)
2434 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2435 auto ptr = obj.template get_ptr<PointerType>();
2443 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2486 template<
typename ValueType,
typename 2488 not std::is_pointer<ValueType>::value
2490 ValueType
get()
const 2492 return get_impl(static_cast<ValueType*>(
nullptr));
2521 template<
typename PointerType,
typename 2523 std::is_pointer<PointerType>::value
2525 PointerType
get() noexcept
2528 return get_ptr<PointerType>();
2535 template<
typename PointerType,
typename 2537 std::is_pointer<PointerType>::value
2539 const PointerType
get()
const noexcept
2542 return get_ptr<PointerType>();
2570 template<
typename PointerType,
typename 2572 std::is_pointer<PointerType>::value
2577 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2584 template<
typename PointerType,
typename 2586 std::is_pointer<PointerType>::value
2587 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2592 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2621 template<
typename ReferenceType,
typename 2623 std::is_reference<ReferenceType>::value
2628 return get_ref_impl<ReferenceType>(*this);
2635 template<
typename ReferenceType,
typename 2637 std::is_reference<ReferenceType>::value
2638 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2643 return get_ref_impl<ReferenceType>(*this);
2674 template <
typename ValueType,
typename 2676 not std::is_pointer<ValueType>::value
2677 and not std::is_same<ValueType, typename string_t::value_type>::value
2678 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2679 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2682 operator ValueType()
const 2685 return get<ValueType>();
2727 assert(m_value.array !=
nullptr);
2728 return m_value.array->at(idx);
2730 catch (std::out_of_range&)
2733 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2738 throw std::domain_error(
"cannot use at() with " + type_name());
2771 assert(m_value.array !=
nullptr);
2772 return m_value.array->at(idx);
2774 catch (std::out_of_range&)
2777 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2782 throw std::domain_error(
"cannot use at() with " + type_name());
2819 assert(m_value.object !=
nullptr);
2820 return m_value.object->at(key);
2822 catch (std::out_of_range&)
2825 throw std::out_of_range(
"key '" + key +
"' not found");
2830 throw std::domain_error(
"cannot use at() with " + type_name());
2867 assert(m_value.object !=
nullptr);
2868 return m_value.object->at(key);
2870 catch (std::out_of_range&)
2873 throw std::out_of_range(
"key '" + key +
"' not found");
2878 throw std::domain_error(
"cannot use at() with " + type_name());
2912 m_type = value_t::array;
2913 m_value.
array = create<array_t>();
2919 assert(m_value.array !=
nullptr);
2920 for (
size_t i = m_value.array->size(); i <= idx; ++i)
2922 m_value.array->push_back(basic_json());
2925 return m_value.array->operator[](idx);
2929 throw std::domain_error(
"cannot use operator[] with " + type_name());
2957 assert(m_value.array !=
nullptr);
2958 return m_value.array->operator[](idx);
2962 throw std::domain_error(
"cannot use operator[] with " + type_name());
2998 m_type = value_t::object;
2999 m_value.
object = create<object_t>();
3005 assert(m_value.object !=
nullptr);
3006 return m_value.object->operator[](key);
3010 throw std::domain_error(
"cannot use operator[] with " + type_name());
3046 assert(m_value.object !=
nullptr);
3047 assert(m_value.object->find(key) != m_value.object->end());
3048 return m_value.object->find(key)->second;
3052 throw std::domain_error(
"cannot use operator[] with " + type_name());
3083 template<
typename T, std::
size_t n>
3086 return operator[](static_cast<const T>(key));
3118 template<
typename T, std::
size_t n>
3121 return operator[](static_cast<const T>(key));
3151 template<
typename T>
3157 m_type = value_t::object;
3158 m_value = value_t::object;
3164 assert(m_value.object !=
nullptr);
3165 return m_value.object->operator[](key);
3169 throw std::domain_error(
"cannot use operator[] with " + type_name());
3200 template<
typename T>
3206 assert(m_value.object !=
nullptr);
3207 assert(m_value.object->find(key) != m_value.object->end());
3208 return m_value.object->find(key)->second;
3212 throw std::domain_error(
"cannot use operator[] with " + type_name());
3264 template <
class ValueType,
typename 3266 std::is_convertible<basic_json_t, ValueType>::value
3268 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3274 const auto it = find(key);
3281 return default_value;
3286 throw std::domain_error(
"cannot use value() with " + type_name());
3294 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3296 return value(key,
string_t(default_value));
3414 template <
class InteratorType,
typename 3416 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3417 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3423 if (
this != pos.m_object)
3425 throw std::domain_error(
"iterator does not fit current value");
3428 InteratorType result = end();
3432 case value_t::boolean:
3433 case value_t::number_float:
3434 case value_t::number_integer:
3435 case value_t::string:
3437 if (not pos.m_it.primitive_iterator.is_begin())
3439 throw std::out_of_range(
"iterator out of range");
3444 delete m_value.string;
3445 m_value.string =
nullptr;
3448 m_type = value_t::null;
3452 case value_t::object:
3454 assert(m_value.object !=
nullptr);
3455 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3459 case value_t::array:
3461 assert(m_value.array !=
nullptr);
3462 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3468 throw std::domain_error(
"cannot use erase() with " + type_name());
3519 template <
class InteratorType,
typename 3521 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3522 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3525 InteratorType
erase(InteratorType first, InteratorType last)
3528 if (
this != first.m_object or
this != last.m_object)
3530 throw std::domain_error(
"iterators do not fit current value");
3533 InteratorType result = end();
3537 case value_t::boolean:
3538 case value_t::number_float:
3539 case value_t::number_integer:
3540 case value_t::string:
3542 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3544 throw std::out_of_range(
"iterators out of range");
3549 delete m_value.string;
3550 m_value.string =
nullptr;
3553 m_type = value_t::null;
3557 case value_t::object:
3559 assert(m_value.object !=
nullptr);
3560 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3561 last.m_it.object_iterator);
3565 case value_t::array:
3567 assert(m_value.array !=
nullptr);
3568 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3569 last.m_it.array_iterator);
3575 throw std::domain_error(
"cannot use erase() with " + type_name());
3613 assert(m_value.object !=
nullptr);
3614 return m_value.object->erase(key);
3618 throw std::domain_error(
"cannot use erase() with " + type_name());
3653 throw std::out_of_range(
"index out of range");
3656 assert(m_value.array !=
nullptr);
3657 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3661 throw std::domain_error(
"cannot use erase() with " + type_name());
3684 auto result = end();
3688 assert(m_value.object !=
nullptr);
3689 result.m_it.object_iterator = m_value.object->find(key);
3701 auto result = cend();
3705 assert(m_value.object !=
nullptr);
3706 result.m_it.object_iterator = m_value.object->find(key);
3733 assert(not is_object() or m_value.object !=
nullptr);
3734 return is_object() ? m_value.object->count(key) : 0;
3974 template<
typename IteratorType>
class iteration_proxy;
3990 return iteration_proxy<iterator>(cont);
3998 return iteration_proxy<const_iterator>(cont);
4050 case value_t::array:
4052 assert(m_value.array !=
nullptr);
4053 return m_value.array->empty();
4056 case value_t::object:
4058 assert(m_value.object !=
nullptr);
4059 return m_value.object->empty();
4108 case value_t::array:
4110 assert(m_value.array !=
nullptr);
4111 return m_value.array->size();
4114 case value_t::object:
4116 assert(m_value.object !=
nullptr);
4117 return m_value.object->size();
4164 case value_t::array:
4166 assert(m_value.array !=
nullptr);
4167 return m_value.array->max_size();
4170 case value_t::object:
4172 assert(m_value.object !=
nullptr);
4173 return m_value.object->max_size();
4223 case value_t::number_integer:
4225 m_value.number_integer = 0;
4229 case value_t::number_float:
4231 m_value.number_float = 0.0;
4235 case value_t::boolean:
4237 m_value.boolean =
false;
4241 case value_t::string:
4243 assert(m_value.string !=
nullptr);
4244 m_value.string->clear();
4248 case value_t::array:
4250 assert(m_value.array !=
nullptr);
4251 m_value.array->clear();
4255 case value_t::object:
4257 assert(m_value.object !=
nullptr);
4258 m_value.object->clear();
4292 if (not(is_null() or is_array()))
4294 throw std::domain_error(
"cannot use push_back() with " + type_name());
4300 m_type = value_t::array;
4301 m_value = value_t::array;
4305 assert(m_value.array !=
nullptr);
4306 m_value.array->push_back(std::move(val));
4308 val.m_type = value_t::null;
4317 push_back(std::move(val));
4328 if (not(is_null() or is_array()))
4330 throw std::domain_error(
"cannot use push_back() with " + type_name());
4336 m_type = value_t::array;
4337 m_value = value_t::array;
4341 assert(m_value.array !=
nullptr);
4342 m_value.array->push_back(val);
4378 if (not(is_null() or is_object()))
4380 throw std::domain_error(
"cannot use push_back() with " + type_name());
4386 m_type = value_t::object;
4387 m_value = value_t::object;
4391 assert(m_value.object !=
nullptr);
4392 m_value.object->insert(val);
4402 return operator[](val.first);
4433 if (pos.m_object !=
this)
4435 throw std::domain_error(
"iterator does not fit current value");
4440 assert(m_value.array !=
nullptr);
4441 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4446 throw std::domain_error(
"cannot use insert() with " + type_name());
4456 return insert(pos, val);
4489 if (pos.m_object !=
this)
4491 throw std::domain_error(
"iterator does not fit current value");
4496 assert(m_value.array !=
nullptr);
4497 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4502 throw std::domain_error(
"cannot use insert() with " + type_name());
4541 throw std::domain_error(
"cannot use insert() with " + type_name());
4545 if (pos.m_object !=
this)
4547 throw std::domain_error(
"iterator does not fit current value");
4550 if (first.m_object != last.m_object)
4552 throw std::domain_error(
"iterators do not fit");
4555 if (first.m_object ==
this or last.m_object ==
this)
4557 throw std::domain_error(
"passed iterators may not belong to container");
4562 assert(m_value.array !=
nullptr);
4563 result.m_it.array_iterator = m_value.array->insert(
4564 pos.m_it.array_iterator,
4565 first.m_it.array_iterator,
4566 last.m_it.array_iterator);
4599 throw std::domain_error(
"cannot use insert() with " + type_name());
4603 if (pos.m_object !=
this)
4605 throw std::domain_error(
"iterator does not fit current value");
4610 assert(m_value.array !=
nullptr);
4611 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4633 std::is_nothrow_move_constructible<value_t>::value and
4634 std::is_nothrow_move_assignable<value_t>::value and
4635 std::is_nothrow_move_constructible<json_value>::value and
4636 std::is_nothrow_move_assignable<json_value>::value
4639 std::swap(m_type, other.m_type);
4640 std::swap(m_value, other.m_value);
4668 assert(m_value.array !=
nullptr);
4669 std::swap(*(m_value.array), other);
4673 throw std::domain_error(
"cannot use swap() with " + type_name());
4702 assert(m_value.object !=
nullptr);
4703 std::swap(*(m_value.object), other);
4707 throw std::domain_error(
"cannot use swap() with " + type_name());
4736 assert(m_value.string !=
nullptr);
4737 std::swap(*(m_value.string), other);
4741 throw std::domain_error(
"cannot use swap() with " + type_name());
4767 static constexpr std::array<uint8_t, 7> order = {{
4779 if (lhs == value_t::discarded or rhs == value_t::discarded)
4784 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
4813 const auto lhs_type = lhs.type();
4814 const auto rhs_type = rhs.type();
4816 if (lhs_type == rhs_type)
4820 case value_t::array:
4822 assert(lhs.m_value.array !=
nullptr);
4823 assert(rhs.m_value.array !=
nullptr);
4824 return *lhs.m_value.array == *rhs.m_value.array;
4826 case value_t::object:
4828 assert(lhs.m_value.object !=
nullptr);
4829 assert(rhs.m_value.object !=
nullptr);
4830 return *lhs.m_value.object == *rhs.m_value.object;
4836 case value_t::string:
4838 assert(lhs.m_value.string !=
nullptr);
4839 assert(rhs.m_value.string !=
nullptr);
4840 return *lhs.m_value.string == *rhs.m_value.string;
4842 case value_t::boolean:
4844 return lhs.m_value.boolean == rhs.m_value.boolean;
4846 case value_t::number_integer:
4848 return lhs.m_value.number_integer == rhs.m_value.number_integer;
4850 case value_t::number_float:
4852 return approx(lhs.m_value.number_float, rhs.m_value.number_float);
4860 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4862 return approx(static_cast<number_float_t>(lhs.m_value.number_integer),
4863 rhs.m_value.number_float);
4865 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4867 return approx(lhs.m_value.number_float,
4868 static_cast<number_float_t>(rhs.m_value.number_integer));
4923 return not (lhs == rhs);
4955 return not v.is_null();
4984 const auto lhs_type = lhs.type();
4985 const auto rhs_type = rhs.type();
4987 if (lhs_type == rhs_type)
4991 case value_t::array:
4993 assert(lhs.m_value.array !=
nullptr);
4994 assert(rhs.m_value.array !=
nullptr);
4995 return *lhs.m_value.array < *rhs.m_value.array;
4997 case value_t::object:
4999 assert(lhs.m_value.object !=
nullptr);
5000 assert(rhs.m_value.object !=
nullptr);
5001 return *lhs.m_value.object < *rhs.m_value.object;
5007 case value_t::string:
5009 assert(lhs.m_value.string !=
nullptr);
5010 assert(rhs.m_value.string !=
nullptr);
5011 return *lhs.m_value.string < *rhs.m_value.string;
5013 case value_t::boolean:
5015 return lhs.m_value.boolean < rhs.m_value.boolean;
5017 case value_t::number_integer:
5019 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5021 case value_t::number_float:
5023 return lhs.m_value.number_float < rhs.m_value.number_float;
5031 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5034 rhs.m_value.number_float;
5036 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5038 return lhs.m_value.number_float <
5045 return operator<(lhs_type, rhs_type);
5067 return not (rhs < lhs);
5089 return not (lhs <= rhs);
5111 return not (lhs < rhs);
5146 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5149 const bool pretty_print = (o.width() > 0);
5150 const auto indentation = (pretty_print ? o.width() : 0);
5156 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5164 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5205 return parser(s, cb).
parse();
5234 return parser(i, cb).
parse();
5242 return parser(i, cb).
parse();
5270 j = parser(i).
parse();
5280 j = parser(i).
parse();
5299 case value_t::object:
5301 case value_t::array:
5303 case value_t::string:
5305 case value_t::boolean:
5307 case value_t::discarded:
5322 static std::size_t extra_space(
const string_t& s) noexcept
5324 std::size_t result = 0;
5326 for (
const auto& c : s)
5345 if (c >= 0x00 and c <= 0x1f)
5373 const auto space = extra_space(s);
5380 string_t result(s.size() + space,
'\\');
5381 std::size_t pos = 0;
5383 for (
const auto& c : s)
5390 result[pos + 1] =
'"';
5406 result[pos + 1] =
'b';
5414 result[pos + 1] =
'f';
5422 result[pos + 1] =
'n';
5430 result[pos + 1] =
'r';
5438 result[pos + 1] =
't';
5445 if (c >= 0x00 and c <= 0x1f)
5448 auto hexify = [](
const char v) ->
char 5450 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5455 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5493 void dump(std::ostream& o,
5494 const bool pretty_print,
5495 const unsigned int indent_step,
5496 const unsigned int current_indent = 0)
const 5499 unsigned int new_indent = current_indent;
5503 case value_t::object:
5505 assert(m_value.object !=
nullptr);
5507 if (m_value.object->empty())
5518 new_indent += indent_step;
5522 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5524 if (i != m_value.object->cbegin())
5526 o << (pretty_print ?
",\n" :
",");
5528 o <<
string_t(new_indent,
' ') <<
"\"" 5529 << escape_string(i->first) <<
"\":" 5530 << (pretty_print ?
" " :
"");
5531 i->second.dump(o, pretty_print, indent_step, new_indent);
5537 new_indent -= indent_step;
5541 o <<
string_t(new_indent,
' ') +
"}";
5545 case value_t::array:
5547 assert(m_value.array !=
nullptr);
5549 if (m_value.array->empty())
5560 new_indent += indent_step;
5564 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5566 if (i != m_value.array->cbegin())
5568 o << (pretty_print ?
",\n" :
",");
5571 i->dump(o, pretty_print, indent_step, new_indent);
5577 new_indent -= indent_step;
5581 o <<
string_t(new_indent,
' ') <<
"]";
5585 case value_t::string:
5587 assert(m_value.string !=
nullptr);
5588 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5592 case value_t::boolean:
5594 o << (m_value.boolean ?
"true" :
"false");
5598 case value_t::number_integer:
5600 o << m_value.number_integer;
5604 case value_t::number_float:
5609 o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
5613 case value_t::discarded:
5633 value_t m_type = value_t::null;
5636 json_value m_value = {};
5653 class primitive_iterator_t
5669 bool is_begin()
const 5671 return (m_it == begin_value);
5677 return (m_it == end_value);
5697 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5707 struct internal_iterator
5710 typename object_t::iterator object_iterator;
5712 typename array_t::iterator array_iterator;
5714 primitive_iterator_t primitive_iterator;
5718 : object_iterator(), array_iterator(), primitive_iterator()
5723 template<
typename IteratorType>
5724 class iteration_proxy
5728 class iteration_proxy_internal
5732 IteratorType anchor;
5734 size_t array_index = 0;
5737 iteration_proxy_internal(IteratorType it)
5742 iteration_proxy_internal& operator*()
5748 iteration_proxy_internal& operator++()
5757 bool operator!= (
const iteration_proxy_internal& o)
const 5759 return anchor != o.anchor;
5765 assert(anchor.m_object !=
nullptr);
5767 switch (anchor.m_object->type())
5770 case value_t::array:
5772 return std::to_string(array_index);
5776 case value_t::object:
5778 return anchor.key();
5790 typename IteratorType::reference value()
const 5792 return anchor.value();
5797 typename IteratorType::reference container;
5801 iteration_proxy(
typename IteratorType::reference cont)
5806 iteration_proxy_internal begin()
5808 return iteration_proxy_internal(container.begin());
5812 iteration_proxy_internal end()
5814 return iteration_proxy_internal(container.end());
5832 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
5835 friend class basic_json;
5855 assert(m_object !=
nullptr);
5857 switch (m_object->m_type)
5861 m_it.object_iterator =
typename object_t::iterator();
5867 m_it.array_iterator =
typename array_t::iterator();
5873 m_it.primitive_iterator = primitive_iterator_t();
5882 assert(m_object !=
nullptr);
5884 switch (m_object->m_type)
5888 m_it.object_iterator = other.m_it.object_iterator;
5894 m_it.array_iterator = other.m_it.array_iterator;
5900 m_it.primitive_iterator = other.m_it.primitive_iterator;
5908 : m_object(other.m_object), m_it(other.m_it)
5913 std::is_nothrow_move_constructible<pointer>::value and
5914 std::is_nothrow_move_assignable<pointer>::value and
5915 std::is_nothrow_move_constructible<internal_iterator>::value and
5916 std::is_nothrow_move_assignable<internal_iterator>::value
5919 std::swap(m_object, other.m_object);
5920 std::swap(m_it, other.m_it);
5928 assert(m_object !=
nullptr);
5930 switch (m_object->m_type)
5934 assert(m_object->m_value.object !=
nullptr);
5935 m_it.object_iterator = m_object->m_value.object->begin();
5941 assert(m_object->m_value.array !=
nullptr);
5942 m_it.array_iterator = m_object->m_value.array->begin();
5949 m_it.primitive_iterator.set_end();
5955 m_it.primitive_iterator.set_begin();
5964 assert(m_object !=
nullptr);
5966 switch (m_object->m_type)
5970 assert(m_object->m_value.object !=
nullptr);
5971 m_it.object_iterator = m_object->m_value.object->end();
5977 assert(m_object->m_value.array !=
nullptr);
5978 m_it.array_iterator = m_object->m_value.array->end();
5984 m_it.primitive_iterator.set_end();
5994 assert(m_object !=
nullptr);
5996 switch (m_object->m_type)
6000 assert(m_object->m_value.object);
6001 assert(m_it.object_iterator != m_object->m_value.object->end());
6002 return m_it.object_iterator->second;
6007 assert(m_object->m_value.array);
6008 assert(m_it.array_iterator != m_object->m_value.array->end());
6009 return *m_it.array_iterator;
6014 throw std::out_of_range(
"cannot get value");
6019 if (m_it.primitive_iterator.is_begin())
6025 throw std::out_of_range(
"cannot get value");
6034 assert(m_object !=
nullptr);
6036 switch (m_object->m_type)
6040 assert(m_object->m_value.object);
6041 assert(m_it.object_iterator != m_object->m_value.object->end());
6042 return &(m_it.object_iterator->second);
6047 assert(m_object->m_value.array);
6048 assert(m_it.array_iterator != m_object->m_value.array->end());
6049 return &*m_it.array_iterator;
6054 if (m_it.primitive_iterator.is_begin())
6060 throw std::out_of_range(
"cannot get value");
6069 auto result = *
this;
6077 assert(m_object !=
nullptr);
6079 switch (m_object->m_type)
6083 ++m_it.object_iterator;
6089 ++m_it.array_iterator;
6095 ++m_it.primitive_iterator;
6106 auto result = *
this;
6114 assert(m_object !=
nullptr);
6116 switch (m_object->m_type)
6120 --m_it.object_iterator;
6126 --m_it.array_iterator;
6132 --m_it.primitive_iterator;
6144 if (m_object != other.m_object)
6146 throw std::domain_error(
"cannot compare iterators of different containers");
6149 assert(m_object !=
nullptr);
6151 switch (m_object->m_type)
6155 return (m_it.object_iterator == other.m_it.object_iterator);
6160 return (m_it.array_iterator == other.m_it.array_iterator);
6165 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6173 return not operator==(other);
6180 if (m_object != other.m_object)
6182 throw std::domain_error(
"cannot compare iterators of different containers");
6185 assert(m_object !=
nullptr);
6187 switch (m_object->m_type)
6191 throw std::domain_error(
"cannot compare order of object iterators");
6196 return (m_it.array_iterator < other.m_it.array_iterator);
6201 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6209 return not other.operator < (*this);
6215 return not operator<=(other);
6221 return not operator<(other);
6227 assert(m_object !=
nullptr);
6229 switch (m_object->m_type)
6233 throw std::domain_error(
"cannot use offsets with object iterators");
6238 m_it.array_iterator += i;
6244 m_it.primitive_iterator += i;
6255 return operator+=(-i);
6261 auto result = *
this;
6269 auto result = *
this;
6277 assert(m_object !=
nullptr);
6279 switch (m_object->m_type)
6283 throw std::domain_error(
"cannot use offsets with object iterators");
6288 return m_it.array_iterator - other.m_it.array_iterator;
6293 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6301 assert(m_object !=
nullptr);
6303 switch (m_object->m_type)
6307 throw std::domain_error(
"cannot use operator[] for object iterators");
6312 return *(m_it.array_iterator + n);
6317 throw std::out_of_range(
"cannot get value");
6322 if (m_it.primitive_iterator == -n)
6328 throw std::out_of_range(
"cannot get value");
6335 typename object_t::key_type
key()
const 6337 assert(m_object !=
nullptr);
6339 if (m_object->is_object())
6341 return m_it.object_iterator->first;
6345 throw std::domain_error(
"cannot use key() for non-object iterators");
6359 internal_iterator m_it = internal_iterator();
6396 std::is_nothrow_move_constructible<pointer>::value and
6397 std::is_nothrow_move_assignable<pointer>::value and
6398 std::is_nothrow_move_constructible<internal_iterator>::value and
6399 std::is_nothrow_move_assignable<internal_iterator>::value
6402 base_iterator::operator=(other);
6409 return const_cast<reference>(base_iterator::operator*());
6415 return const_cast<pointer>(base_iterator::operator->());
6422 base_iterator::operator++();
6429 base_iterator::operator++();
6437 base_iterator::operator--();
6444 base_iterator::operator--();
6451 base_iterator::operator+=(i);
6458 base_iterator::operator-=(i);
6465 auto result = *
this;
6473 auto result = *
this;
6480 return base_iterator::operator-(other);
6486 return const_cast<reference>(base_iterator::operator[](n));
6492 return const_cast<reference>(base_iterator::value());
6513 template<
typename Base>
6535 return base_iterator::operator++(1);
6541 base_iterator::operator++();
6548 return base_iterator::operator--(1);
6554 base_iterator::operator--();
6561 base_iterator::operator+=(i);
6568 auto result = *
this;
6576 auto result = *
this;
6584 return this->base() - other.base();
6590 return *(this->operator+(n));
6594 typename object_t::key_type
key()
const 6596 auto it = --this->base();
6603 auto it = --this->base();
6604 return it.operator * ();
6625 enum class token_type
6644 using lexer_char_t =
unsigned char;
6647 explicit lexer(
const string_t& s) noexcept
6648 : m_stream(
nullptr), m_buffer(s)
6650 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6651 assert(m_content !=
nullptr);
6652 m_start = m_cursor = m_content;
6653 m_limit = m_content + s.size();
6657 explicit lexer(std::istream* s) noexcept
6658 : m_stream(s), m_buffer()
6660 assert(m_stream !=
nullptr);
6661 getline(*m_stream, m_buffer);
6662 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6663 assert(m_content !=
nullptr);
6664 m_start = m_cursor = m_content;
6665 m_limit = m_content + m_buffer.size();
6672 lexer(
const lexer&) =
delete;
6673 lexer operator=(
const lexer&) =
delete;
6690 static string_t to_unicode(
const std::size_t codepoint1,
6691 const std::size_t codepoint2 = 0)
6696 std::size_t codepoint = codepoint1;
6699 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6702 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6716 throw std::invalid_argument(
"missing or wrong low surrogate");
6720 if (codepoint < 0x80)
6723 result.append(1, static_cast<typename string_t::value_type>(codepoint));
6725 else if (codepoint <= 0x7ff)
6728 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6729 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6731 else if (codepoint <= 0xffff)
6734 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
6735 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6736 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6738 else if (codepoint <= 0x10ffff)
6741 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
6742 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
6743 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6744 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6748 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
6755 static std::string token_type_name(token_type t)
6759 case token_type::uninitialized:
6760 return "<uninitialized>";
6761 case token_type::literal_true:
6762 return "true literal";
6763 case token_type::literal_false:
6764 return "false literal";
6765 case token_type::literal_null:
6766 return "null literal";
6767 case token_type::value_string:
6768 return "string literal";
6769 case token_type::value_number:
6770 return "number literal";
6771 case token_type::begin_array:
6773 case token_type::begin_object:
6775 case token_type::end_array:
6777 case token_type::end_object:
6779 case token_type::name_separator:
6781 case token_type::value_separator:
6783 case token_type::parse_error:
6784 return "<parse error>";
6785 case token_type::end_of_input:
6786 return "end of input";
6790 return "unknown token";
6805 token_type scan() noexcept
6812 assert(m_start !=
nullptr);
6817 unsigned int yyaccept = 0;
6818 static const unsigned char yybm[] =
6820 0, 0, 0, 0, 0, 0, 0, 0,
6821 0, 32, 32, 0, 0, 32, 0, 0,
6822 64, 64, 64, 64, 64, 64, 64, 64,
6823 64, 64, 64, 64, 64, 64, 64, 64,
6824 96, 64, 0, 64, 64, 64, 64, 64,
6825 64, 64, 64, 64, 64, 64, 64, 64,
6826 192, 192, 192, 192, 192, 192, 192, 192,
6827 192, 192, 64, 64, 64, 64, 64, 64,
6828 64, 64, 64, 64, 64, 64, 64, 64,
6829 64, 64, 64, 64, 64, 64, 64, 64,
6830 64, 64, 64, 64, 64, 64, 64, 64,
6831 64, 64, 64, 64, 0, 64, 64, 64,
6832 64, 64, 64, 64, 64, 64, 64, 64,
6833 64, 64, 64, 64, 64, 64, 64, 64,
6834 64, 64, 64, 64, 64, 64, 64, 64,
6835 64, 64, 64, 64, 64, 64, 64, 64,
6836 64, 64, 64, 64, 64, 64, 64, 64,
6837 64, 64, 64, 64, 64, 64, 64, 64,
6838 64, 64, 64, 64, 64, 64, 64, 64,
6839 64, 64, 64, 64, 64, 64, 64, 64,
6840 64, 64, 64, 64, 64, 64, 64, 64,
6841 64, 64, 64, 64, 64, 64, 64, 64,
6842 64, 64, 64, 64, 64, 64, 64, 64,
6843 64, 64, 64, 64, 64, 64, 64, 64,
6844 64, 64, 64, 64, 64, 64, 64, 64,
6845 64, 64, 64, 64, 64, 64, 64, 64,
6846 64, 64, 64, 64, 64, 64, 64, 64,
6847 64, 64, 64, 64, 64, 64, 64, 64,
6848 64, 64, 64, 64, 64, 64, 64, 64,
6849 64, 64, 64, 64, 64, 64, 64, 64,
6850 64, 64, 64, 64, 64, 64, 64, 64,
6851 64, 64, 64, 64, 64, 64, 64, 64,
6853 if ((m_limit - m_cursor) < 5)
6866 goto basic_json_parser_28;
6870 goto basic_json_parser_30;
6874 goto basic_json_parser_4;
6881 goto basic_json_parser_2;
6885 goto basic_json_parser_30;
6895 goto basic_json_parser_27;
6899 goto basic_json_parser_30;
6901 goto basic_json_parser_16;
6909 goto basic_json_parser_23;
6911 goto basic_json_parser_30;
6917 goto basic_json_parser_24;
6921 goto basic_json_parser_26;
6923 goto basic_json_parser_18;
6936 goto basic_json_parser_8;
6940 goto basic_json_parser_30;
6942 goto basic_json_parser_10;
6948 goto basic_json_parser_22;
6952 goto basic_json_parser_30;
6954 goto basic_json_parser_20;
6963 goto basic_json_parser_21;
6967 goto basic_json_parser_30;
6969 goto basic_json_parser_12;
6977 goto basic_json_parser_30;
6979 goto basic_json_parser_14;
6985 goto basic_json_parser_6;
6987 goto basic_json_parser_30;
6992 basic_json_parser_2:
6995 goto basic_json_parser_5;
6996 basic_json_parser_3:
7000 basic_json_parser_4:
7002 if (m_limit <= m_cursor)
7007 basic_json_parser_5:
7008 if (yybm[0 + yych] & 32)
7010 goto basic_json_parser_4;
7012 goto basic_json_parser_3;
7013 basic_json_parser_6:
7015 yych = *(m_marker = ++m_cursor);
7018 goto basic_json_parser_64;
7020 basic_json_parser_7:
7022 return token_type::parse_error;
7024 basic_json_parser_8:
7027 return token_type::begin_array;
7029 basic_json_parser_10:
7032 return token_type::end_array;
7034 basic_json_parser_12:
7037 return token_type::begin_object;
7039 basic_json_parser_14:
7042 return token_type::end_object;
7044 basic_json_parser_16:
7047 return token_type::value_separator;
7049 basic_json_parser_18:
7052 return token_type::name_separator;
7054 basic_json_parser_20:
7056 yych = *(m_marker = ++m_cursor);
7059 goto basic_json_parser_60;
7061 goto basic_json_parser_7;
7062 basic_json_parser_21:
7064 yych = *(m_marker = ++m_cursor);
7067 goto basic_json_parser_56;
7069 goto basic_json_parser_7;
7070 basic_json_parser_22:
7072 yych = *(m_marker = ++m_cursor);
7075 goto basic_json_parser_51;
7077 goto basic_json_parser_7;
7078 basic_json_parser_23:
7082 goto basic_json_parser_7;
7086 goto basic_json_parser_50;
7090 goto basic_json_parser_41;
7092 goto basic_json_parser_7;
7093 basic_json_parser_24:
7095 yych = *(m_marker = ++m_cursor);
7100 goto basic_json_parser_43;
7107 goto basic_json_parser_44;
7111 goto basic_json_parser_44;
7114 basic_json_parser_25:
7116 return token_type::value_number;
7118 basic_json_parser_26:
7120 yych = *(m_marker = ++m_cursor);
7121 goto basic_json_parser_42;
7122 basic_json_parser_27:
7124 yych = *(m_marker = ++m_cursor);
7127 goto basic_json_parser_7;
7129 goto basic_json_parser_32;
7130 basic_json_parser_28:
7133 return token_type::end_of_input;
7135 basic_json_parser_30:
7137 goto basic_json_parser_7;
7138 basic_json_parser_31:
7140 if (m_limit <= m_cursor)
7145 basic_json_parser_32:
7146 if (yybm[0 + yych] & 64)
7148 goto basic_json_parser_31;
7152 goto basic_json_parser_33;
7156 goto basic_json_parser_35;
7158 goto basic_json_parser_34;
7159 basic_json_parser_33:
7160 m_cursor = m_marker;
7163 goto basic_json_parser_7;
7167 goto basic_json_parser_25;
7169 basic_json_parser_34:
7171 if (m_limit <= m_cursor)
7182 goto basic_json_parser_31;
7186 goto basic_json_parser_33;
7188 goto basic_json_parser_31;
7196 goto basic_json_parser_33;
7198 goto basic_json_parser_31;
7204 goto basic_json_parser_31;
7206 goto basic_json_parser_33;
7216 goto basic_json_parser_31;
7220 goto basic_json_parser_31;
7222 goto basic_json_parser_33;
7230 goto basic_json_parser_31;
7232 goto basic_json_parser_33;
7238 goto basic_json_parser_31;
7242 goto basic_json_parser_37;
7244 goto basic_json_parser_33;
7248 basic_json_parser_35:
7251 return token_type::value_string;
7253 basic_json_parser_37:
7255 if (m_limit <= m_cursor)
7264 goto basic_json_parser_33;
7268 goto basic_json_parser_33;
7275 goto basic_json_parser_38;
7279 goto basic_json_parser_33;
7283 goto basic_json_parser_33;
7286 basic_json_parser_38:
7288 if (m_limit <= m_cursor)
7297 goto basic_json_parser_33;
7301 goto basic_json_parser_33;
7308 goto basic_json_parser_39;
7312 goto basic_json_parser_33;
7316 goto basic_json_parser_33;
7319 basic_json_parser_39:
7321 if (m_limit <= m_cursor)
7330 goto basic_json_parser_33;
7334 goto basic_json_parser_33;
7341 goto basic_json_parser_40;
7345 goto basic_json_parser_33;
7349 goto basic_json_parser_33;
7352 basic_json_parser_40:
7354 if (m_limit <= m_cursor)
7363 goto basic_json_parser_33;
7367 goto basic_json_parser_31;
7369 goto basic_json_parser_33;
7375 goto basic_json_parser_31;
7379 goto basic_json_parser_33;
7383 goto basic_json_parser_31;
7385 goto basic_json_parser_33;
7387 basic_json_parser_41:
7389 m_marker = ++m_cursor;
7390 if ((m_limit - m_cursor) < 3)
7395 basic_json_parser_42:
7396 if (yybm[0 + yych] & 128)
7398 goto basic_json_parser_41;
7404 goto basic_json_parser_25;
7411 goto basic_json_parser_44;
7415 goto basic_json_parser_44;
7417 goto basic_json_parser_25;
7419 basic_json_parser_43:
7423 goto basic_json_parser_33;
7427 goto basic_json_parser_48;
7429 goto basic_json_parser_33;
7430 basic_json_parser_44:
7436 goto basic_json_parser_33;
7443 goto basic_json_parser_45;
7447 goto basic_json_parser_33;
7451 goto basic_json_parser_46;
7453 goto basic_json_parser_33;
7455 basic_json_parser_45:
7459 goto basic_json_parser_33;
7463 goto basic_json_parser_33;
7465 basic_json_parser_46:
7467 if (m_limit <= m_cursor)
7474 goto basic_json_parser_25;
7478 goto basic_json_parser_46;
7480 goto basic_json_parser_25;
7481 basic_json_parser_48:
7483 m_marker = ++m_cursor;
7484 if ((m_limit - m_cursor) < 3)
7493 goto basic_json_parser_25;
7497 goto basic_json_parser_48;
7499 goto basic_json_parser_25;
7505 goto basic_json_parser_44;
7509 goto basic_json_parser_44;
7511 goto basic_json_parser_25;
7513 basic_json_parser_50:
7515 yych = *(m_marker = ++m_cursor);
7520 goto basic_json_parser_43;
7522 goto basic_json_parser_25;
7528 goto basic_json_parser_44;
7532 goto basic_json_parser_44;
7534 goto basic_json_parser_25;
7536 basic_json_parser_51:
7540 goto basic_json_parser_33;
7545 goto basic_json_parser_33;
7550 goto basic_json_parser_33;
7554 return token_type::literal_false;
7556 basic_json_parser_56:
7560 goto basic_json_parser_33;
7565 goto basic_json_parser_33;
7569 return token_type::literal_true;
7571 basic_json_parser_60:
7575 goto basic_json_parser_33;
7580 goto basic_json_parser_33;
7584 return token_type::literal_null;
7586 basic_json_parser_64:
7590 goto basic_json_parser_33;
7602 void yyfill() noexcept
7604 if (m_stream ==
nullptr or not * m_stream)
7609 const ssize_t offset_start = m_start - m_content;
7610 const ssize_t offset_marker = m_marker - m_start;
7611 const ssize_t offset_cursor = m_cursor - m_start;
7613 m_buffer.erase(0, static_cast<size_t>(offset_start));
7615 assert(m_stream !=
nullptr);
7616 std::getline(*m_stream, line);
7617 m_buffer +=
"\n" + line;
7619 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7620 assert(m_content !=
nullptr);
7621 m_start = m_content;
7622 m_marker = m_start + offset_marker;
7623 m_cursor = m_start + offset_cursor;
7624 m_limit = m_start + m_buffer.size() - 1;
7628 string_t get_token()
const noexcept
7630 assert(m_start !=
nullptr);
7631 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7632 static_cast<size_t>(m_cursor - m_start));
7659 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7662 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7718 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7719 4).c_str(),
nullptr, 16);
7722 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7725 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7727 throw std::invalid_argument(
"missing low surrogate");
7731 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7732 (i + 7), 4).c_str(),
nullptr, 16);
7733 result += to_unicode(codepoint, codepoint2);
7740 result += to_unicode(codepoint);
7752 result.append(1, static_cast<typename string_t::value_type>(*i));
7776 long double get_number()
const 7779 typename string_t::value_type* endptr;
7780 assert(m_start !=
nullptr);
7781 const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
7786 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7791 std::istream* m_stream =
nullptr;
7795 const lexer_char_t* m_content =
nullptr;
7797 const lexer_char_t* m_start =
nullptr;
7799 const lexer_char_t* m_marker =
nullptr;
7801 const lexer_char_t* m_cursor =
nullptr;
7803 const lexer_char_t* m_limit =
nullptr;
7816 : callback(cb), m_lexer(s)
7824 : callback(cb), m_lexer(&_is)
7833 basic_json result = parse_internal(
true);
7835 expect(lexer::token_type::end_of_input);
7844 basic_json parse_internal(
bool keep)
7846 auto result = basic_json(value_t::discarded);
7850 case lexer::token_type::begin_object:
7852 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7855 result.m_type = value_t::object;
7856 result.m_value = json_value(value_t::object);
7863 if (last_token == lexer::token_type::end_object)
7866 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7868 result = basic_json(value_t::discarded);
7874 unexpect(lexer::token_type::value_separator);
7880 if (last_token == lexer::token_type::value_separator)
7886 expect(lexer::token_type::value_string);
7887 const auto key = m_lexer.get_string();
7889 bool keep_tag =
false;
7895 keep_tag = callback(depth, parse_event_t::key, k);
7905 expect(lexer::token_type::name_separator);
7909 auto value = parse_internal(keep);
7910 if (keep and keep_tag and not value.is_discarded())
7912 result[key] = std::move(value);
7915 while (last_token == lexer::token_type::value_separator);
7918 expect(lexer::token_type::end_object);
7920 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7922 result = basic_json(value_t::discarded);
7928 case lexer::token_type::begin_array:
7930 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7933 result.m_type = value_t::array;
7934 result.m_value = json_value(value_t::array);
7941 if (last_token == lexer::token_type::end_array)
7944 if (callback and not callback(--depth, parse_event_t::array_end, result))
7946 result = basic_json(value_t::discarded);
7952 unexpect(lexer::token_type::value_separator);
7958 if (last_token == lexer::token_type::value_separator)
7964 auto value = parse_internal(keep);
7965 if (keep and not value.is_discarded())
7967 result.push_back(std::move(value));
7970 while (last_token == lexer::token_type::value_separator);
7973 expect(lexer::token_type::end_array);
7975 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
7977 result = basic_json(value_t::discarded);
7983 case lexer::token_type::literal_null:
7986 result.m_type = value_t::null;
7990 case lexer::token_type::value_string:
7992 const auto s = m_lexer.get_string();
7994 result = basic_json(s);
7998 case lexer::token_type::literal_true:
8001 result.m_type = value_t::boolean;
8002 result.m_value =
true;
8006 case lexer::token_type::literal_false:
8009 result.m_type = value_t::boolean;
8010 result.m_value =
false;
8014 case lexer::token_type::value_number:
8016 auto float_val = m_lexer.get_number();
8020 if (std::isnan(float_val))
8022 throw std::invalid_argument(std::string(
"parse error - ") +
8023 m_lexer.get_token() +
" is not a number");
8030 if (approx(float_val, static_cast<long double>(int_val)))
8033 result.m_type = value_t::number_integer;
8034 result.m_value = int_val;
8039 result.m_type = value_t::number_float;
8048 unexpect(last_token);
8052 if (keep and callback and not callback(depth, parse_event_t::value, result))
8054 result = basic_json(value_t::discarded);
8060 typename lexer::token_type get_token()
8062 last_token = m_lexer.scan();
8066 void expect(
typename lexer::token_type t)
const 8068 if (t != last_token)
8070 std::string error_msg =
"parse error - unexpected ";
8071 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8072 lexer::token_type_name(last_token));
8073 error_msg +=
"; expected " + lexer::token_type_name(t);
8074 throw std::invalid_argument(error_msg);
8078 void unexpect(
typename lexer::token_type t)
const 8080 if (t == last_token)
8082 std::string error_msg =
"parse error - unexpected ";
8083 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8084 lexer::token_type_name(last_token));
8085 throw std::invalid_argument(error_msg);
8095 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8133 is_nothrow_move_constructible<nlohmann::json>::value and
8134 is_nothrow_move_assignable<nlohmann::json>::value
8152 const auto& h = hash<nlohmann::json::string_t>();
8170 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
bool operator!=(const const_iterator &other) const
comparison: not equal
iterator insert(const_iterator pos, basic_json &&val)
inserts element
iterator operator++(int)
post-increment (it++)
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
const_reference operator[](size_type idx) const
access specified array element
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
const_iterator & operator--()
pre-decrement (–it)
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
const_iterator & operator=(const_iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
reference & operator=(basic_json other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
copy assignment
const_reference operator[](T *key) const
read-only access specified object element
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
json_reverse_iterator operator--(int)
post-decrement (it–)
StringType string_t
a type for a string
void push_back(const typename object_t::value_type &val)
add an object to an object
basic_json(boolean_t val)
create a boolean (explicit)
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
iterator & operator++()
pre-increment (++it)
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
const_iterator & operator++()
pre-increment (++it)
difference_type operator-(const json_reverse_iterator &other) const
return difference
basic_json<> json
default JSON class
reference front()
access the first element
bool is_array() const noexcept
return whether value is an array
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
json_reverse_iterator(const typename base_iterator::iterator_type &it)
create reverse iterator from iterator
a class to store JSON values
json_reverse_iterator & operator--()
pre-decrement (–it)
basic_json(const object_t &val)
create an object (explicit)
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
void push_back(basic_json &&val)
add an object to an array
const_iterator cbegin() const
returns a const iterator to the first element
reference operator[](T *key)
access specified object element
bool is_string() const noexcept
return whether value is a string
iterator & operator+=(difference_type i)
add to iterator
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
basic_json(const CompatibleStringType &val)
create a string (implicit)
reference operator+=(basic_json &&val)
add an object to an array
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
a mutable random access iterator for the basic_json class
iterator & operator-=(difference_type i)
subtract from iterator
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
reference operator[](const typename object_t::key_type &key)
access specified object element
difference_type operator-(const iterator &other) const
reference value() const
return the value of an iterator
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
const_iterator end() const
returns a const iterator to one past the last element
const_iterator(const const_iterator &other) noexcept
copy constructor
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
object_t::key_type key() const
return the key of an object iterator
iterator end()
returns an iterator to one past the last element
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
reference operator*()
return a reference to the value pointed to by the iterator
reverse_iterator rend()
returns an iterator to the reverse-end
bool is_object() const noexcept
return whether value is an object
const_iterator operator-(difference_type i)
subtract from iterator
bool is_discarded() const noexcept
return whether value is discarded
basic_json(const CompatibleArrayType &val)
create an array (implicit)
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
const_reverse_iterator rend() const
returns a const reverse iterator to one before the first
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
bool is_boolean() const noexcept
return whether value is a boolean
iterator begin()
returns an iterator to the first element
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
reference operator+=(const basic_json &val)
add an object to an array
AllocatorType< basic_json > allocator_type
the allocator type
basic_json(const number_float_t val)
create a floating-point number (explicit)
reference operator[](T *(&key)[n])
access specified object element
bool is_number_integer() const noexcept
return whether value is an integer number
iterator operator+(difference_type i)
add to iterator
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
basic_json(const typename string_t::value_type *val)
create a string (explicit)
iterator find(typename object_t::key_type key)
find an element in a JSON object
basic_json(const value_t value_type)
create an empty value with a given type
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
iterator & operator--()
pre-decrement (–it)
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
pointer operator->() const
dereference the iterator
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
const_iterator cend() const
returns a const iterator to one past the last element
typename Base::reference reference
the reference type for the pointed-to element
size_type size() const noexcept
returns the number of elements
static allocator_type get_allocator()
returns the allocator associated with the container
object (unordered set of name/value pairs)
ReferenceType get_ref()
get a reference value (implicit)
reference at(size_type idx)
access specified array element with bounds checking
json_reverse_iterator(const base_iterator &it)
create reverse iterator from base class
value_t type() const noexcept
return the type of the JSON value (explicit)
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
object_t::key_type key() const
return the key of an object iterator
bool is_structured() const noexcept
return whether type is structured
namespace for Niels Lohmann
typename basic_json::difference_type difference_type
a type to represent differences between iterators
void swap(array_t &other)
exchanges the values
reverse_iterator rbegin()
returns an iterator to the reverse-beginning
reference operator+=(const typename object_t::value_type &val)
add an object to an object
basic_json(const number_integer_t val)
create an integer number (explicit)
reference operator[](difference_type n) const
access to successor
std::size_t size_type
a type to represent container sizes
const_reverse_iterator rbegin() const
returns a const reverse iterator to the last element
basic_json(const basic_json &other)
copy constructor
const_iterator operator+(difference_type i)
add to iterator
value_t
the JSON type enumeration
const value_type & const_reference
the type of an element const reference
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
ReferenceType get_ref() const
get a reference value (implicit)
bool is_null() const noexcept
return whether value is null
void swap(string_t &other)
exchanges the values
reference value() const
return the value of an iterator
const_iterator operator--(int)
post-decrement (it–)
ValueType get() const
get a value (explicit)
void erase(const size_type idx)
remove element from a JSON array given an index
void clear() noexcept
clears the contents
pointer operator->()
dereference the iterator
basic_json value_type
the type of elements in a basic_json container
array (ordered collection of values)
const_reference front() const
access the first element
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
std::ptrdiff_t difference_type
a type to represent differences between iterators
const_iterator & operator+=(difference_type i)
add to iterator
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
difference_type operator-(const const_iterator &other) const
return difference
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
bool is_number() const noexcept
return whether value is a number
BooleanType boolean_t
a type for a boolean
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
bool empty() const noexcept
checks whether the container is empty
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
void swap(reference other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
exchanges the values
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
const_reverse_iterator crbegin() const
returns a const reverse iterator to the last element
reference value() const
return the value of an iterator
const_iterator(pointer object)
constructor for a given JSON instance
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON types
iterator(pointer object) noexcept
constructor for a given JSON instance
bool operator<(const const_iterator &other) const
comparison: smaller
string_t dump(const int indent=-1) const
serialization
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
const_iterator & operator-=(difference_type i)
subtract from iterator
basic_json(const int val)
create an integer number from an enum type (explicit)
basic_json(const array_t &val)
create an array (explicit)
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
json_reverse_iterator operator++(int)
post-increment (it++)
PointerType get_ptr() noexcept
get a pointer value (implicit)
const_iterator(const iterator &other)
copy constructor given a nonconst iterator
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
InteratorType erase(InteratorType pos)
remove element given an iterator
bool operator<=(const const_iterator &other) const
comparison: less than or equal
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
reference back()
access the last element
bool is_number_float() const noexcept
return whether value is a floating-point number
const_iterator operator++(int)
post-increment (it++)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
basic_json(const string_t &val)
create a string (explicit)
iterator(const iterator &other) noexcept
copy constructor
const_reference back() const
access the last element
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
size_type max_size() const noexcept
returns the maximum possible number of elements
void push_back(const basic_json &val)
add an object to an array
bool operator==(const const_iterator &other) const
comparison: equal
json_reverse_iterator & operator++()
pre-increment (++it)
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
bool operator>(const const_iterator &other) const
comparison: greater than
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
basic_json(basic_json &&other) noexcept
move constructor
const_iterator begin() const
returns a const iterator to the first element
const_reference at(size_type idx) const
access specified array element with bounds checking
json_reverse_iterator & operator+=(difference_type i)
add to iterator
a const random access iterator for the basic_json class
a template for a reverse iterator class
void swap(object_t &other)
exchanges the values
std::bidirectional_iterator_tag iterator_category
the category of the iterator
bool is_primitive() const noexcept
return whether type is primitive
iterator insert(const_iterator pos, const basic_json &val)
inserts element
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
reference operator[](difference_type n) const
access to successor
NumberIntegerType number_integer_t
a type for a number (integer)
reference operator[](difference_type n) const
access to successor
reference operator*() const
return a reference to the value pointed to by the iterator
value_type & reference
the type of an element reference
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
NumberFloatType number_float_t
a type for a number (floating-point)
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
iterator & operator=(iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
basic_json(const CompatibleObjectType &val)
create an object (implicit)
reference operator[](size_type idx)
access specified array element
iterator operator--(int)
post-decrement (it–)
json_reverse_iterator operator+(difference_type i) const
add to iterator
parse_event_t
JSON callback events.
iterator operator-(difference_type i)
subtract from iterator