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;
2457 template<
typename ValueType,
typename 2459 not std::is_pointer<ValueType>::value
2461 ValueType
get()
const 2463 return get_impl(static_cast<ValueType*>(
nullptr));
2492 template<
typename PointerType,
typename 2494 std::is_pointer<PointerType>::value
2496 PointerType
get() noexcept
2499 return get_ptr<PointerType>();
2506 template<
typename PointerType,
typename 2508 std::is_pointer<PointerType>::value
2510 const PointerType
get()
const noexcept
2513 return get_ptr<PointerType>();
2541 template<
typename PointerType,
typename 2543 std::is_pointer<PointerType>::value
2548 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2555 template<
typename PointerType,
typename 2557 std::is_pointer<PointerType>::value
2558 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2563 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2594 template<
typename ValueType,
typename 2596 not std::is_pointer<ValueType>::value
2597 and not std::is_same<ValueType, typename string_t::value_type>::value
2598 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2600 operator ValueType()
const 2603 return get<ValueType>();
2645 assert(m_value.array !=
nullptr);
2646 return m_value.array->at(idx);
2648 catch (std::out_of_range& e)
2651 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2656 throw std::domain_error(
"cannot use at() with " + type_name());
2689 assert(m_value.array !=
nullptr);
2690 return m_value.array->at(idx);
2692 catch (std::out_of_range& e)
2695 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2700 throw std::domain_error(
"cannot use at() with " + type_name());
2737 assert(m_value.object !=
nullptr);
2738 return m_value.object->at(key);
2740 catch (std::out_of_range& e)
2743 throw std::out_of_range(
"key '" + key +
"' not found");
2748 throw std::domain_error(
"cannot use at() with " + type_name());
2785 assert(m_value.object !=
nullptr);
2786 return m_value.object->at(key);
2788 catch (std::out_of_range& e)
2791 throw std::out_of_range(
"key '" + key +
"' not found");
2796 throw std::domain_error(
"cannot use at() with " + type_name());
2830 m_type = value_t::array;
2831 m_value.
array = create<array_t>();
2837 assert(m_value.array !=
nullptr);
2838 for (
size_t i = m_value.array->size(); i <= idx; ++i)
2840 m_value.array->push_back(basic_json());
2843 return m_value.array->operator[](idx);
2847 throw std::domain_error(
"cannot use operator[] with " + type_name());
2875 assert(m_value.array !=
nullptr);
2876 return m_value.array->operator[](idx);
2880 throw std::domain_error(
"cannot use operator[] with " + type_name());
2916 m_type = value_t::object;
2917 m_value.
object = create<object_t>();
2923 assert(m_value.object !=
nullptr);
2924 return m_value.object->operator[](key);
2928 throw std::domain_error(
"cannot use operator[] with " + type_name());
2964 assert(m_value.object !=
nullptr);
2965 assert(m_value.object->find(key) != m_value.object->end());
2966 return m_value.object->find(key)->second;
2970 throw std::domain_error(
"cannot use operator[] with " + type_name());
3003 template<
typename T, std::
size_t n>
3009 m_type = value_t::object;
3010 m_value = value_t::object;
3016 assert(m_value.object !=
nullptr);
3017 return m_value.object->operator[](key);
3021 throw std::domain_error(
"cannot use operator[] with " + type_name());
3054 template<
typename T, std::
size_t n>
3060 assert(m_value.object !=
nullptr);
3061 assert(m_value.object->find(key) != m_value.object->end());
3062 return m_value.object->find(key)->second;
3066 throw std::domain_error(
"cannot use operator[] with " + type_name());
3118 template <
class ValueType,
typename 3120 std::is_convertible<basic_json_t, ValueType>::value
3122 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3128 const auto it = find(key);
3135 return default_value;
3140 throw std::domain_error(
"cannot use value() with " + type_name());
3148 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3150 return value(key,
string_t(default_value));
3268 template <
class InteratorType,
typename 3270 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3271 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3277 if (
this != pos.m_object)
3279 throw std::domain_error(
"iterator does not fit current value");
3282 InteratorType result = end();
3286 case value_t::boolean:
3287 case value_t::number_float:
3288 case value_t::number_integer:
3289 case value_t::string:
3291 if (not pos.m_it.primitive_iterator.is_begin())
3293 throw std::out_of_range(
"iterator out of range");
3298 delete m_value.string;
3299 m_value.string =
nullptr;
3302 m_type = value_t::null;
3306 case value_t::object:
3308 assert(m_value.object !=
nullptr);
3309 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3313 case value_t::array:
3315 assert(m_value.array !=
nullptr);
3316 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3322 throw std::domain_error(
"cannot use erase() with " + type_name());
3373 template <
class InteratorType,
typename 3375 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3376 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3379 InteratorType
erase(InteratorType first, InteratorType last)
3382 if (
this != first.m_object or
this != last.m_object)
3384 throw std::domain_error(
"iterators do not fit current value");
3387 InteratorType result = end();
3391 case value_t::boolean:
3392 case value_t::number_float:
3393 case value_t::number_integer:
3394 case value_t::string:
3396 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3398 throw std::out_of_range(
"iterators out of range");
3403 delete m_value.string;
3404 m_value.string =
nullptr;
3407 m_type = value_t::null;
3411 case value_t::object:
3413 assert(m_value.object !=
nullptr);
3414 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3415 last.m_it.object_iterator);
3419 case value_t::array:
3421 assert(m_value.array !=
nullptr);
3422 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3423 last.m_it.array_iterator);
3429 throw std::domain_error(
"cannot use erase() with " + type_name());
3467 assert(m_value.object !=
nullptr);
3468 return m_value.object->erase(key);
3472 throw std::domain_error(
"cannot use erase() with " + type_name());
3507 throw std::out_of_range(
"index out of range");
3510 assert(m_value.array !=
nullptr);
3511 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3515 throw std::domain_error(
"cannot use erase() with " + type_name());
3538 auto result = end();
3542 assert(m_value.object !=
nullptr);
3543 result.m_it.object_iterator = m_value.object->find(key);
3555 auto result = cend();
3559 assert(m_value.object !=
nullptr);
3560 result.m_it.object_iterator = m_value.object->find(key);
3587 assert(not is_object() or m_value.object !=
nullptr);
3588 return is_object() ? m_value.object->count(key) : 0;
3828 template<
typename IteratorType>
class iteration_proxy;
3844 return iteration_proxy<iterator>(cont);
3852 return iteration_proxy<const_iterator>(cont);
3904 case value_t::array:
3906 assert(m_value.array !=
nullptr);
3907 return m_value.array->empty();
3910 case value_t::object:
3912 assert(m_value.object !=
nullptr);
3913 return m_value.object->empty();
3962 case value_t::array:
3964 assert(m_value.array !=
nullptr);
3965 return m_value.array->size();
3968 case value_t::object:
3970 assert(m_value.object !=
nullptr);
3971 return m_value.object->size();
4018 case value_t::array:
4020 assert(m_value.array !=
nullptr);
4021 return m_value.array->max_size();
4024 case value_t::object:
4026 assert(m_value.object !=
nullptr);
4027 return m_value.object->max_size();
4077 case value_t::number_integer:
4079 m_value.number_integer = 0;
4083 case value_t::number_float:
4085 m_value.number_float = 0.0;
4089 case value_t::boolean:
4091 m_value.boolean =
false;
4095 case value_t::string:
4097 assert(m_value.string !=
nullptr);
4098 m_value.string->clear();
4102 case value_t::array:
4104 assert(m_value.array !=
nullptr);
4105 m_value.array->clear();
4109 case value_t::object:
4111 assert(m_value.object !=
nullptr);
4112 m_value.object->clear();
4146 if (not(is_null() or is_array()))
4148 throw std::domain_error(
"cannot use push_back() with " + type_name());
4154 m_type = value_t::array;
4155 m_value = value_t::array;
4159 assert(m_value.array !=
nullptr);
4160 m_value.array->push_back(std::move(val));
4162 val.m_type = value_t::null;
4171 push_back(std::move(val));
4182 if (not(is_null() or is_array()))
4184 throw std::domain_error(
"cannot use push_back() with " + type_name());
4190 m_type = value_t::array;
4191 m_value = value_t::array;
4195 assert(m_value.array !=
nullptr);
4196 m_value.array->push_back(val);
4232 if (not(is_null() or is_object()))
4234 throw std::domain_error(
"cannot use push_back() with " + type_name());
4240 m_type = value_t::object;
4241 m_value = value_t::object;
4245 assert(m_value.object !=
nullptr);
4246 m_value.object->insert(val);
4256 return operator[](val.first);
4287 if (pos.m_object !=
this)
4289 throw std::domain_error(
"iterator does not fit current value");
4294 assert(m_value.array !=
nullptr);
4295 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4300 throw std::domain_error(
"cannot use insert() with " + type_name());
4310 return insert(pos, val);
4343 if (pos.m_object !=
this)
4345 throw std::domain_error(
"iterator does not fit current value");
4350 assert(m_value.array !=
nullptr);
4351 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4356 throw std::domain_error(
"cannot use insert() with " + type_name());
4395 throw std::domain_error(
"cannot use insert() with " + type_name());
4399 if (pos.m_object !=
this)
4401 throw std::domain_error(
"iterator does not fit current value");
4404 if (first.m_object != last.m_object)
4406 throw std::domain_error(
"iterators do not fit");
4409 if (first.m_object ==
this or last.m_object ==
this)
4411 throw std::domain_error(
"passed iterators may not belong to container");
4416 assert(m_value.array !=
nullptr);
4417 result.m_it.array_iterator = m_value.array->insert(
4418 pos.m_it.array_iterator,
4419 first.m_it.array_iterator,
4420 last.m_it.array_iterator);
4453 throw std::domain_error(
"cannot use insert() with " + type_name());
4457 if (pos.m_object !=
this)
4459 throw std::domain_error(
"iterator does not fit current value");
4464 assert(m_value.array !=
nullptr);
4465 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4487 std::is_nothrow_move_constructible<value_t>::value and
4488 std::is_nothrow_move_assignable<value_t>::value and
4489 std::is_nothrow_move_constructible<json_value>::value and
4490 std::is_nothrow_move_assignable<json_value>::value
4493 std::swap(m_type, other.m_type);
4494 std::swap(m_value, other.m_value);
4522 assert(m_value.array !=
nullptr);
4523 std::swap(*(m_value.array), other);
4527 throw std::domain_error(
"cannot use swap() with " + type_name());
4556 assert(m_value.object !=
nullptr);
4557 std::swap(*(m_value.object), other);
4561 throw std::domain_error(
"cannot use swap() with " + type_name());
4590 assert(m_value.string !=
nullptr);
4591 std::swap(*(m_value.string), other);
4595 throw std::domain_error(
"cannot use swap() with " + type_name());
4621 static constexpr std::array<uint8_t, 7> order = {{
4633 if (lhs == value_t::discarded or rhs == value_t::discarded)
4638 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
4667 const auto lhs_type = lhs.type();
4668 const auto rhs_type = rhs.type();
4670 if (lhs_type == rhs_type)
4674 case value_t::array:
4676 assert(lhs.m_value.array !=
nullptr);
4677 assert(rhs.m_value.array !=
nullptr);
4678 return *lhs.m_value.array == *rhs.m_value.array;
4680 case value_t::object:
4682 assert(lhs.m_value.object !=
nullptr);
4683 assert(rhs.m_value.object !=
nullptr);
4684 return *lhs.m_value.object == *rhs.m_value.object;
4690 case value_t::string:
4692 assert(lhs.m_value.string !=
nullptr);
4693 assert(rhs.m_value.string !=
nullptr);
4694 return *lhs.m_value.string == *rhs.m_value.string;
4696 case value_t::boolean:
4698 return lhs.m_value.boolean == rhs.m_value.boolean;
4700 case value_t::number_integer:
4702 return lhs.m_value.number_integer == rhs.m_value.number_integer;
4704 case value_t::number_float:
4706 return approx(lhs.m_value.number_float, rhs.m_value.number_float);
4714 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4716 return approx(static_cast<number_float_t>(lhs.m_value.number_integer),
4717 rhs.m_value.number_float);
4719 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4721 return approx(lhs.m_value.number_float,
4722 static_cast<number_float_t>(rhs.m_value.number_integer));
4777 return not (lhs == rhs);
4809 return not v.is_null();
4838 const auto lhs_type = lhs.type();
4839 const auto rhs_type = rhs.type();
4841 if (lhs_type == rhs_type)
4845 case value_t::array:
4847 assert(lhs.m_value.array !=
nullptr);
4848 assert(rhs.m_value.array !=
nullptr);
4849 return *lhs.m_value.array < *rhs.m_value.array;
4851 case value_t::object:
4853 assert(lhs.m_value.object !=
nullptr);
4854 assert(rhs.m_value.object !=
nullptr);
4855 return *lhs.m_value.object < *rhs.m_value.object;
4861 case value_t::string:
4863 assert(lhs.m_value.string !=
nullptr);
4864 assert(rhs.m_value.string !=
nullptr);
4865 return *lhs.m_value.string < *rhs.m_value.string;
4867 case value_t::boolean:
4869 return lhs.m_value.boolean < rhs.m_value.boolean;
4871 case value_t::number_integer:
4873 return lhs.m_value.number_integer < rhs.m_value.number_integer;
4875 case value_t::number_float:
4877 return lhs.m_value.number_float < rhs.m_value.number_float;
4885 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4888 rhs.m_value.number_float;
4890 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4892 return lhs.m_value.number_float <
4899 return operator<(lhs_type, rhs_type);
4921 return not (rhs < lhs);
4943 return not (lhs <= rhs);
4965 return not (lhs < rhs);
5000 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5003 const bool pretty_print = (o.width() > 0);
5004 const auto indentation = (pretty_print ? o.width() : 0);
5010 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5018 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5059 return parser(s, cb).
parse();
5088 return parser(i, cb).
parse();
5096 return parser(i, cb).
parse();
5124 j = parser(i).
parse();
5134 j = parser(i).
parse();
5153 case value_t::object:
5155 case value_t::array:
5157 case value_t::string:
5159 case value_t::boolean:
5161 case value_t::discarded:
5176 static std::size_t extra_space(
const string_t& s) noexcept
5178 std::size_t result = 0;
5180 for (
const auto& c : s)
5199 if (c >= 0x00 and c <= 0x1f)
5227 const auto space = extra_space(s);
5234 string_t result(s.size() + space,
'\\');
5235 std::size_t pos = 0;
5237 for (
const auto& c : s)
5244 result[pos + 1] =
'"';
5260 result[pos + 1] =
'b';
5268 result[pos + 1] =
'f';
5276 result[pos + 1] =
'n';
5284 result[pos + 1] =
'r';
5292 result[pos + 1] =
't';
5299 if (c >= 0x00 and c <= 0x1f)
5302 auto hexify = [](
const char v) ->
char 5304 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5309 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5347 void dump(std::ostream& o,
5348 const bool pretty_print,
5349 const unsigned int indent_step,
5350 const unsigned int current_indent = 0)
const 5353 unsigned int new_indent = current_indent;
5357 case value_t::object:
5359 assert(m_value.object !=
nullptr);
5361 if (m_value.object->empty())
5372 new_indent += indent_step;
5376 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5378 if (i != m_value.object->cbegin())
5380 o << (pretty_print ?
",\n" :
",");
5382 o <<
string_t(new_indent,
' ') <<
"\"" 5383 << escape_string(i->first) <<
"\":" 5384 << (pretty_print ?
" " :
"");
5385 i->second.dump(o, pretty_print, indent_step, new_indent);
5391 new_indent -= indent_step;
5395 o <<
string_t(new_indent,
' ') +
"}";
5399 case value_t::array:
5401 assert(m_value.array !=
nullptr);
5403 if (m_value.array->empty())
5414 new_indent += indent_step;
5418 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5420 if (i != m_value.array->cbegin())
5422 o << (pretty_print ?
",\n" :
",");
5425 i->dump(o, pretty_print, indent_step, new_indent);
5431 new_indent -= indent_step;
5435 o <<
string_t(new_indent,
' ') <<
"]";
5439 case value_t::string:
5441 assert(m_value.string !=
nullptr);
5442 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5446 case value_t::boolean:
5448 o << (m_value.boolean ?
"true" :
"false");
5452 case value_t::number_integer:
5454 o << m_value.number_integer;
5458 case value_t::number_float:
5463 o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
5467 case value_t::discarded:
5487 value_t m_type = value_t::null;
5490 json_value m_value = {};
5507 class primitive_iterator_t
5523 bool is_begin()
const 5525 return (m_it == begin_value);
5531 return (m_it == end_value);
5551 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5561 struct internal_iterator
5564 typename object_t::iterator object_iterator;
5566 typename array_t::iterator array_iterator;
5568 primitive_iterator_t primitive_iterator;
5572 : object_iterator(), array_iterator(), primitive_iterator()
5577 template<
typename IteratorType>
5578 class iteration_proxy
5582 class iteration_proxy_internal
5586 IteratorType anchor;
5588 size_t array_index = 0;
5591 iteration_proxy_internal(IteratorType it)
5596 iteration_proxy_internal& operator*()
5602 iteration_proxy_internal& operator++()
5611 bool operator!= (
const iteration_proxy_internal& o)
const 5613 return anchor != o.anchor;
5619 assert(anchor.m_object !=
nullptr);
5621 switch (anchor.m_object->type())
5624 case value_t::array:
5626 return std::to_string(array_index);
5630 case value_t::object:
5632 return anchor.key();
5644 typename IteratorType::reference value()
const 5646 return anchor.value();
5651 typename IteratorType::reference container;
5655 iteration_proxy(
typename IteratorType::reference cont)
5660 iteration_proxy_internal begin()
5662 return iteration_proxy_internal(container.begin());
5666 iteration_proxy_internal end()
5668 return iteration_proxy_internal(container.end());
5686 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
5689 friend class basic_json;
5709 assert(m_object !=
nullptr);
5711 switch (m_object->m_type)
5715 m_it.object_iterator =
typename object_t::iterator();
5721 m_it.array_iterator =
typename array_t::iterator();
5727 m_it.primitive_iterator = primitive_iterator_t();
5736 assert(m_object !=
nullptr);
5738 switch (m_object->m_type)
5742 m_it.object_iterator = other.m_it.object_iterator;
5748 m_it.array_iterator = other.m_it.array_iterator;
5754 m_it.primitive_iterator = other.m_it.primitive_iterator;
5762 : m_object(other.m_object), m_it(other.m_it)
5767 std::is_nothrow_move_constructible<pointer>::value and
5768 std::is_nothrow_move_assignable<pointer>::value and
5769 std::is_nothrow_move_constructible<internal_iterator>::value and
5770 std::is_nothrow_move_assignable<internal_iterator>::value
5773 std::swap(m_object, other.m_object);
5774 std::swap(m_it, other.m_it);
5782 assert(m_object !=
nullptr);
5784 switch (m_object->m_type)
5788 assert(m_object->m_value.object !=
nullptr);
5789 m_it.object_iterator = m_object->m_value.object->begin();
5795 assert(m_object->m_value.array !=
nullptr);
5796 m_it.array_iterator = m_object->m_value.array->begin();
5803 m_it.primitive_iterator.set_end();
5809 m_it.primitive_iterator.set_begin();
5818 assert(m_object !=
nullptr);
5820 switch (m_object->m_type)
5824 assert(m_object->m_value.object !=
nullptr);
5825 m_it.object_iterator = m_object->m_value.object->end();
5831 assert(m_object->m_value.array !=
nullptr);
5832 m_it.array_iterator = m_object->m_value.array->end();
5838 m_it.primitive_iterator.set_end();
5848 assert(m_object !=
nullptr);
5850 switch (m_object->m_type)
5854 assert(m_object->m_value.object);
5855 assert(m_it.object_iterator != m_object->m_value.object->end());
5856 return m_it.object_iterator->second;
5861 assert(m_object->m_value.array);
5862 assert(m_it.array_iterator != m_object->m_value.array->end());
5863 return *m_it.array_iterator;
5868 throw std::out_of_range(
"cannot get value");
5873 if (m_it.primitive_iterator.is_begin())
5879 throw std::out_of_range(
"cannot get value");
5888 assert(m_object !=
nullptr);
5890 switch (m_object->m_type)
5894 assert(m_object->m_value.object);
5895 assert(m_it.object_iterator != m_object->m_value.object->end());
5896 return &(m_it.object_iterator->second);
5901 assert(m_object->m_value.array);
5902 assert(m_it.array_iterator != m_object->m_value.array->end());
5903 return &*m_it.array_iterator;
5908 if (m_it.primitive_iterator.is_begin())
5914 throw std::out_of_range(
"cannot get value");
5923 auto result = *
this;
5931 assert(m_object !=
nullptr);
5933 switch (m_object->m_type)
5937 ++m_it.object_iterator;
5943 ++m_it.array_iterator;
5949 ++m_it.primitive_iterator;
5960 auto result = *
this;
5968 assert(m_object !=
nullptr);
5970 switch (m_object->m_type)
5974 --m_it.object_iterator;
5980 --m_it.array_iterator;
5986 --m_it.primitive_iterator;
5998 if (m_object != other.m_object)
6000 throw std::domain_error(
"cannot compare iterators of different containers");
6003 assert(m_object !=
nullptr);
6005 switch (m_object->m_type)
6009 return (m_it.object_iterator == other.m_it.object_iterator);
6014 return (m_it.array_iterator == other.m_it.array_iterator);
6019 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6027 return not operator==(other);
6034 if (m_object != other.m_object)
6036 throw std::domain_error(
"cannot compare iterators of different containers");
6039 assert(m_object !=
nullptr);
6041 switch (m_object->m_type)
6045 throw std::domain_error(
"cannot compare order of object iterators");
6050 return (m_it.array_iterator < other.m_it.array_iterator);
6055 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6063 return not other.operator < (*this);
6069 return not operator<=(other);
6075 return not operator<(other);
6081 assert(m_object !=
nullptr);
6083 switch (m_object->m_type)
6087 throw std::domain_error(
"cannot use offsets with object iterators");
6092 m_it.array_iterator += i;
6098 m_it.primitive_iterator += i;
6109 return operator+=(-i);
6115 auto result = *
this;
6123 auto result = *
this;
6131 assert(m_object !=
nullptr);
6133 switch (m_object->m_type)
6137 throw std::domain_error(
"cannot use offsets with object iterators");
6142 return m_it.array_iterator - other.m_it.array_iterator;
6147 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6155 assert(m_object !=
nullptr);
6157 switch (m_object->m_type)
6161 throw std::domain_error(
"cannot use operator[] for object iterators");
6166 return *(m_it.array_iterator + n);
6171 throw std::out_of_range(
"cannot get value");
6176 if (m_it.primitive_iterator == -n)
6182 throw std::out_of_range(
"cannot get value");
6189 typename object_t::key_type
key()
const 6191 assert(m_object !=
nullptr);
6193 if (m_object->is_object())
6195 return m_it.object_iterator->first;
6199 throw std::domain_error(
"cannot use key() for non-object iterators");
6213 internal_iterator m_it = internal_iterator();
6250 std::is_nothrow_move_constructible<pointer>::value and
6251 std::is_nothrow_move_assignable<pointer>::value and
6252 std::is_nothrow_move_constructible<internal_iterator>::value and
6253 std::is_nothrow_move_assignable<internal_iterator>::value
6256 base_iterator::operator=(other);
6263 return const_cast<reference>(base_iterator::operator*());
6269 return const_cast<pointer>(base_iterator::operator->());
6276 base_iterator::operator++();
6283 base_iterator::operator++();
6291 base_iterator::operator--();
6298 base_iterator::operator--();
6305 base_iterator::operator+=(i);
6312 base_iterator::operator-=(i);
6319 auto result = *
this;
6327 auto result = *
this;
6334 return base_iterator::operator-(other);
6340 return const_cast<reference>(base_iterator::operator[](n));
6346 return const_cast<reference>(base_iterator::value());
6367 template<
typename Base>
6389 return base_iterator::operator++(1);
6395 base_iterator::operator++();
6402 return base_iterator::operator--(1);
6408 base_iterator::operator--();
6415 base_iterator::operator+=(i);
6422 auto result = *
this;
6430 auto result = *
this;
6438 return this->base() - other.base();
6444 return *(this->operator+(n));
6448 typename object_t::key_type
key()
const 6450 auto it = --this->base();
6457 auto it = --this->base();
6458 return it.operator * ();
6479 enum class token_type
6498 using lexer_char_t =
unsigned char;
6501 explicit lexer(
const string_t& s) noexcept
6502 : m_stream(
nullptr), m_buffer(s)
6504 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6505 assert(m_content !=
nullptr);
6506 m_start = m_cursor = m_content;
6507 m_limit = m_content + s.size();
6511 explicit lexer(std::istream* s) noexcept
6512 : m_stream(s), m_buffer()
6514 assert(m_stream !=
nullptr);
6515 getline(*m_stream, m_buffer);
6516 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6517 assert(m_content !=
nullptr);
6518 m_start = m_cursor = m_content;
6519 m_limit = m_content + m_buffer.size();
6526 lexer(
const lexer&) =
delete;
6527 lexer operator=(
const lexer&) =
delete;
6544 static string_t to_unicode(
const std::size_t codepoint1,
6545 const std::size_t codepoint2 = 0)
6550 std::size_t codepoint = codepoint1;
6553 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6556 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6570 throw std::invalid_argument(
"missing or wrong low surrogate");
6574 if (codepoint < 0x80)
6577 result.append(1, static_cast<typename string_t::value_type>(codepoint));
6579 else if (codepoint <= 0x7ff)
6582 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6583 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6585 else if (codepoint <= 0xffff)
6588 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
6589 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6590 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6592 else if (codepoint <= 0x10ffff)
6595 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
6596 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
6597 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6598 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6602 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
6609 static std::string token_type_name(token_type t)
6613 case token_type::uninitialized:
6614 return "<uninitialized>";
6615 case token_type::literal_true:
6616 return "true literal";
6617 case token_type::literal_false:
6618 return "false literal";
6619 case token_type::literal_null:
6620 return "null literal";
6621 case token_type::value_string:
6622 return "string literal";
6623 case token_type::value_number:
6624 return "number literal";
6625 case token_type::begin_array:
6627 case token_type::begin_object:
6629 case token_type::end_array:
6631 case token_type::end_object:
6633 case token_type::name_separator:
6635 case token_type::value_separator:
6637 case token_type::parse_error:
6638 return "<parse error>";
6639 case token_type::end_of_input:
6640 return "end of input";
6644 return "unknown token";
6659 token_type scan() noexcept
6666 assert(m_start !=
nullptr);
6671 unsigned int yyaccept = 0;
6672 static const unsigned char yybm[] =
6674 0, 0, 0, 0, 0, 0, 0, 0,
6675 0, 32, 32, 0, 0, 32, 0, 0,
6676 64, 64, 64, 64, 64, 64, 64, 64,
6677 64, 64, 64, 64, 64, 64, 64, 64,
6678 96, 64, 0, 64, 64, 64, 64, 64,
6679 64, 64, 64, 64, 64, 64, 64, 64,
6680 192, 192, 192, 192, 192, 192, 192, 192,
6681 192, 192, 64, 64, 64, 64, 64, 64,
6682 64, 64, 64, 64, 64, 64, 64, 64,
6683 64, 64, 64, 64, 64, 64, 64, 64,
6684 64, 64, 64, 64, 64, 64, 64, 64,
6685 64, 64, 64, 64, 0, 64, 64, 64,
6686 64, 64, 64, 64, 64, 64, 64, 64,
6687 64, 64, 64, 64, 64, 64, 64, 64,
6688 64, 64, 64, 64, 64, 64, 64, 64,
6689 64, 64, 64, 64, 64, 64, 64, 64,
6690 64, 64, 64, 64, 64, 64, 64, 64,
6691 64, 64, 64, 64, 64, 64, 64, 64,
6692 64, 64, 64, 64, 64, 64, 64, 64,
6693 64, 64, 64, 64, 64, 64, 64, 64,
6694 64, 64, 64, 64, 64, 64, 64, 64,
6695 64, 64, 64, 64, 64, 64, 64, 64,
6696 64, 64, 64, 64, 64, 64, 64, 64,
6697 64, 64, 64, 64, 64, 64, 64, 64,
6698 64, 64, 64, 64, 64, 64, 64, 64,
6699 64, 64, 64, 64, 64, 64, 64, 64,
6700 64, 64, 64, 64, 64, 64, 64, 64,
6701 64, 64, 64, 64, 64, 64, 64, 64,
6702 64, 64, 64, 64, 64, 64, 64, 64,
6703 64, 64, 64, 64, 64, 64, 64, 64,
6704 64, 64, 64, 64, 64, 64, 64, 64,
6705 64, 64, 64, 64, 64, 64, 64, 64,
6707 if ((m_limit - m_cursor) < 5)
6720 goto basic_json_parser_28;
6724 goto basic_json_parser_30;
6728 goto basic_json_parser_4;
6735 goto basic_json_parser_2;
6739 goto basic_json_parser_30;
6749 goto basic_json_parser_27;
6753 goto basic_json_parser_30;
6755 goto basic_json_parser_16;
6763 goto basic_json_parser_23;
6765 goto basic_json_parser_30;
6771 goto basic_json_parser_24;
6775 goto basic_json_parser_26;
6777 goto basic_json_parser_18;
6790 goto basic_json_parser_8;
6794 goto basic_json_parser_30;
6796 goto basic_json_parser_10;
6802 goto basic_json_parser_22;
6806 goto basic_json_parser_30;
6808 goto basic_json_parser_20;
6817 goto basic_json_parser_21;
6821 goto basic_json_parser_30;
6823 goto basic_json_parser_12;
6831 goto basic_json_parser_30;
6833 goto basic_json_parser_14;
6839 goto basic_json_parser_6;
6841 goto basic_json_parser_30;
6846 basic_json_parser_2:
6849 goto basic_json_parser_5;
6850 basic_json_parser_3:
6854 basic_json_parser_4:
6856 if (m_limit <= m_cursor)
6861 basic_json_parser_5:
6862 if (yybm[0 + yych] & 32)
6864 goto basic_json_parser_4;
6866 goto basic_json_parser_3;
6867 basic_json_parser_6:
6869 yych = *(m_marker = ++m_cursor);
6872 goto basic_json_parser_64;
6874 basic_json_parser_7:
6876 return token_type::parse_error;
6878 basic_json_parser_8:
6881 return token_type::begin_array;
6883 basic_json_parser_10:
6886 return token_type::end_array;
6888 basic_json_parser_12:
6891 return token_type::begin_object;
6893 basic_json_parser_14:
6896 return token_type::end_object;
6898 basic_json_parser_16:
6901 return token_type::value_separator;
6903 basic_json_parser_18:
6906 return token_type::name_separator;
6908 basic_json_parser_20:
6910 yych = *(m_marker = ++m_cursor);
6913 goto basic_json_parser_60;
6915 goto basic_json_parser_7;
6916 basic_json_parser_21:
6918 yych = *(m_marker = ++m_cursor);
6921 goto basic_json_parser_56;
6923 goto basic_json_parser_7;
6924 basic_json_parser_22:
6926 yych = *(m_marker = ++m_cursor);
6929 goto basic_json_parser_51;
6931 goto basic_json_parser_7;
6932 basic_json_parser_23:
6936 goto basic_json_parser_7;
6940 goto basic_json_parser_50;
6944 goto basic_json_parser_41;
6946 goto basic_json_parser_7;
6947 basic_json_parser_24:
6949 yych = *(m_marker = ++m_cursor);
6954 goto basic_json_parser_43;
6961 goto basic_json_parser_44;
6965 goto basic_json_parser_44;
6968 basic_json_parser_25:
6970 return token_type::value_number;
6972 basic_json_parser_26:
6974 yych = *(m_marker = ++m_cursor);
6975 goto basic_json_parser_42;
6976 basic_json_parser_27:
6978 yych = *(m_marker = ++m_cursor);
6981 goto basic_json_parser_7;
6983 goto basic_json_parser_32;
6984 basic_json_parser_28:
6987 return token_type::end_of_input;
6989 basic_json_parser_30:
6991 goto basic_json_parser_7;
6992 basic_json_parser_31:
6994 if (m_limit <= m_cursor)
6999 basic_json_parser_32:
7000 if (yybm[0 + yych] & 64)
7002 goto basic_json_parser_31;
7006 goto basic_json_parser_33;
7010 goto basic_json_parser_35;
7012 goto basic_json_parser_34;
7013 basic_json_parser_33:
7014 m_cursor = m_marker;
7017 goto basic_json_parser_7;
7021 goto basic_json_parser_25;
7023 basic_json_parser_34:
7025 if (m_limit <= m_cursor)
7036 goto basic_json_parser_31;
7040 goto basic_json_parser_33;
7042 goto basic_json_parser_31;
7050 goto basic_json_parser_33;
7052 goto basic_json_parser_31;
7058 goto basic_json_parser_31;
7060 goto basic_json_parser_33;
7070 goto basic_json_parser_31;
7074 goto basic_json_parser_31;
7076 goto basic_json_parser_33;
7084 goto basic_json_parser_31;
7086 goto basic_json_parser_33;
7092 goto basic_json_parser_31;
7096 goto basic_json_parser_37;
7098 goto basic_json_parser_33;
7102 basic_json_parser_35:
7105 return token_type::value_string;
7107 basic_json_parser_37:
7109 if (m_limit <= m_cursor)
7118 goto basic_json_parser_33;
7122 goto basic_json_parser_33;
7129 goto basic_json_parser_38;
7133 goto basic_json_parser_33;
7137 goto basic_json_parser_33;
7140 basic_json_parser_38:
7142 if (m_limit <= m_cursor)
7151 goto basic_json_parser_33;
7155 goto basic_json_parser_33;
7162 goto basic_json_parser_39;
7166 goto basic_json_parser_33;
7170 goto basic_json_parser_33;
7173 basic_json_parser_39:
7175 if (m_limit <= m_cursor)
7184 goto basic_json_parser_33;
7188 goto basic_json_parser_33;
7195 goto basic_json_parser_40;
7199 goto basic_json_parser_33;
7203 goto basic_json_parser_33;
7206 basic_json_parser_40:
7208 if (m_limit <= m_cursor)
7217 goto basic_json_parser_33;
7221 goto basic_json_parser_31;
7223 goto basic_json_parser_33;
7229 goto basic_json_parser_31;
7233 goto basic_json_parser_33;
7237 goto basic_json_parser_31;
7239 goto basic_json_parser_33;
7241 basic_json_parser_41:
7243 m_marker = ++m_cursor;
7244 if ((m_limit - m_cursor) < 3)
7249 basic_json_parser_42:
7250 if (yybm[0 + yych] & 128)
7252 goto basic_json_parser_41;
7258 goto basic_json_parser_25;
7265 goto basic_json_parser_44;
7269 goto basic_json_parser_44;
7271 goto basic_json_parser_25;
7273 basic_json_parser_43:
7277 goto basic_json_parser_33;
7281 goto basic_json_parser_48;
7283 goto basic_json_parser_33;
7284 basic_json_parser_44:
7290 goto basic_json_parser_33;
7297 goto basic_json_parser_45;
7301 goto basic_json_parser_33;
7305 goto basic_json_parser_46;
7307 goto basic_json_parser_33;
7309 basic_json_parser_45:
7313 goto basic_json_parser_33;
7317 goto basic_json_parser_33;
7319 basic_json_parser_46:
7321 if (m_limit <= m_cursor)
7328 goto basic_json_parser_25;
7332 goto basic_json_parser_46;
7334 goto basic_json_parser_25;
7335 basic_json_parser_48:
7337 m_marker = ++m_cursor;
7338 if ((m_limit - m_cursor) < 3)
7347 goto basic_json_parser_25;
7351 goto basic_json_parser_48;
7353 goto basic_json_parser_25;
7359 goto basic_json_parser_44;
7363 goto basic_json_parser_44;
7365 goto basic_json_parser_25;
7367 basic_json_parser_50:
7369 yych = *(m_marker = ++m_cursor);
7374 goto basic_json_parser_43;
7376 goto basic_json_parser_25;
7382 goto basic_json_parser_44;
7386 goto basic_json_parser_44;
7388 goto basic_json_parser_25;
7390 basic_json_parser_51:
7394 goto basic_json_parser_33;
7399 goto basic_json_parser_33;
7404 goto basic_json_parser_33;
7408 return token_type::literal_false;
7410 basic_json_parser_56:
7414 goto basic_json_parser_33;
7419 goto basic_json_parser_33;
7423 return token_type::literal_true;
7425 basic_json_parser_60:
7429 goto basic_json_parser_33;
7434 goto basic_json_parser_33;
7438 return token_type::literal_null;
7440 basic_json_parser_64:
7444 goto basic_json_parser_33;
7456 void yyfill() noexcept
7458 if (m_stream ==
nullptr or not * m_stream)
7463 const ssize_t offset_start = m_start - m_content;
7464 const ssize_t offset_marker = m_marker - m_start;
7465 const ssize_t offset_cursor = m_cursor - m_start;
7467 m_buffer.erase(0, static_cast<size_t>(offset_start));
7469 assert(m_stream !=
nullptr);
7470 std::getline(*m_stream, line);
7471 m_buffer +=
"\n" + line;
7473 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7474 assert(m_content !=
nullptr);
7475 m_start = m_content;
7476 m_marker = m_start + offset_marker;
7477 m_cursor = m_start + offset_cursor;
7478 m_limit = m_start + m_buffer.size() - 1;
7482 string_t get_token()
const noexcept
7484 assert(m_start !=
nullptr);
7485 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7486 static_cast<size_t>(m_cursor - m_start));
7513 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7516 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7572 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7573 4).c_str(),
nullptr, 16);
7576 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7579 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7581 throw std::invalid_argument(
"missing low surrogate");
7585 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7586 (i + 7), 4).c_str(),
nullptr, 16);
7587 result += to_unicode(codepoint, codepoint2);
7594 result += to_unicode(codepoint);
7606 result.append(1, static_cast<typename string_t::value_type>(*i));
7630 long double get_number()
const 7633 typename string_t::value_type* endptr;
7634 assert(m_start !=
nullptr);
7635 const auto float_val = std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start),
7640 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7645 std::istream* m_stream =
nullptr;
7649 const lexer_char_t* m_content =
nullptr;
7651 const lexer_char_t* m_start =
nullptr;
7653 const lexer_char_t* m_marker =
nullptr;
7655 const lexer_char_t* m_cursor =
nullptr;
7657 const lexer_char_t* m_limit =
nullptr;
7670 : callback(cb), m_lexer(s)
7678 : callback(cb), m_lexer(&_is)
7687 basic_json result = parse_internal(
true);
7689 expect(lexer::token_type::end_of_input);
7698 basic_json parse_internal(
bool keep)
7700 auto result = basic_json(value_t::discarded);
7704 case lexer::token_type::begin_object:
7706 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7709 result.m_type = value_t::object;
7710 result.m_value = json_value(value_t::object);
7717 if (last_token == lexer::token_type::end_object)
7720 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7722 result = basic_json(value_t::discarded);
7728 unexpect(lexer::token_type::value_separator);
7734 if (last_token == lexer::token_type::value_separator)
7740 expect(lexer::token_type::value_string);
7741 const auto key = m_lexer.get_string();
7743 bool keep_tag =
false;
7749 keep_tag = callback(depth, parse_event_t::key, k);
7759 expect(lexer::token_type::name_separator);
7763 auto value = parse_internal(keep);
7764 if (keep and keep_tag and not value.is_discarded())
7766 result[key] = std::move(value);
7769 while (last_token == lexer::token_type::value_separator);
7772 expect(lexer::token_type::end_object);
7774 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7776 result = basic_json(value_t::discarded);
7782 case lexer::token_type::begin_array:
7784 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7787 result.m_type = value_t::array;
7788 result.m_value = json_value(value_t::array);
7795 if (last_token == lexer::token_type::end_array)
7798 if (callback and not callback(--depth, parse_event_t::array_end, result))
7800 result = basic_json(value_t::discarded);
7806 unexpect(lexer::token_type::value_separator);
7812 if (last_token == lexer::token_type::value_separator)
7818 auto value = parse_internal(keep);
7819 if (keep and not value.is_discarded())
7821 result.push_back(std::move(value));
7824 while (last_token == lexer::token_type::value_separator);
7827 expect(lexer::token_type::end_array);
7829 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
7831 result = basic_json(value_t::discarded);
7837 case lexer::token_type::literal_null:
7840 result.m_type = value_t::null;
7844 case lexer::token_type::value_string:
7846 const auto s = m_lexer.get_string();
7848 result = basic_json(s);
7852 case lexer::token_type::literal_true:
7855 result.m_type = value_t::boolean;
7856 result.m_value =
true;
7860 case lexer::token_type::literal_false:
7863 result.m_type = value_t::boolean;
7864 result.m_value =
false;
7868 case lexer::token_type::value_number:
7870 auto float_val = m_lexer.get_number();
7874 if (std::isnan(float_val))
7876 throw std::invalid_argument(std::string(
"parse error - ") +
7877 m_lexer.get_token() +
" is not a number");
7884 if (approx(float_val, static_cast<long double>(int_val)))
7887 result.m_type = value_t::number_integer;
7888 result.m_value = int_val;
7893 result.m_type = value_t::number_float;
7902 unexpect(last_token);
7906 if (keep and callback and not callback(depth, parse_event_t::value, result))
7908 result = basic_json(value_t::discarded);
7914 typename lexer::token_type get_token()
7916 last_token = m_lexer.scan();
7920 void expect(
typename lexer::token_type t)
const 7922 if (t != last_token)
7924 std::string error_msg =
"parse error - unexpected ";
7925 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
7926 lexer::token_type_name(last_token));
7927 error_msg +=
"; expected " + lexer::token_type_name(t);
7928 throw std::invalid_argument(error_msg);
7932 void unexpect(
typename lexer::token_type t)
const 7934 if (t == last_token)
7936 std::string error_msg =
"parse error - unexpected ";
7937 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
7938 lexer::token_type_name(last_token));
7939 throw std::invalid_argument(error_msg);
7949 typename lexer::token_type last_token = lexer::token_type::uninitialized;
7987 is_nothrow_move_constructible<nlohmann::json>::value and
7988 is_nothrow_move_assignable<nlohmann::json>::value
8006 const auto& h = hash<nlohmann::json::string_t>();
8024 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)
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)
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