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 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2680 operator ValueType()
const 2683 return get<ValueType>();
2725 assert(m_value.array !=
nullptr);
2726 return m_value.array->at(idx);
2728 catch (std::out_of_range&)
2731 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2736 throw std::domain_error(
"cannot use at() with " + type_name());
2769 assert(m_value.array !=
nullptr);
2770 return m_value.array->at(idx);
2772 catch (std::out_of_range&)
2775 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2780 throw std::domain_error(
"cannot use at() with " + type_name());
2817 assert(m_value.object !=
nullptr);
2818 return m_value.object->at(key);
2820 catch (std::out_of_range&)
2823 throw std::out_of_range(
"key '" + key +
"' not found");
2828 throw std::domain_error(
"cannot use at() with " + type_name());
2865 assert(m_value.object !=
nullptr);
2866 return m_value.object->at(key);
2868 catch (std::out_of_range&)
2871 throw std::out_of_range(
"key '" + key +
"' not found");
2876 throw std::domain_error(
"cannot use at() with " + type_name());
2910 m_type = value_t::array;
2911 m_value.
array = create<array_t>();
2917 assert(m_value.array !=
nullptr);
2918 for (
size_t i = m_value.array->size(); i <= idx; ++i)
2920 m_value.array->push_back(basic_json());
2923 return m_value.array->operator[](idx);
2927 throw std::domain_error(
"cannot use operator[] with " + type_name());
2955 assert(m_value.array !=
nullptr);
2956 return m_value.array->operator[](idx);
2960 throw std::domain_error(
"cannot use operator[] with " + type_name());
2996 m_type = value_t::object;
2997 m_value.
object = create<object_t>();
3003 assert(m_value.object !=
nullptr);
3004 return m_value.object->operator[](key);
3008 throw std::domain_error(
"cannot use operator[] with " + type_name());
3044 assert(m_value.object !=
nullptr);
3045 assert(m_value.object->find(key) != m_value.object->end());
3046 return m_value.object->find(key)->second;
3050 throw std::domain_error(
"cannot use operator[] with " + type_name());
3083 template<
typename T, std::
size_t n>
3089 m_type = value_t::object;
3090 m_value = value_t::object;
3096 assert(m_value.object !=
nullptr);
3097 return m_value.object->operator[](key);
3101 throw std::domain_error(
"cannot use operator[] with " + type_name());
3134 template<
typename T, std::
size_t n>
3140 assert(m_value.object !=
nullptr);
3141 assert(m_value.object->find(key) != m_value.object->end());
3142 return m_value.object->find(key)->second;
3146 throw std::domain_error(
"cannot use operator[] with " + type_name());
3198 template <
class ValueType,
typename 3200 std::is_convertible<basic_json_t, ValueType>::value
3202 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3208 const auto it = find(key);
3215 return default_value;
3220 throw std::domain_error(
"cannot use value() with " + type_name());
3228 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3230 return value(key,
string_t(default_value));
3348 template <
class InteratorType,
typename 3350 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3351 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3357 if (
this != pos.m_object)
3359 throw std::domain_error(
"iterator does not fit current value");
3362 InteratorType result = end();
3366 case value_t::boolean:
3367 case value_t::number_float:
3368 case value_t::number_integer:
3369 case value_t::string:
3371 if (not pos.m_it.primitive_iterator.is_begin())
3373 throw std::out_of_range(
"iterator out of range");
3378 delete m_value.string;
3379 m_value.string =
nullptr;
3382 m_type = value_t::null;
3386 case value_t::object:
3388 assert(m_value.object !=
nullptr);
3389 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3393 case value_t::array:
3395 assert(m_value.array !=
nullptr);
3396 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3402 throw std::domain_error(
"cannot use erase() with " + type_name());
3453 template <
class InteratorType,
typename 3455 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3456 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3459 InteratorType
erase(InteratorType first, InteratorType last)
3462 if (
this != first.m_object or
this != last.m_object)
3464 throw std::domain_error(
"iterators do not fit current value");
3467 InteratorType result = end();
3471 case value_t::boolean:
3472 case value_t::number_float:
3473 case value_t::number_integer:
3474 case value_t::string:
3476 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3478 throw std::out_of_range(
"iterators out of range");
3483 delete m_value.string;
3484 m_value.string =
nullptr;
3487 m_type = value_t::null;
3491 case value_t::object:
3493 assert(m_value.object !=
nullptr);
3494 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3495 last.m_it.object_iterator);
3499 case value_t::array:
3501 assert(m_value.array !=
nullptr);
3502 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3503 last.m_it.array_iterator);
3509 throw std::domain_error(
"cannot use erase() with " + type_name());
3547 assert(m_value.object !=
nullptr);
3548 return m_value.object->erase(key);
3552 throw std::domain_error(
"cannot use erase() with " + type_name());
3587 throw std::out_of_range(
"index out of range");
3590 assert(m_value.array !=
nullptr);
3591 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3595 throw std::domain_error(
"cannot use erase() with " + type_name());
3618 auto result = end();
3622 assert(m_value.object !=
nullptr);
3623 result.m_it.object_iterator = m_value.object->find(key);
3635 auto result = cend();
3639 assert(m_value.object !=
nullptr);
3640 result.m_it.object_iterator = m_value.object->find(key);
3667 assert(not is_object() or m_value.object !=
nullptr);
3668 return is_object() ? m_value.object->count(key) : 0;
3908 template<
typename IteratorType>
class iteration_proxy;
3924 return iteration_proxy<iterator>(cont);
3932 return iteration_proxy<const_iterator>(cont);
3984 case value_t::array:
3986 assert(m_value.array !=
nullptr);
3987 return m_value.array->empty();
3990 case value_t::object:
3992 assert(m_value.object !=
nullptr);
3993 return m_value.object->empty();
4042 case value_t::array:
4044 assert(m_value.array !=
nullptr);
4045 return m_value.array->size();
4048 case value_t::object:
4050 assert(m_value.object !=
nullptr);
4051 return m_value.object->size();
4098 case value_t::array:
4100 assert(m_value.array !=
nullptr);
4101 return m_value.array->max_size();
4104 case value_t::object:
4106 assert(m_value.object !=
nullptr);
4107 return m_value.object->max_size();
4157 case value_t::number_integer:
4159 m_value.number_integer = 0;
4163 case value_t::number_float:
4165 m_value.number_float = 0.0;
4169 case value_t::boolean:
4171 m_value.boolean =
false;
4175 case value_t::string:
4177 assert(m_value.string !=
nullptr);
4178 m_value.string->clear();
4182 case value_t::array:
4184 assert(m_value.array !=
nullptr);
4185 m_value.array->clear();
4189 case value_t::object:
4191 assert(m_value.object !=
nullptr);
4192 m_value.object->clear();
4226 if (not(is_null() or is_array()))
4228 throw std::domain_error(
"cannot use push_back() with " + type_name());
4234 m_type = value_t::array;
4235 m_value = value_t::array;
4239 assert(m_value.array !=
nullptr);
4240 m_value.array->push_back(std::move(val));
4242 val.m_type = value_t::null;
4251 push_back(std::move(val));
4262 if (not(is_null() or is_array()))
4264 throw std::domain_error(
"cannot use push_back() with " + type_name());
4270 m_type = value_t::array;
4271 m_value = value_t::array;
4275 assert(m_value.array !=
nullptr);
4276 m_value.array->push_back(val);
4312 if (not(is_null() or is_object()))
4314 throw std::domain_error(
"cannot use push_back() with " + type_name());
4320 m_type = value_t::object;
4321 m_value = value_t::object;
4325 assert(m_value.object !=
nullptr);
4326 m_value.object->insert(val);
4336 return operator[](val.first);
4367 if (pos.m_object !=
this)
4369 throw std::domain_error(
"iterator does not fit current value");
4374 assert(m_value.array !=
nullptr);
4375 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4380 throw std::domain_error(
"cannot use insert() with " + type_name());
4390 return insert(pos, val);
4423 if (pos.m_object !=
this)
4425 throw std::domain_error(
"iterator does not fit current value");
4430 assert(m_value.array !=
nullptr);
4431 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4436 throw std::domain_error(
"cannot use insert() with " + type_name());
4475 throw std::domain_error(
"cannot use insert() with " + type_name());
4479 if (pos.m_object !=
this)
4481 throw std::domain_error(
"iterator does not fit current value");
4484 if (first.m_object != last.m_object)
4486 throw std::domain_error(
"iterators do not fit");
4489 if (first.m_object ==
this or last.m_object ==
this)
4491 throw std::domain_error(
"passed iterators may not belong to container");
4496 assert(m_value.array !=
nullptr);
4497 result.m_it.array_iterator = m_value.array->insert(
4498 pos.m_it.array_iterator,
4499 first.m_it.array_iterator,
4500 last.m_it.array_iterator);
4533 throw std::domain_error(
"cannot use insert() with " + type_name());
4537 if (pos.m_object !=
this)
4539 throw std::domain_error(
"iterator does not fit current value");
4544 assert(m_value.array !=
nullptr);
4545 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4567 std::is_nothrow_move_constructible<value_t>::value and
4568 std::is_nothrow_move_assignable<value_t>::value and
4569 std::is_nothrow_move_constructible<json_value>::value and
4570 std::is_nothrow_move_assignable<json_value>::value
4573 std::swap(m_type, other.m_type);
4574 std::swap(m_value, other.m_value);
4602 assert(m_value.array !=
nullptr);
4603 std::swap(*(m_value.array), other);
4607 throw std::domain_error(
"cannot use swap() with " + type_name());
4636 assert(m_value.object !=
nullptr);
4637 std::swap(*(m_value.object), other);
4641 throw std::domain_error(
"cannot use swap() with " + type_name());
4670 assert(m_value.string !=
nullptr);
4671 std::swap(*(m_value.string), other);
4675 throw std::domain_error(
"cannot use swap() with " + type_name());
4701 static constexpr std::array<uint8_t, 7> order = {{
4713 if (lhs == value_t::discarded or rhs == value_t::discarded)
4718 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
4747 const auto lhs_type = lhs.type();
4748 const auto rhs_type = rhs.type();
4750 if (lhs_type == rhs_type)
4754 case value_t::array:
4756 assert(lhs.m_value.array !=
nullptr);
4757 assert(rhs.m_value.array !=
nullptr);
4758 return *lhs.m_value.array == *rhs.m_value.array;
4760 case value_t::object:
4762 assert(lhs.m_value.object !=
nullptr);
4763 assert(rhs.m_value.object !=
nullptr);
4764 return *lhs.m_value.object == *rhs.m_value.object;
4770 case value_t::string:
4772 assert(lhs.m_value.string !=
nullptr);
4773 assert(rhs.m_value.string !=
nullptr);
4774 return *lhs.m_value.string == *rhs.m_value.string;
4776 case value_t::boolean:
4778 return lhs.m_value.boolean == rhs.m_value.boolean;
4780 case value_t::number_integer:
4782 return lhs.m_value.number_integer == rhs.m_value.number_integer;
4784 case value_t::number_float:
4786 return approx(lhs.m_value.number_float, rhs.m_value.number_float);
4794 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4796 return approx(static_cast<number_float_t>(lhs.m_value.number_integer),
4797 rhs.m_value.number_float);
4799 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4801 return approx(lhs.m_value.number_float,
4802 static_cast<number_float_t>(rhs.m_value.number_integer));
4857 return not (lhs == rhs);
4889 return not v.is_null();
4918 const auto lhs_type = lhs.type();
4919 const auto rhs_type = rhs.type();
4921 if (lhs_type == rhs_type)
4925 case value_t::array:
4927 assert(lhs.m_value.array !=
nullptr);
4928 assert(rhs.m_value.array !=
nullptr);
4929 return *lhs.m_value.array < *rhs.m_value.array;
4931 case value_t::object:
4933 assert(lhs.m_value.object !=
nullptr);
4934 assert(rhs.m_value.object !=
nullptr);
4935 return *lhs.m_value.object < *rhs.m_value.object;
4941 case value_t::string:
4943 assert(lhs.m_value.string !=
nullptr);
4944 assert(rhs.m_value.string !=
nullptr);
4945 return *lhs.m_value.string < *rhs.m_value.string;
4947 case value_t::boolean:
4949 return lhs.m_value.boolean < rhs.m_value.boolean;
4951 case value_t::number_integer:
4953 return lhs.m_value.number_integer < rhs.m_value.number_integer;
4955 case value_t::number_float:
4957 return lhs.m_value.number_float < rhs.m_value.number_float;
4965 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4968 rhs.m_value.number_float;
4970 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4972 return lhs.m_value.number_float <
4979 return operator<(lhs_type, rhs_type);
5001 return not (rhs < lhs);
5023 return not (lhs <= rhs);
5045 return not (lhs < rhs);
5080 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5083 const bool pretty_print = (o.width() > 0);
5084 const auto indentation = (pretty_print ? o.width() : 0);
5090 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5098 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5139 return parser(s, cb).
parse();
5168 return parser(i, cb).
parse();
5176 return parser(i, cb).
parse();
5204 j = parser(i).
parse();
5214 j = parser(i).
parse();
5233 case value_t::object:
5235 case value_t::array:
5237 case value_t::string:
5239 case value_t::boolean:
5241 case value_t::discarded:
5256 static std::size_t extra_space(
const string_t& s) noexcept
5258 std::size_t result = 0;
5260 for (
const auto& c : s)
5279 if (c >= 0x00 and c <= 0x1f)
5307 const auto space = extra_space(s);
5314 string_t result(s.size() + space,
'\\');
5315 std::size_t pos = 0;
5317 for (
const auto& c : s)
5324 result[pos + 1] =
'"';
5340 result[pos + 1] =
'b';
5348 result[pos + 1] =
'f';
5356 result[pos + 1] =
'n';
5364 result[pos + 1] =
'r';
5372 result[pos + 1] =
't';
5379 if (c >= 0x00 and c <= 0x1f)
5382 auto hexify = [](
const char v) ->
char 5384 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5389 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5427 void dump(std::ostream& o,
5428 const bool pretty_print,
5429 const unsigned int indent_step,
5430 const unsigned int current_indent = 0)
const 5433 unsigned int new_indent = current_indent;
5437 case value_t::object:
5439 assert(m_value.object !=
nullptr);
5441 if (m_value.object->empty())
5452 new_indent += indent_step;
5456 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5458 if (i != m_value.object->cbegin())
5460 o << (pretty_print ?
",\n" :
",");
5462 o <<
string_t(new_indent,
' ') <<
"\"" 5463 << escape_string(i->first) <<
"\":" 5464 << (pretty_print ?
" " :
"");
5465 i->second.dump(o, pretty_print, indent_step, new_indent);
5471 new_indent -= indent_step;
5475 o <<
string_t(new_indent,
' ') +
"}";
5479 case value_t::array:
5481 assert(m_value.array !=
nullptr);
5483 if (m_value.array->empty())
5494 new_indent += indent_step;
5498 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5500 if (i != m_value.array->cbegin())
5502 o << (pretty_print ?
",\n" :
",");
5505 i->dump(o, pretty_print, indent_step, new_indent);
5511 new_indent -= indent_step;
5515 o <<
string_t(new_indent,
' ') <<
"]";
5519 case value_t::string:
5521 assert(m_value.string !=
nullptr);
5522 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5526 case value_t::boolean:
5528 o << (m_value.boolean ?
"true" :
"false");
5532 case value_t::number_integer:
5534 o << m_value.number_integer;
5538 case value_t::number_float:
5543 o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
5547 case value_t::discarded:
5567 value_t m_type = value_t::null;
5570 json_value m_value = {};
5587 class primitive_iterator_t
5603 bool is_begin()
const 5605 return (m_it == begin_value);
5611 return (m_it == end_value);
5631 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5641 struct internal_iterator
5644 typename object_t::iterator object_iterator;
5646 typename array_t::iterator array_iterator;
5648 primitive_iterator_t primitive_iterator;
5652 : object_iterator(), array_iterator(), primitive_iterator()
5657 template<
typename IteratorType>
5658 class iteration_proxy
5662 class iteration_proxy_internal
5666 IteratorType anchor;
5668 size_t array_index = 0;
5671 iteration_proxy_internal(IteratorType it)
5676 iteration_proxy_internal& operator*()
5682 iteration_proxy_internal& operator++()
5691 bool operator!= (
const iteration_proxy_internal& o)
const 5693 return anchor != o.anchor;
5699 assert(anchor.m_object !=
nullptr);
5701 switch (anchor.m_object->type())
5704 case value_t::array:
5706 return std::to_string(array_index);
5710 case value_t::object:
5712 return anchor.key();
5724 typename IteratorType::reference value()
const 5726 return anchor.value();
5731 typename IteratorType::reference container;
5735 iteration_proxy(
typename IteratorType::reference cont)
5740 iteration_proxy_internal begin()
5742 return iteration_proxy_internal(container.begin());
5746 iteration_proxy_internal end()
5748 return iteration_proxy_internal(container.end());
5766 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
5769 friend class basic_json;
5789 assert(m_object !=
nullptr);
5791 switch (m_object->m_type)
5795 m_it.object_iterator =
typename object_t::iterator();
5801 m_it.array_iterator =
typename array_t::iterator();
5807 m_it.primitive_iterator = primitive_iterator_t();
5816 assert(m_object !=
nullptr);
5818 switch (m_object->m_type)
5822 m_it.object_iterator = other.m_it.object_iterator;
5828 m_it.array_iterator = other.m_it.array_iterator;
5834 m_it.primitive_iterator = other.m_it.primitive_iterator;
5842 : m_object(other.m_object), m_it(other.m_it)
5847 std::is_nothrow_move_constructible<pointer>::value and
5848 std::is_nothrow_move_assignable<pointer>::value and
5849 std::is_nothrow_move_constructible<internal_iterator>::value and
5850 std::is_nothrow_move_assignable<internal_iterator>::value
5853 std::swap(m_object, other.m_object);
5854 std::swap(m_it, other.m_it);
5862 assert(m_object !=
nullptr);
5864 switch (m_object->m_type)
5868 assert(m_object->m_value.object !=
nullptr);
5869 m_it.object_iterator = m_object->m_value.object->begin();
5875 assert(m_object->m_value.array !=
nullptr);
5876 m_it.array_iterator = m_object->m_value.array->begin();
5883 m_it.primitive_iterator.set_end();
5889 m_it.primitive_iterator.set_begin();
5898 assert(m_object !=
nullptr);
5900 switch (m_object->m_type)
5904 assert(m_object->m_value.object !=
nullptr);
5905 m_it.object_iterator = m_object->m_value.object->end();
5911 assert(m_object->m_value.array !=
nullptr);
5912 m_it.array_iterator = m_object->m_value.array->end();
5918 m_it.primitive_iterator.set_end();
5928 assert(m_object !=
nullptr);
5930 switch (m_object->m_type)
5934 assert(m_object->m_value.object);
5935 assert(m_it.object_iterator != m_object->m_value.object->end());
5936 return m_it.object_iterator->second;
5941 assert(m_object->m_value.array);
5942 assert(m_it.array_iterator != m_object->m_value.array->end());
5943 return *m_it.array_iterator;
5948 throw std::out_of_range(
"cannot get value");
5953 if (m_it.primitive_iterator.is_begin())
5959 throw std::out_of_range(
"cannot get value");
5968 assert(m_object !=
nullptr);
5970 switch (m_object->m_type)
5974 assert(m_object->m_value.object);
5975 assert(m_it.object_iterator != m_object->m_value.object->end());
5976 return &(m_it.object_iterator->second);
5981 assert(m_object->m_value.array);
5982 assert(m_it.array_iterator != m_object->m_value.array->end());
5983 return &*m_it.array_iterator;
5988 if (m_it.primitive_iterator.is_begin())
5994 throw std::out_of_range(
"cannot get value");
6003 auto result = *
this;
6011 assert(m_object !=
nullptr);
6013 switch (m_object->m_type)
6017 ++m_it.object_iterator;
6023 ++m_it.array_iterator;
6029 ++m_it.primitive_iterator;
6040 auto result = *
this;
6048 assert(m_object !=
nullptr);
6050 switch (m_object->m_type)
6054 --m_it.object_iterator;
6060 --m_it.array_iterator;
6066 --m_it.primitive_iterator;
6078 if (m_object != other.m_object)
6080 throw std::domain_error(
"cannot compare iterators of different containers");
6083 assert(m_object !=
nullptr);
6085 switch (m_object->m_type)
6089 return (m_it.object_iterator == other.m_it.object_iterator);
6094 return (m_it.array_iterator == other.m_it.array_iterator);
6099 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6107 return not operator==(other);
6114 if (m_object != other.m_object)
6116 throw std::domain_error(
"cannot compare iterators of different containers");
6119 assert(m_object !=
nullptr);
6121 switch (m_object->m_type)
6125 throw std::domain_error(
"cannot compare order of object iterators");
6130 return (m_it.array_iterator < other.m_it.array_iterator);
6135 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6143 return not other.operator < (*this);
6149 return not operator<=(other);
6155 return not operator<(other);
6161 assert(m_object !=
nullptr);
6163 switch (m_object->m_type)
6167 throw std::domain_error(
"cannot use offsets with object iterators");
6172 m_it.array_iterator += i;
6178 m_it.primitive_iterator += i;
6189 return operator+=(-i);
6195 auto result = *
this;
6203 auto result = *
this;
6211 assert(m_object !=
nullptr);
6213 switch (m_object->m_type)
6217 throw std::domain_error(
"cannot use offsets with object iterators");
6222 return m_it.array_iterator - other.m_it.array_iterator;
6227 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6235 assert(m_object !=
nullptr);
6237 switch (m_object->m_type)
6241 throw std::domain_error(
"cannot use operator[] for object iterators");
6246 return *(m_it.array_iterator + n);
6251 throw std::out_of_range(
"cannot get value");
6256 if (m_it.primitive_iterator == -n)
6262 throw std::out_of_range(
"cannot get value");
6269 typename object_t::key_type
key()
const 6271 assert(m_object !=
nullptr);
6273 if (m_object->is_object())
6275 return m_it.object_iterator->first;
6279 throw std::domain_error(
"cannot use key() for non-object iterators");
6293 internal_iterator m_it = internal_iterator();
6330 std::is_nothrow_move_constructible<pointer>::value and
6331 std::is_nothrow_move_assignable<pointer>::value and
6332 std::is_nothrow_move_constructible<internal_iterator>::value and
6333 std::is_nothrow_move_assignable<internal_iterator>::value
6336 base_iterator::operator=(other);
6343 return const_cast<reference>(base_iterator::operator*());
6349 return const_cast<pointer>(base_iterator::operator->());
6356 base_iterator::operator++();
6363 base_iterator::operator++();
6371 base_iterator::operator--();
6378 base_iterator::operator--();
6385 base_iterator::operator+=(i);
6392 base_iterator::operator-=(i);
6399 auto result = *
this;
6407 auto result = *
this;
6414 return base_iterator::operator-(other);
6420 return const_cast<reference>(base_iterator::operator[](n));
6426 return const_cast<reference>(base_iterator::value());
6447 template<
typename Base>
6469 return base_iterator::operator++(1);
6475 base_iterator::operator++();
6482 return base_iterator::operator--(1);
6488 base_iterator::operator--();
6495 base_iterator::operator+=(i);
6502 auto result = *
this;
6510 auto result = *
this;
6518 return this->base() - other.base();
6524 return *(this->operator+(n));
6528 typename object_t::key_type
key()
const 6530 auto it = --this->base();
6537 auto it = --this->base();
6538 return it.operator * ();
6559 enum class token_type
6578 using lexer_char_t =
unsigned char;
6581 explicit lexer(
const string_t& s) noexcept
6582 : m_stream(
nullptr), m_buffer(s)
6584 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6585 assert(m_content !=
nullptr);
6586 m_start = m_cursor = m_content;
6587 m_limit = m_content + s.size();
6591 explicit lexer(std::istream* s) noexcept
6592 : m_stream(s), m_buffer()
6594 assert(m_stream !=
nullptr);
6595 getline(*m_stream, m_buffer);
6596 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6597 assert(m_content !=
nullptr);
6598 m_start = m_cursor = m_content;
6599 m_limit = m_content + m_buffer.size();
6606 lexer(
const lexer&) =
delete;
6607 lexer operator=(
const lexer&) =
delete;
6624 static string_t to_unicode(
const std::size_t codepoint1,
6625 const std::size_t codepoint2 = 0)
6630 std::size_t codepoint = codepoint1;
6633 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6636 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6650 throw std::invalid_argument(
"missing or wrong low surrogate");
6654 if (codepoint < 0x80)
6657 result.append(1, static_cast<typename string_t::value_type>(codepoint));
6659 else if (codepoint <= 0x7ff)
6662 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6663 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6665 else if (codepoint <= 0xffff)
6668 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
6669 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6670 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6672 else if (codepoint <= 0x10ffff)
6675 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
6676 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
6677 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6678 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6682 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
6689 static std::string token_type_name(token_type t)
6693 case token_type::uninitialized:
6694 return "<uninitialized>";
6695 case token_type::literal_true:
6696 return "true literal";
6697 case token_type::literal_false:
6698 return "false literal";
6699 case token_type::literal_null:
6700 return "null literal";
6701 case token_type::value_string:
6702 return "string literal";
6703 case token_type::value_number:
6704 return "number literal";
6705 case token_type::begin_array:
6707 case token_type::begin_object:
6709 case token_type::end_array:
6711 case token_type::end_object:
6713 case token_type::name_separator:
6715 case token_type::value_separator:
6717 case token_type::parse_error:
6718 return "<parse error>";
6719 case token_type::end_of_input:
6720 return "end of input";
6724 return "unknown token";
6739 token_type scan() noexcept
6746 assert(m_start !=
nullptr);
6751 unsigned int yyaccept = 0;
6752 static const unsigned char yybm[] =
6754 0, 0, 0, 0, 0, 0, 0, 0,
6755 0, 32, 32, 0, 0, 32, 0, 0,
6756 64, 64, 64, 64, 64, 64, 64, 64,
6757 64, 64, 64, 64, 64, 64, 64, 64,
6758 96, 64, 0, 64, 64, 64, 64, 64,
6759 64, 64, 64, 64, 64, 64, 64, 64,
6760 192, 192, 192, 192, 192, 192, 192, 192,
6761 192, 192, 64, 64, 64, 64, 64, 64,
6762 64, 64, 64, 64, 64, 64, 64, 64,
6763 64, 64, 64, 64, 64, 64, 64, 64,
6764 64, 64, 64, 64, 64, 64, 64, 64,
6765 64, 64, 64, 64, 0, 64, 64, 64,
6766 64, 64, 64, 64, 64, 64, 64, 64,
6767 64, 64, 64, 64, 64, 64, 64, 64,
6768 64, 64, 64, 64, 64, 64, 64, 64,
6769 64, 64, 64, 64, 64, 64, 64, 64,
6770 64, 64, 64, 64, 64, 64, 64, 64,
6771 64, 64, 64, 64, 64, 64, 64, 64,
6772 64, 64, 64, 64, 64, 64, 64, 64,
6773 64, 64, 64, 64, 64, 64, 64, 64,
6774 64, 64, 64, 64, 64, 64, 64, 64,
6775 64, 64, 64, 64, 64, 64, 64, 64,
6776 64, 64, 64, 64, 64, 64, 64, 64,
6777 64, 64, 64, 64, 64, 64, 64, 64,
6778 64, 64, 64, 64, 64, 64, 64, 64,
6779 64, 64, 64, 64, 64, 64, 64, 64,
6780 64, 64, 64, 64, 64, 64, 64, 64,
6781 64, 64, 64, 64, 64, 64, 64, 64,
6782 64, 64, 64, 64, 64, 64, 64, 64,
6783 64, 64, 64, 64, 64, 64, 64, 64,
6784 64, 64, 64, 64, 64, 64, 64, 64,
6785 64, 64, 64, 64, 64, 64, 64, 64,
6787 if ((m_limit - m_cursor) < 5)
6800 goto basic_json_parser_28;
6804 goto basic_json_parser_30;
6808 goto basic_json_parser_4;
6815 goto basic_json_parser_2;
6819 goto basic_json_parser_30;
6829 goto basic_json_parser_27;
6833 goto basic_json_parser_30;
6835 goto basic_json_parser_16;
6843 goto basic_json_parser_23;
6845 goto basic_json_parser_30;
6851 goto basic_json_parser_24;
6855 goto basic_json_parser_26;
6857 goto basic_json_parser_18;
6870 goto basic_json_parser_8;
6874 goto basic_json_parser_30;
6876 goto basic_json_parser_10;
6882 goto basic_json_parser_22;
6886 goto basic_json_parser_30;
6888 goto basic_json_parser_20;
6897 goto basic_json_parser_21;
6901 goto basic_json_parser_30;
6903 goto basic_json_parser_12;
6911 goto basic_json_parser_30;
6913 goto basic_json_parser_14;
6919 goto basic_json_parser_6;
6921 goto basic_json_parser_30;
6926 basic_json_parser_2:
6929 goto basic_json_parser_5;
6930 basic_json_parser_3:
6934 basic_json_parser_4:
6936 if (m_limit <= m_cursor)
6941 basic_json_parser_5:
6942 if (yybm[0 + yych] & 32)
6944 goto basic_json_parser_4;
6946 goto basic_json_parser_3;
6947 basic_json_parser_6:
6949 yych = *(m_marker = ++m_cursor);
6952 goto basic_json_parser_64;
6954 basic_json_parser_7:
6956 return token_type::parse_error;
6958 basic_json_parser_8:
6961 return token_type::begin_array;
6963 basic_json_parser_10:
6966 return token_type::end_array;
6968 basic_json_parser_12:
6971 return token_type::begin_object;
6973 basic_json_parser_14:
6976 return token_type::end_object;
6978 basic_json_parser_16:
6981 return token_type::value_separator;
6983 basic_json_parser_18:
6986 return token_type::name_separator;
6988 basic_json_parser_20:
6990 yych = *(m_marker = ++m_cursor);
6993 goto basic_json_parser_60;
6995 goto basic_json_parser_7;
6996 basic_json_parser_21:
6998 yych = *(m_marker = ++m_cursor);
7001 goto basic_json_parser_56;
7003 goto basic_json_parser_7;
7004 basic_json_parser_22:
7006 yych = *(m_marker = ++m_cursor);
7009 goto basic_json_parser_51;
7011 goto basic_json_parser_7;
7012 basic_json_parser_23:
7016 goto basic_json_parser_7;
7020 goto basic_json_parser_50;
7024 goto basic_json_parser_41;
7026 goto basic_json_parser_7;
7027 basic_json_parser_24:
7029 yych = *(m_marker = ++m_cursor);
7034 goto basic_json_parser_43;
7041 goto basic_json_parser_44;
7045 goto basic_json_parser_44;
7048 basic_json_parser_25:
7050 return token_type::value_number;
7052 basic_json_parser_26:
7054 yych = *(m_marker = ++m_cursor);
7055 goto basic_json_parser_42;
7056 basic_json_parser_27:
7058 yych = *(m_marker = ++m_cursor);
7061 goto basic_json_parser_7;
7063 goto basic_json_parser_32;
7064 basic_json_parser_28:
7067 return token_type::end_of_input;
7069 basic_json_parser_30:
7071 goto basic_json_parser_7;
7072 basic_json_parser_31:
7074 if (m_limit <= m_cursor)
7079 basic_json_parser_32:
7080 if (yybm[0 + yych] & 64)
7082 goto basic_json_parser_31;
7086 goto basic_json_parser_33;
7090 goto basic_json_parser_35;
7092 goto basic_json_parser_34;
7093 basic_json_parser_33:
7094 m_cursor = m_marker;
7097 goto basic_json_parser_7;
7101 goto basic_json_parser_25;
7103 basic_json_parser_34:
7105 if (m_limit <= m_cursor)
7116 goto basic_json_parser_31;
7120 goto basic_json_parser_33;
7122 goto basic_json_parser_31;
7130 goto basic_json_parser_33;
7132 goto basic_json_parser_31;
7138 goto basic_json_parser_31;
7140 goto basic_json_parser_33;
7150 goto basic_json_parser_31;
7154 goto basic_json_parser_31;
7156 goto basic_json_parser_33;
7164 goto basic_json_parser_31;
7166 goto basic_json_parser_33;
7172 goto basic_json_parser_31;
7176 goto basic_json_parser_37;
7178 goto basic_json_parser_33;
7182 basic_json_parser_35:
7185 return token_type::value_string;
7187 basic_json_parser_37:
7189 if (m_limit <= m_cursor)
7198 goto basic_json_parser_33;
7202 goto basic_json_parser_33;
7209 goto basic_json_parser_38;
7213 goto basic_json_parser_33;
7217 goto basic_json_parser_33;
7220 basic_json_parser_38:
7222 if (m_limit <= m_cursor)
7231 goto basic_json_parser_33;
7235 goto basic_json_parser_33;
7242 goto basic_json_parser_39;
7246 goto basic_json_parser_33;
7250 goto basic_json_parser_33;
7253 basic_json_parser_39:
7255 if (m_limit <= m_cursor)
7264 goto basic_json_parser_33;
7268 goto basic_json_parser_33;
7275 goto basic_json_parser_40;
7279 goto basic_json_parser_33;
7283 goto basic_json_parser_33;
7286 basic_json_parser_40:
7288 if (m_limit <= m_cursor)
7297 goto basic_json_parser_33;
7301 goto basic_json_parser_31;
7303 goto basic_json_parser_33;
7309 goto basic_json_parser_31;
7313 goto basic_json_parser_33;
7317 goto basic_json_parser_31;
7319 goto basic_json_parser_33;
7321 basic_json_parser_41:
7323 m_marker = ++m_cursor;
7324 if ((m_limit - m_cursor) < 3)
7329 basic_json_parser_42:
7330 if (yybm[0 + yych] & 128)
7332 goto basic_json_parser_41;
7338 goto basic_json_parser_25;
7345 goto basic_json_parser_44;
7349 goto basic_json_parser_44;
7351 goto basic_json_parser_25;
7353 basic_json_parser_43:
7357 goto basic_json_parser_33;
7361 goto basic_json_parser_48;
7363 goto basic_json_parser_33;
7364 basic_json_parser_44:
7370 goto basic_json_parser_33;
7377 goto basic_json_parser_45;
7381 goto basic_json_parser_33;
7385 goto basic_json_parser_46;
7387 goto basic_json_parser_33;
7389 basic_json_parser_45:
7393 goto basic_json_parser_33;
7397 goto basic_json_parser_33;
7399 basic_json_parser_46:
7401 if (m_limit <= m_cursor)
7408 goto basic_json_parser_25;
7412 goto basic_json_parser_46;
7414 goto basic_json_parser_25;
7415 basic_json_parser_48:
7417 m_marker = ++m_cursor;
7418 if ((m_limit - m_cursor) < 3)
7427 goto basic_json_parser_25;
7431 goto basic_json_parser_48;
7433 goto basic_json_parser_25;
7439 goto basic_json_parser_44;
7443 goto basic_json_parser_44;
7445 goto basic_json_parser_25;
7447 basic_json_parser_50:
7449 yych = *(m_marker = ++m_cursor);
7454 goto basic_json_parser_43;
7456 goto basic_json_parser_25;
7462 goto basic_json_parser_44;
7466 goto basic_json_parser_44;
7468 goto basic_json_parser_25;
7470 basic_json_parser_51:
7474 goto basic_json_parser_33;
7479 goto basic_json_parser_33;
7484 goto basic_json_parser_33;
7488 return token_type::literal_false;
7490 basic_json_parser_56:
7494 goto basic_json_parser_33;
7499 goto basic_json_parser_33;
7503 return token_type::literal_true;
7505 basic_json_parser_60:
7509 goto basic_json_parser_33;
7514 goto basic_json_parser_33;
7518 return token_type::literal_null;
7520 basic_json_parser_64:
7524 goto basic_json_parser_33;
7536 void yyfill() noexcept
7538 if (m_stream ==
nullptr or not * m_stream)
7543 const ssize_t offset_start = m_start - m_content;
7544 const ssize_t offset_marker = m_marker - m_start;
7545 const ssize_t offset_cursor = m_cursor - m_start;
7547 m_buffer.erase(0, static_cast<size_t>(offset_start));
7549 assert(m_stream !=
nullptr);
7550 std::getline(*m_stream, line);
7551 m_buffer +=
"\n" + line;
7553 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7554 assert(m_content !=
nullptr);
7555 m_start = m_content;
7556 m_marker = m_start + offset_marker;
7557 m_cursor = m_start + offset_cursor;
7558 m_limit = m_start + m_buffer.size() - 1;
7562 string_t get_token()
const noexcept
7564 assert(m_start !=
nullptr);
7565 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7566 static_cast<size_t>(m_cursor - m_start));
7593 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7596 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7652 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7653 4).c_str(),
nullptr, 16);
7656 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7659 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7661 throw std::invalid_argument(
"missing low surrogate");
7665 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7666 (i + 7), 4).c_str(),
nullptr, 16);
7667 result += to_unicode(codepoint, codepoint2);
7674 result += to_unicode(codepoint);
7686 result.append(1, static_cast<typename string_t::value_type>(*i));
7710 long double get_number()
const 7713 typename string_t::value_type* endptr;
7714 assert(m_start !=
nullptr);
7715 const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
7720 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7725 std::istream* m_stream =
nullptr;
7729 const lexer_char_t* m_content =
nullptr;
7731 const lexer_char_t* m_start =
nullptr;
7733 const lexer_char_t* m_marker =
nullptr;
7735 const lexer_char_t* m_cursor =
nullptr;
7737 const lexer_char_t* m_limit =
nullptr;
7750 : callback(cb), m_lexer(s)
7758 : callback(cb), m_lexer(&_is)
7767 basic_json result = parse_internal(
true);
7769 expect(lexer::token_type::end_of_input);
7778 basic_json parse_internal(
bool keep)
7780 auto result = basic_json(value_t::discarded);
7784 case lexer::token_type::begin_object:
7786 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7789 result.m_type = value_t::object;
7790 result.m_value = json_value(value_t::object);
7797 if (last_token == lexer::token_type::end_object)
7800 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7802 result = basic_json(value_t::discarded);
7808 unexpect(lexer::token_type::value_separator);
7814 if (last_token == lexer::token_type::value_separator)
7820 expect(lexer::token_type::value_string);
7821 const auto key = m_lexer.get_string();
7823 bool keep_tag =
false;
7829 keep_tag = callback(depth, parse_event_t::key, k);
7839 expect(lexer::token_type::name_separator);
7843 auto value = parse_internal(keep);
7844 if (keep and keep_tag and not value.is_discarded())
7846 result[key] = std::move(value);
7849 while (last_token == lexer::token_type::value_separator);
7852 expect(lexer::token_type::end_object);
7854 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7856 result = basic_json(value_t::discarded);
7862 case lexer::token_type::begin_array:
7864 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7867 result.m_type = value_t::array;
7868 result.m_value = json_value(value_t::array);
7875 if (last_token == lexer::token_type::end_array)
7878 if (callback and not callback(--depth, parse_event_t::array_end, result))
7880 result = basic_json(value_t::discarded);
7886 unexpect(lexer::token_type::value_separator);
7892 if (last_token == lexer::token_type::value_separator)
7898 auto value = parse_internal(keep);
7899 if (keep and not value.is_discarded())
7901 result.push_back(std::move(value));
7904 while (last_token == lexer::token_type::value_separator);
7907 expect(lexer::token_type::end_array);
7909 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
7911 result = basic_json(value_t::discarded);
7917 case lexer::token_type::literal_null:
7920 result.m_type = value_t::null;
7924 case lexer::token_type::value_string:
7926 const auto s = m_lexer.get_string();
7928 result = basic_json(s);
7932 case lexer::token_type::literal_true:
7935 result.m_type = value_t::boolean;
7936 result.m_value =
true;
7940 case lexer::token_type::literal_false:
7943 result.m_type = value_t::boolean;
7944 result.m_value =
false;
7948 case lexer::token_type::value_number:
7950 auto float_val = m_lexer.get_number();
7954 if (std::isnan(float_val))
7956 throw std::invalid_argument(std::string(
"parse error - ") +
7957 m_lexer.get_token() +
" is not a number");
7964 if (approx(float_val, static_cast<long double>(int_val)))
7967 result.m_type = value_t::number_integer;
7968 result.m_value = int_val;
7973 result.m_type = value_t::number_float;
7982 unexpect(last_token);
7986 if (keep and callback and not callback(depth, parse_event_t::value, result))
7988 result = basic_json(value_t::discarded);
7994 typename lexer::token_type get_token()
7996 last_token = m_lexer.scan();
8000 void expect(
typename lexer::token_type t)
const 8002 if (t != last_token)
8004 std::string error_msg =
"parse error - unexpected ";
8005 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8006 lexer::token_type_name(last_token));
8007 error_msg +=
"; expected " + lexer::token_type_name(t);
8008 throw std::invalid_argument(error_msg);
8012 void unexpect(
typename lexer::token_type t)
const 8014 if (t == last_token)
8016 std::string error_msg =
"parse error - unexpected ";
8017 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8018 lexer::token_type_name(last_token));
8019 throw std::invalid_argument(error_msg);
8029 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8067 is_nothrow_move_constructible<nlohmann::json>::value and
8068 is_nothrow_move_assignable<nlohmann::json>::value
8086 const auto& h = hash<nlohmann::json::string_t>();
8104 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
reference operator[](const T(&key)[n])
access specified object 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
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
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)
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_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_reference operator[](const T(&key)[n]) const
read-only access specified object element
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