38 #ifndef NLOHMANN_JSON_HPP 39 #define NLOHMANN_JSON_HPP 50 #include <initializer_list> 60 #include <type_traits> 67 #include <sys/types.h> 72 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 73 #pragma GCC diagnostic push 74 #pragma GCC diagnostic ignored "-Wfloat-equal" 80 using ssize_t = SSIZE_T;
103 struct has_mapped_type
106 template<
typename C>
static char test(
typename C::mapped_type*);
107 template<
typename C>
static char (&test(...))[2];
109 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
183 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
184 template<
typename U,
typename... Args>
class ArrayType = std::vector,
185 class StringType = std::string,
186 class BooleanType = bool,
187 class NumberIntegerType = int64_t,
188 class NumberFloatType = double,
189 template<
typename U>
class AllocatorType = std::allocator
229 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
231 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
346 using object_t = ObjectType<StringType,
348 std::less<StringType>,
349 AllocatorType<std::pair<
const StringType,
396 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
636 template<
typename T,
typename... Args>
637 static T* create(Args&& ... args)
639 AllocatorType<T> alloc;
640 auto deleter = [&](T * object)
642 alloc.deallocate(
object, 1);
644 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
645 alloc.construct(
object.
get(), std::forward<Args>(args)...);
646 return object.release();
676 json_value() noexcept =
default;
678 json_value(
boolean_t v) noexcept : boolean(v) {}
688 case value_t::object:
690 object = create<object_t>();
696 array = create<array_t>();
700 case value_t::string:
702 string = create<string_t>(
"");
706 case value_t::boolean:
712 case value_t::number_integer:
718 case value_t::number_float:
734 string = create<string_t>(value);
740 object = create<object_t>(value);
744 json_value(
const array_t& value)
746 array = create<array_t>(value);
829 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
877 : m_type(value_type), m_value(value_type)
899 basic_json() noexcept =
default;
944 : m_type(
value_t::object), m_value(val)
970 template <
class CompatibleObjectType,
typename 972 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
973 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
980 m_value.object = create<object_t>(begin(val), end(val));
1003 : m_type(
value_t::array), m_value(val)
1029 template <
class CompatibleArrayType,
typename 1031 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1032 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1033 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1034 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1035 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1036 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1037 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1044 m_value.array = create<array_t>(begin(val), end(val));
1069 : m_type(
value_t::string), m_value(val)
1119 template <
class CompatibleStringType,
typename 1121 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1142 : m_type(
value_t::boolean), m_value(val)
1170 template<
typename T,
1171 typename std::enable_if<
1172 not (std::is_same<T, int>::value)
1173 and std::is_same<T, number_integer_t>::value
1176 : m_type(
value_t::number_integer), m_value(val)
1205 : m_type(
value_t::number_integer),
1234 template<
typename CompatibleNumberIntegerType,
typename 1236 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1237 std::numeric_limits<CompatibleNumberIntegerType>::is_integer, CompatibleNumberIntegerType>::type
1240 : m_type(value_t::number_integer),
1241 m_value(static_cast<number_integer_t>(val))
1269 : m_type(
value_t::number_float), m_value(val)
1272 if (not std::isfinite(val))
1274 m_type = value_t::null;
1275 m_value = json_value();
1309 template<
typename CompatibleNumberFloatType,
typename =
typename 1311 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1312 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1388 bool type_deduction =
true,
1389 value_t manual_type = value_t::array)
1392 bool is_an_object =
true;
1396 for (
const auto& element : init)
1398 if (not element.is_array() or element.size() != 2
1399 or not element[0].is_string())
1403 is_an_object =
false;
1409 if (not type_deduction)
1412 if (manual_type == value_t::array)
1414 is_an_object =
false;
1418 if (manual_type == value_t::object and not is_an_object)
1420 throw std::domain_error(
"cannot create object from initializer list");
1427 m_type = value_t::object;
1428 m_value = value_t::object;
1430 assert(m_value.object !=
nullptr);
1432 for (
auto& element : init)
1434 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1440 m_type = value_t::array;
1441 m_value.array = create<array_t>(std::move(init));
1479 static basic_json
array(std::initializer_list<basic_json> init =
1480 std::initializer_list<basic_json>())
1482 return basic_json(init,
false, value_t::array);
1519 static basic_json
object(std::initializer_list<basic_json> init =
1520 std::initializer_list<basic_json>())
1522 return basic_json(init,
false, value_t::object);
1546 m_value.array = create<array_t>(cnt, val);
1583 template <
class InputIT,
typename 1585 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1586 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1589 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1592 if (first.m_object != last.m_object)
1594 throw std::domain_error(
"iterators are not compatible");
1600 case value_t::boolean:
1601 case value_t::number_float:
1602 case value_t::number_integer:
1603 case value_t::string:
1605 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1607 throw std::out_of_range(
"iterators out of range");
1620 case value_t::number_integer:
1622 assert(first.m_object !=
nullptr);
1623 m_value.number_integer = first.m_object->m_value.number_integer;
1627 case value_t::number_float:
1629 assert(first.m_object !=
nullptr);
1630 m_value.number_float = first.m_object->m_value.number_float;
1634 case value_t::boolean:
1636 assert(first.m_object !=
nullptr);
1637 m_value.boolean = first.m_object->m_value.boolean;
1641 case value_t::string:
1643 assert(first.m_object !=
nullptr);
1644 m_value = *first.m_object->m_value.string;
1648 case value_t::object:
1650 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1654 case value_t::array:
1656 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1662 assert(first.m_object !=
nullptr);
1663 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1693 : m_type(other.m_type)
1697 case value_t::object:
1699 assert(other.m_value.object !=
nullptr);
1700 m_value = *other.m_value.object;
1704 case value_t::array:
1706 assert(other.m_value.array !=
nullptr);
1707 m_value = *other.m_value.array;
1711 case value_t::string:
1713 assert(other.m_value.string !=
nullptr);
1714 m_value = *other.m_value.string;
1718 case value_t::boolean:
1720 m_value = other.m_value.boolean;
1724 case value_t::number_integer:
1726 m_value = other.m_value.number_integer;
1730 case value_t::number_float:
1732 m_value = other.m_value.number_float;
1762 : m_type(
std::move(other.m_type)),
1763 m_value(
std::move(other.m_value))
1766 other.m_type = value_t::null;
1792 std::is_nothrow_move_constructible<value_t>::value and
1793 std::is_nothrow_move_assignable<value_t>::value and
1794 std::is_nothrow_move_constructible<json_value>::value and
1795 std::is_nothrow_move_assignable<json_value>::value
1799 swap(m_type, other.m_type);
1800 swap(m_value, other.m_value);
1821 case value_t::object:
1823 AllocatorType<object_t> alloc;
1824 alloc.destroy(m_value.object);
1825 alloc.deallocate(m_value.object, 1);
1829 case value_t::array:
1831 AllocatorType<array_t> alloc;
1832 alloc.destroy(m_value.array);
1833 alloc.deallocate(m_value.array, 1);
1837 case value_t::string:
1839 AllocatorType<string_t> alloc;
1840 alloc.destroy(m_value.string);
1841 alloc.deallocate(m_value.string, 1);
1888 std::stringstream ss;
1892 dump(ss,
true, static_cast<unsigned int>(indent));
1940 return is_null() or is_string() or is_boolean() or is_number();
1960 return is_array() or is_object();
1979 return m_type == value_t::null;
1998 return m_type == value_t::boolean;
2022 return is_number_integer() or is_number_float();
2045 return m_type == value_t::number_integer;
2068 return m_type == value_t::number_float;
2087 return m_type == value_t::object;
2106 return m_type == value_t::array;
2125 return m_type == value_t::string;
2149 return m_type == value_t::discarded;
2180 template <
class T,
typename 2182 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2183 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2185 T get_impl(T*)
const 2189 assert(m_value.object !=
nullptr);
2190 return T(m_value.object->begin(), m_value.object->end());
2194 throw std::domain_error(
"type must be object, but is " + type_name());
2203 assert(m_value.object !=
nullptr);
2204 return *(m_value.object);
2208 throw std::domain_error(
"type must be object, but is " + type_name());
2213 template <
class T,
typename 2215 std::is_convertible<basic_json_t, typename T::value_type>::value and
2216 not std::is_same<basic_json_t, typename T::value_type>::value and
2217 not std::is_arithmetic<T>::value and
2218 not std::is_convertible<std::string, T>::value and
2219 not has_mapped_type<T>::value
2221 T get_impl(T*)
const 2226 assert(m_value.array !=
nullptr);
2227 std::transform(m_value.array->begin(), m_value.array->end(),
2228 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2230 return i.
get<
typename T::value_type>();
2236 throw std::domain_error(
"type must be array, but is " + type_name());
2241 template <
class T,
typename 2243 std::is_convertible<basic_json_t, T>::value and
2244 not std::is_same<basic_json_t, T>::value
2246 std::vector<T> get_impl(std::vector<T>*)
const 2250 std::vector<T> to_vector;
2251 assert(m_value.array !=
nullptr);
2252 to_vector.reserve(m_value.array->size());
2253 std::transform(m_value.array->begin(), m_value.array->end(),
2254 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2262 throw std::domain_error(
"type must be array, but is " + type_name());
2267 template <
class T,
typename 2269 std::is_same<basic_json, typename T::value_type>::value and
2270 not has_mapped_type<T>::value
2272 T get_impl(T*)
const 2276 assert(m_value.array !=
nullptr);
2277 return T(m_value.array->begin(), m_value.array->end());
2281 throw std::domain_error(
"type must be array, but is " + type_name());
2290 assert(m_value.array !=
nullptr);
2291 return *(m_value.array);
2295 throw std::domain_error(
"type must be array, but is " + type_name());
2300 template <
typename T,
typename 2302 std::is_convertible<string_t, T>::value
2304 T get_impl(T*)
const 2308 assert(m_value.string !=
nullptr);
2309 return *m_value.string;
2313 throw std::domain_error(
"type must be string, but is " + type_name());
2318 template<
typename T,
typename 2320 std::is_arithmetic<T>::value
2322 T get_impl(T*)
const 2326 case value_t::number_integer:
2328 return static_cast<T
>(m_value.number_integer);
2331 case value_t::number_float:
2333 return static_cast<T
>(m_value.number_float);
2338 throw std::domain_error(
"type must be number, but is " + type_name());
2348 return m_value.boolean;
2352 throw std::domain_error(
"type must be boolean, but is " + type_name());
2359 return is_object() ? m_value.object :
nullptr;
2365 return is_object() ? m_value.object :
nullptr;
2371 return is_array() ? m_value.array :
nullptr;
2377 return is_array() ? m_value.array :
nullptr;
2383 return is_string() ? m_value.string :
nullptr;
2389 return is_string() ? m_value.string :
nullptr;
2395 return is_boolean() ? &m_value.boolean :
nullptr;
2401 return is_boolean() ? &m_value.boolean :
nullptr;
2407 return is_number_integer() ? &m_value.number_integer :
nullptr;
2413 return is_number_integer() ? &m_value.number_integer :
nullptr;
2419 return is_number_float() ? &m_value.number_float :
nullptr;
2425 return is_number_float() ? &m_value.number_float :
nullptr;
2439 template<
typename ReferenceType,
typename ThisType>
2440 static ReferenceType get_ref_impl(ThisType& obj)
2443 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2444 auto ptr = obj.template get_ptr<PointerType>();
2452 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2495 template<
typename ValueType,
typename 2497 not std::is_pointer<ValueType>::value
2499 ValueType
get()
const 2501 return get_impl(static_cast<ValueType*>(
nullptr));
2530 template<
typename PointerType,
typename 2532 std::is_pointer<PointerType>::value
2534 PointerType
get() noexcept
2537 return get_ptr<PointerType>();
2544 template<
typename PointerType,
typename 2546 std::is_pointer<PointerType>::value
2548 const PointerType
get()
const noexcept
2551 return get_ptr<PointerType>();
2579 template<
typename PointerType,
typename 2581 std::is_pointer<PointerType>::value
2586 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2593 template<
typename PointerType,
typename 2595 std::is_pointer<PointerType>::value
2596 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2601 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2630 template<
typename ReferenceType,
typename 2632 std::is_reference<ReferenceType>::value
2637 return get_ref_impl<ReferenceType>(*this);
2644 template<
typename ReferenceType,
typename 2646 std::is_reference<ReferenceType>::value
2647 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2652 return get_ref_impl<ReferenceType>(*this);
2683 template <
typename ValueType,
typename 2685 not std::is_pointer<ValueType>::value
2686 and not std::is_same<ValueType, typename string_t::value_type>::value
2687 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2688 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2691 operator ValueType()
const 2694 return get<ValueType>();
2736 assert(m_value.array !=
nullptr);
2737 return m_value.array->at(idx);
2739 catch (std::out_of_range&)
2742 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2747 throw std::domain_error(
"cannot use at() with " + type_name());
2780 assert(m_value.array !=
nullptr);
2781 return m_value.array->at(idx);
2783 catch (std::out_of_range&)
2786 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2791 throw std::domain_error(
"cannot use at() with " + type_name());
2828 assert(m_value.object !=
nullptr);
2829 return m_value.object->at(key);
2831 catch (std::out_of_range&)
2834 throw std::out_of_range(
"key '" + key +
"' not found");
2839 throw std::domain_error(
"cannot use at() with " + type_name());
2876 assert(m_value.object !=
nullptr);
2877 return m_value.object->at(key);
2879 catch (std::out_of_range&)
2882 throw std::out_of_range(
"key '" + key +
"' not found");
2887 throw std::domain_error(
"cannot use at() with " + type_name());
2921 m_type = value_t::array;
2922 m_value.
array = create<array_t>();
2928 assert(m_value.array !=
nullptr);
2929 for (
size_t i = m_value.array->size(); i <= idx; ++i)
2931 m_value.array->push_back(basic_json());
2934 return m_value.array->operator[](idx);
2938 throw std::domain_error(
"cannot use operator[] with " + type_name());
2966 assert(m_value.array !=
nullptr);
2967 return m_value.array->operator[](idx);
2971 throw std::domain_error(
"cannot use operator[] with " + type_name());
3007 m_type = value_t::object;
3008 m_value.
object = create<object_t>();
3014 assert(m_value.object !=
nullptr);
3015 return m_value.object->operator[](key);
3019 throw std::domain_error(
"cannot use operator[] with " + type_name());
3055 assert(m_value.object !=
nullptr);
3056 assert(m_value.object->find(key) != m_value.object->end());
3057 return m_value.object->find(key)->second;
3061 throw std::domain_error(
"cannot use operator[] with " + type_name());
3092 template<
typename T, std::
size_t n>
3095 return operator[](static_cast<const T>(key));
3127 template<
typename T, std::
size_t n>
3130 return operator[](static_cast<const T>(key));
3160 template<
typename T>
3166 m_type = value_t::object;
3167 m_value = value_t::object;
3173 assert(m_value.object !=
nullptr);
3174 return m_value.object->operator[](key);
3178 throw std::domain_error(
"cannot use operator[] with " + type_name());
3209 template<
typename T>
3215 assert(m_value.object !=
nullptr);
3216 assert(m_value.object->find(key) != m_value.object->end());
3217 return m_value.object->find(key)->second;
3221 throw std::domain_error(
"cannot use operator[] with " + type_name());
3273 template <
class ValueType,
typename 3275 std::is_convertible<basic_json_t, ValueType>::value
3277 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3283 const auto it = find(key);
3290 return default_value;
3295 throw std::domain_error(
"cannot use value() with " + type_name());
3303 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3305 return value(key,
string_t(default_value));
3423 template <
class InteratorType,
typename 3425 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3426 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3432 if (
this != pos.m_object)
3434 throw std::domain_error(
"iterator does not fit current value");
3437 InteratorType result = end();
3441 case value_t::boolean:
3442 case value_t::number_float:
3443 case value_t::number_integer:
3444 case value_t::string:
3446 if (not pos.m_it.primitive_iterator.is_begin())
3448 throw std::out_of_range(
"iterator out of range");
3453 delete m_value.string;
3454 m_value.string =
nullptr;
3457 m_type = value_t::null;
3461 case value_t::object:
3463 assert(m_value.object !=
nullptr);
3464 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3468 case value_t::array:
3470 assert(m_value.array !=
nullptr);
3471 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3477 throw std::domain_error(
"cannot use erase() with " + type_name());
3528 template <
class InteratorType,
typename 3530 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3531 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3534 InteratorType
erase(InteratorType first, InteratorType last)
3537 if (
this != first.m_object or
this != last.m_object)
3539 throw std::domain_error(
"iterators do not fit current value");
3542 InteratorType result = end();
3546 case value_t::boolean:
3547 case value_t::number_float:
3548 case value_t::number_integer:
3549 case value_t::string:
3551 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3553 throw std::out_of_range(
"iterators out of range");
3558 delete m_value.string;
3559 m_value.string =
nullptr;
3562 m_type = value_t::null;
3566 case value_t::object:
3568 assert(m_value.object !=
nullptr);
3569 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3570 last.m_it.object_iterator);
3574 case value_t::array:
3576 assert(m_value.array !=
nullptr);
3577 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3578 last.m_it.array_iterator);
3584 throw std::domain_error(
"cannot use erase() with " + type_name());
3622 assert(m_value.object !=
nullptr);
3623 return m_value.object->erase(key);
3627 throw std::domain_error(
"cannot use erase() with " + type_name());
3662 throw std::out_of_range(
"index out of range");
3665 assert(m_value.array !=
nullptr);
3666 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3670 throw std::domain_error(
"cannot use erase() with " + type_name());
3693 auto result = end();
3697 assert(m_value.object !=
nullptr);
3698 result.m_it.object_iterator = m_value.object->find(key);
3710 auto result = cend();
3714 assert(m_value.object !=
nullptr);
3715 result.m_it.object_iterator = m_value.object->find(key);
3742 assert(not is_object() or m_value.object !=
nullptr);
3743 return is_object() ? m_value.object->count(key) : 0;
3983 template<
typename IteratorType>
class iteration_proxy;
3999 return iteration_proxy<iterator>(cont);
4007 return iteration_proxy<const_iterator>(cont);
4059 case value_t::array:
4061 assert(m_value.array !=
nullptr);
4062 return m_value.array->empty();
4065 case value_t::object:
4067 assert(m_value.object !=
nullptr);
4068 return m_value.object->empty();
4117 case value_t::array:
4119 assert(m_value.array !=
nullptr);
4120 return m_value.array->size();
4123 case value_t::object:
4125 assert(m_value.object !=
nullptr);
4126 return m_value.object->size();
4173 case value_t::array:
4175 assert(m_value.array !=
nullptr);
4176 return m_value.array->max_size();
4179 case value_t::object:
4181 assert(m_value.object !=
nullptr);
4182 return m_value.object->max_size();
4232 case value_t::number_integer:
4234 m_value.number_integer = 0;
4238 case value_t::number_float:
4240 m_value.number_float = 0.0;
4244 case value_t::boolean:
4246 m_value.boolean =
false;
4250 case value_t::string:
4252 assert(m_value.string !=
nullptr);
4253 m_value.string->clear();
4257 case value_t::array:
4259 assert(m_value.array !=
nullptr);
4260 m_value.array->clear();
4264 case value_t::object:
4266 assert(m_value.object !=
nullptr);
4267 m_value.object->clear();
4301 if (not(is_null() or is_array()))
4303 throw std::domain_error(
"cannot use push_back() with " + type_name());
4309 m_type = value_t::array;
4310 m_value = value_t::array;
4314 assert(m_value.array !=
nullptr);
4315 m_value.array->push_back(std::move(val));
4317 val.m_type = value_t::null;
4326 push_back(std::move(val));
4337 if (not(is_null() or is_array()))
4339 throw std::domain_error(
"cannot use push_back() with " + type_name());
4345 m_type = value_t::array;
4346 m_value = value_t::array;
4350 assert(m_value.array !=
nullptr);
4351 m_value.array->push_back(val);
4387 if (not(is_null() or is_object()))
4389 throw std::domain_error(
"cannot use push_back() with " + type_name());
4395 m_type = value_t::object;
4396 m_value = value_t::object;
4400 assert(m_value.object !=
nullptr);
4401 m_value.object->insert(val);
4411 return operator[](val.first);
4442 if (pos.m_object !=
this)
4444 throw std::domain_error(
"iterator does not fit current value");
4449 assert(m_value.array !=
nullptr);
4450 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4455 throw std::domain_error(
"cannot use insert() with " + type_name());
4465 return insert(pos, val);
4498 if (pos.m_object !=
this)
4500 throw std::domain_error(
"iterator does not fit current value");
4505 assert(m_value.array !=
nullptr);
4506 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4511 throw std::domain_error(
"cannot use insert() with " + type_name());
4550 throw std::domain_error(
"cannot use insert() with " + type_name());
4554 if (pos.m_object !=
this)
4556 throw std::domain_error(
"iterator does not fit current value");
4559 if (first.m_object != last.m_object)
4561 throw std::domain_error(
"iterators do not fit");
4564 if (first.m_object ==
this or last.m_object ==
this)
4566 throw std::domain_error(
"passed iterators may not belong to container");
4571 assert(m_value.array !=
nullptr);
4572 result.m_it.array_iterator = m_value.array->insert(
4573 pos.m_it.array_iterator,
4574 first.m_it.array_iterator,
4575 last.m_it.array_iterator);
4608 throw std::domain_error(
"cannot use insert() with " + type_name());
4612 if (pos.m_object !=
this)
4614 throw std::domain_error(
"iterator does not fit current value");
4619 assert(m_value.array !=
nullptr);
4620 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4642 std::is_nothrow_move_constructible<value_t>::value and
4643 std::is_nothrow_move_assignable<value_t>::value and
4644 std::is_nothrow_move_constructible<json_value>::value and
4645 std::is_nothrow_move_assignable<json_value>::value
4648 std::swap(m_type, other.m_type);
4649 std::swap(m_value, other.m_value);
4677 assert(m_value.array !=
nullptr);
4678 std::swap(*(m_value.array), other);
4682 throw std::domain_error(
"cannot use swap() with " + type_name());
4711 assert(m_value.object !=
nullptr);
4712 std::swap(*(m_value.object), other);
4716 throw std::domain_error(
"cannot use swap() with " + type_name());
4745 assert(m_value.string !=
nullptr);
4746 std::swap(*(m_value.string), other);
4750 throw std::domain_error(
"cannot use swap() with " + type_name());
4776 static constexpr std::array<uint8_t, 7> order = {{
4788 if (lhs == value_t::discarded or rhs == value_t::discarded)
4793 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
4822 const auto lhs_type = lhs.type();
4823 const auto rhs_type = rhs.type();
4825 if (lhs_type == rhs_type)
4829 case value_t::array:
4831 assert(lhs.m_value.array !=
nullptr);
4832 assert(rhs.m_value.array !=
nullptr);
4833 return *lhs.m_value.array == *rhs.m_value.array;
4835 case value_t::object:
4837 assert(lhs.m_value.object !=
nullptr);
4838 assert(rhs.m_value.object !=
nullptr);
4839 return *lhs.m_value.object == *rhs.m_value.object;
4845 case value_t::string:
4847 assert(lhs.m_value.string !=
nullptr);
4848 assert(rhs.m_value.string !=
nullptr);
4849 return *lhs.m_value.string == *rhs.m_value.string;
4851 case value_t::boolean:
4853 return lhs.m_value.boolean == rhs.m_value.boolean;
4855 case value_t::number_integer:
4857 return lhs.m_value.number_integer == rhs.m_value.number_integer;
4859 case value_t::number_float:
4861 return lhs.m_value.number_float == rhs.m_value.number_float;
4869 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
4871 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
4873 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
4875 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
4930 return not (lhs == rhs);
4962 return not v.is_null();
4991 const auto lhs_type = lhs.type();
4992 const auto rhs_type = rhs.type();
4994 if (lhs_type == rhs_type)
4998 case value_t::array:
5000 assert(lhs.m_value.array !=
nullptr);
5001 assert(rhs.m_value.array !=
nullptr);
5002 return *lhs.m_value.array < *rhs.m_value.array;
5004 case value_t::object:
5006 assert(lhs.m_value.object !=
nullptr);
5007 assert(rhs.m_value.object !=
nullptr);
5008 return *lhs.m_value.object < *rhs.m_value.object;
5014 case value_t::string:
5016 assert(lhs.m_value.string !=
nullptr);
5017 assert(rhs.m_value.string !=
nullptr);
5018 return *lhs.m_value.string < *rhs.m_value.string;
5020 case value_t::boolean:
5022 return lhs.m_value.boolean < rhs.m_value.boolean;
5024 case value_t::number_integer:
5026 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5028 case value_t::number_float:
5030 return lhs.m_value.number_float < rhs.m_value.number_float;
5038 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5041 rhs.m_value.number_float;
5043 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5045 return lhs.m_value.number_float <
5052 return operator<(lhs_type, rhs_type);
5074 return not (rhs < lhs);
5096 return not (lhs <= rhs);
5118 return not (lhs < rhs);
5153 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5156 const bool pretty_print = (o.width() > 0);
5157 const auto indentation = (pretty_print ? o.width() : 0);
5163 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5171 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5212 return parser(s, cb).
parse();
5241 return parser(i, cb).
parse();
5249 return parser(i, cb).
parse();
5277 j = parser(i).
parse();
5287 j = parser(i).
parse();
5306 case value_t::object:
5308 case value_t::array:
5310 case value_t::string:
5312 case value_t::boolean:
5314 case value_t::discarded:
5329 static std::size_t extra_space(
const string_t& s) noexcept
5331 std::size_t result = 0;
5333 for (
const auto& c : s)
5352 if (c >= 0x00 and c <= 0x1f)
5380 const auto space = extra_space(s);
5387 string_t result(s.size() + space,
'\\');
5388 std::size_t pos = 0;
5390 for (
const auto& c : s)
5397 result[pos + 1] =
'"';
5413 result[pos + 1] =
'b';
5421 result[pos + 1] =
'f';
5429 result[pos + 1] =
'n';
5437 result[pos + 1] =
'r';
5445 result[pos + 1] =
't';
5452 if (c >= 0x00 and c <= 0x1f)
5455 auto hexify = [](
const char v) ->
char 5457 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5462 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5500 void dump(std::ostream& o,
5501 const bool pretty_print,
5502 const unsigned int indent_step,
5503 const unsigned int current_indent = 0)
const 5506 unsigned int new_indent = current_indent;
5510 case value_t::object:
5512 assert(m_value.object !=
nullptr);
5514 if (m_value.object->empty())
5525 new_indent += indent_step;
5529 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5531 if (i != m_value.object->cbegin())
5533 o << (pretty_print ?
",\n" :
",");
5535 o <<
string_t(new_indent,
' ') <<
"\"" 5536 << escape_string(i->first) <<
"\":" 5537 << (pretty_print ?
" " :
"");
5538 i->second.dump(o, pretty_print, indent_step, new_indent);
5544 new_indent -= indent_step;
5548 o <<
string_t(new_indent,
' ') +
"}";
5552 case value_t::array:
5554 assert(m_value.array !=
nullptr);
5556 if (m_value.array->empty())
5567 new_indent += indent_step;
5571 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5573 if (i != m_value.array->cbegin())
5575 o << (pretty_print ?
",\n" :
",");
5578 i->dump(o, pretty_print, indent_step, new_indent);
5584 new_indent -= indent_step;
5588 o <<
string_t(new_indent,
' ') <<
"]";
5592 case value_t::string:
5594 assert(m_value.string !=
nullptr);
5595 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5599 case value_t::boolean:
5601 o << (m_value.boolean ?
"true" :
"false");
5605 case value_t::number_integer:
5607 o << m_value.number_integer;
5611 case value_t::number_float:
5619 if (std::fmod(m_value.number_float, 1) == 0)
5621 o << std::fixed << std::setprecision(1);
5626 o.unsetf(std::ios_base::floatfield);
5627 o << std::setprecision(std::numeric_limits<double>::digits10);
5629 o << m_value.number_float;
5633 case value_t::discarded:
5653 value_t m_type = value_t::null;
5656 json_value m_value = {};
5673 class primitive_iterator_t
5689 bool is_begin()
const 5691 return (m_it == begin_value);
5697 return (m_it == end_value);
5717 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5727 struct internal_iterator
5730 typename object_t::iterator object_iterator;
5732 typename array_t::iterator array_iterator;
5734 primitive_iterator_t primitive_iterator;
5738 : object_iterator(), array_iterator(), primitive_iterator()
5743 template<
typename IteratorType>
5744 class iteration_proxy
5748 class iteration_proxy_internal
5752 IteratorType anchor;
5754 size_t array_index = 0;
5757 iteration_proxy_internal(IteratorType it)
5762 iteration_proxy_internal& operator*()
5768 iteration_proxy_internal& operator++()
5777 bool operator!= (
const iteration_proxy_internal& o)
const 5779 return anchor != o.anchor;
5785 assert(anchor.m_object !=
nullptr);
5787 switch (anchor.m_object->type())
5790 case value_t::array:
5792 return std::to_string(array_index);
5796 case value_t::object:
5798 return anchor.key();
5810 typename IteratorType::reference value()
const 5812 return anchor.value();
5817 typename IteratorType::reference container;
5821 iteration_proxy(
typename IteratorType::reference cont)
5826 iteration_proxy_internal begin()
5828 return iteration_proxy_internal(container.begin());
5832 iteration_proxy_internal end()
5834 return iteration_proxy_internal(container.end());
5852 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
5855 friend class basic_json;
5875 assert(m_object !=
nullptr);
5877 switch (m_object->m_type)
5881 m_it.object_iterator =
typename object_t::iterator();
5887 m_it.array_iterator =
typename array_t::iterator();
5893 m_it.primitive_iterator = primitive_iterator_t();
5902 assert(m_object !=
nullptr);
5904 switch (m_object->m_type)
5908 m_it.object_iterator = other.m_it.object_iterator;
5914 m_it.array_iterator = other.m_it.array_iterator;
5920 m_it.primitive_iterator = other.m_it.primitive_iterator;
5928 : m_object(other.m_object), m_it(other.m_it)
5933 std::is_nothrow_move_constructible<pointer>::value and
5934 std::is_nothrow_move_assignable<pointer>::value and
5935 std::is_nothrow_move_constructible<internal_iterator>::value and
5936 std::is_nothrow_move_assignable<internal_iterator>::value
5939 std::swap(m_object, other.m_object);
5940 std::swap(m_it, other.m_it);
5948 assert(m_object !=
nullptr);
5950 switch (m_object->m_type)
5954 assert(m_object->m_value.object !=
nullptr);
5955 m_it.object_iterator = m_object->m_value.object->begin();
5961 assert(m_object->m_value.array !=
nullptr);
5962 m_it.array_iterator = m_object->m_value.array->begin();
5969 m_it.primitive_iterator.set_end();
5975 m_it.primitive_iterator.set_begin();
5984 assert(m_object !=
nullptr);
5986 switch (m_object->m_type)
5990 assert(m_object->m_value.object !=
nullptr);
5991 m_it.object_iterator = m_object->m_value.object->end();
5997 assert(m_object->m_value.array !=
nullptr);
5998 m_it.array_iterator = m_object->m_value.array->end();
6004 m_it.primitive_iterator.set_end();
6014 assert(m_object !=
nullptr);
6016 switch (m_object->m_type)
6020 assert(m_object->m_value.object);
6021 assert(m_it.object_iterator != m_object->m_value.object->end());
6022 return m_it.object_iterator->second;
6027 assert(m_object->m_value.array);
6028 assert(m_it.array_iterator != m_object->m_value.array->end());
6029 return *m_it.array_iterator;
6034 throw std::out_of_range(
"cannot get value");
6039 if (m_it.primitive_iterator.is_begin())
6045 throw std::out_of_range(
"cannot get value");
6054 assert(m_object !=
nullptr);
6056 switch (m_object->m_type)
6060 assert(m_object->m_value.object);
6061 assert(m_it.object_iterator != m_object->m_value.object->end());
6062 return &(m_it.object_iterator->second);
6067 assert(m_object->m_value.array);
6068 assert(m_it.array_iterator != m_object->m_value.array->end());
6069 return &*m_it.array_iterator;
6074 if (m_it.primitive_iterator.is_begin())
6080 throw std::out_of_range(
"cannot get value");
6089 auto result = *
this;
6097 assert(m_object !=
nullptr);
6099 switch (m_object->m_type)
6103 ++m_it.object_iterator;
6109 ++m_it.array_iterator;
6115 ++m_it.primitive_iterator;
6126 auto result = *
this;
6134 assert(m_object !=
nullptr);
6136 switch (m_object->m_type)
6140 --m_it.object_iterator;
6146 --m_it.array_iterator;
6152 --m_it.primitive_iterator;
6164 if (m_object != other.m_object)
6166 throw std::domain_error(
"cannot compare iterators of different containers");
6169 assert(m_object !=
nullptr);
6171 switch (m_object->m_type)
6175 return (m_it.object_iterator == other.m_it.object_iterator);
6180 return (m_it.array_iterator == other.m_it.array_iterator);
6185 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6193 return not operator==(other);
6200 if (m_object != other.m_object)
6202 throw std::domain_error(
"cannot compare iterators of different containers");
6205 assert(m_object !=
nullptr);
6207 switch (m_object->m_type)
6211 throw std::domain_error(
"cannot compare order of object iterators");
6216 return (m_it.array_iterator < other.m_it.array_iterator);
6221 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6229 return not other.operator < (*this);
6235 return not operator<=(other);
6241 return not operator<(other);
6247 assert(m_object !=
nullptr);
6249 switch (m_object->m_type)
6253 throw std::domain_error(
"cannot use offsets with object iterators");
6258 m_it.array_iterator += i;
6264 m_it.primitive_iterator += i;
6275 return operator+=(-i);
6281 auto result = *
this;
6289 auto result = *
this;
6297 assert(m_object !=
nullptr);
6299 switch (m_object->m_type)
6303 throw std::domain_error(
"cannot use offsets with object iterators");
6308 return m_it.array_iterator - other.m_it.array_iterator;
6313 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6321 assert(m_object !=
nullptr);
6323 switch (m_object->m_type)
6327 throw std::domain_error(
"cannot use operator[] for object iterators");
6332 return *(m_it.array_iterator + n);
6337 throw std::out_of_range(
"cannot get value");
6342 if (m_it.primitive_iterator == -n)
6348 throw std::out_of_range(
"cannot get value");
6355 typename object_t::key_type
key()
const 6357 assert(m_object !=
nullptr);
6359 if (m_object->is_object())
6361 return m_it.object_iterator->first;
6365 throw std::domain_error(
"cannot use key() for non-object iterators");
6379 internal_iterator m_it = internal_iterator();
6416 std::is_nothrow_move_constructible<pointer>::value and
6417 std::is_nothrow_move_assignable<pointer>::value and
6418 std::is_nothrow_move_constructible<internal_iterator>::value and
6419 std::is_nothrow_move_assignable<internal_iterator>::value
6422 base_iterator::operator=(other);
6429 return const_cast<reference>(base_iterator::operator*());
6435 return const_cast<pointer>(base_iterator::operator->());
6442 base_iterator::operator++();
6449 base_iterator::operator++();
6457 base_iterator::operator--();
6464 base_iterator::operator--();
6471 base_iterator::operator+=(i);
6478 base_iterator::operator-=(i);
6485 auto result = *
this;
6493 auto result = *
this;
6500 return base_iterator::operator-(other);
6506 return const_cast<reference>(base_iterator::operator[](n));
6512 return const_cast<reference>(base_iterator::value());
6533 template<
typename Base>
6555 return base_iterator::operator++(1);
6561 base_iterator::operator++();
6568 return base_iterator::operator--(1);
6574 base_iterator::operator--();
6581 base_iterator::operator+=(i);
6588 auto result = *
this;
6596 auto result = *
this;
6604 return this->base() - other.base();
6610 return *(this->operator+(n));
6614 typename object_t::key_type
key()
const 6616 auto it = --this->base();
6623 auto it = --this->base();
6624 return it.operator * ();
6645 enum class token_type
6664 using lexer_char_t =
unsigned char;
6667 explicit lexer(
const string_t& s) noexcept
6668 : m_stream(
nullptr), m_buffer(s)
6670 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6671 assert(m_content !=
nullptr);
6672 m_start = m_cursor = m_content;
6673 m_limit = m_content + s.size();
6677 explicit lexer(std::istream* s) noexcept
6678 : m_stream(s), m_buffer()
6680 assert(m_stream !=
nullptr);
6681 getline(*m_stream, m_buffer);
6682 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6683 assert(m_content !=
nullptr);
6684 m_start = m_cursor = m_content;
6685 m_limit = m_content + m_buffer.size();
6692 lexer(
const lexer&) =
delete;
6693 lexer operator=(
const lexer&) =
delete;
6710 static string_t to_unicode(
const std::size_t codepoint1,
6711 const std::size_t codepoint2 = 0)
6716 std::size_t codepoint = codepoint1;
6719 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6722 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6736 throw std::invalid_argument(
"missing or wrong low surrogate");
6740 if (codepoint < 0x80)
6743 result.append(1, static_cast<typename string_t::value_type>(codepoint));
6745 else if (codepoint <= 0x7ff)
6748 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6749 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6751 else if (codepoint <= 0xffff)
6754 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
6755 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6756 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6758 else if (codepoint <= 0x10ffff)
6761 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
6762 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
6763 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
6764 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
6768 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
6775 static std::string token_type_name(token_type t)
6779 case token_type::uninitialized:
6780 return "<uninitialized>";
6781 case token_type::literal_true:
6782 return "true literal";
6783 case token_type::literal_false:
6784 return "false literal";
6785 case token_type::literal_null:
6786 return "null literal";
6787 case token_type::value_string:
6788 return "string literal";
6789 case token_type::value_number:
6790 return "number literal";
6791 case token_type::begin_array:
6793 case token_type::begin_object:
6795 case token_type::end_array:
6797 case token_type::end_object:
6799 case token_type::name_separator:
6801 case token_type::value_separator:
6803 case token_type::parse_error:
6804 return "<parse error>";
6805 case token_type::end_of_input:
6806 return "end of input";
6810 return "unknown token";
6825 token_type scan() noexcept
6832 assert(m_start !=
nullptr);
6837 unsigned int yyaccept = 0;
6838 static const unsigned char yybm[] =
6840 0, 0, 0, 0, 0, 0, 0, 0,
6841 0, 32, 32, 0, 0, 32, 0, 0,
6842 64, 64, 64, 64, 64, 64, 64, 64,
6843 64, 64, 64, 64, 64, 64, 64, 64,
6844 96, 64, 0, 64, 64, 64, 64, 64,
6845 64, 64, 64, 64, 64, 64, 64, 64,
6846 192, 192, 192, 192, 192, 192, 192, 192,
6847 192, 192, 64, 64, 64, 64, 64, 64,
6848 64, 64, 64, 64, 64, 64, 64, 64,
6849 64, 64, 64, 64, 64, 64, 64, 64,
6850 64, 64, 64, 64, 64, 64, 64, 64,
6851 64, 64, 64, 64, 0, 64, 64, 64,
6852 64, 64, 64, 64, 64, 64, 64, 64,
6853 64, 64, 64, 64, 64, 64, 64, 64,
6854 64, 64, 64, 64, 64, 64, 64, 64,
6855 64, 64, 64, 64, 64, 64, 64, 64,
6856 64, 64, 64, 64, 64, 64, 64, 64,
6857 64, 64, 64, 64, 64, 64, 64, 64,
6858 64, 64, 64, 64, 64, 64, 64, 64,
6859 64, 64, 64, 64, 64, 64, 64, 64,
6860 64, 64, 64, 64, 64, 64, 64, 64,
6861 64, 64, 64, 64, 64, 64, 64, 64,
6862 64, 64, 64, 64, 64, 64, 64, 64,
6863 64, 64, 64, 64, 64, 64, 64, 64,
6864 64, 64, 64, 64, 64, 64, 64, 64,
6865 64, 64, 64, 64, 64, 64, 64, 64,
6866 64, 64, 64, 64, 64, 64, 64, 64,
6867 64, 64, 64, 64, 64, 64, 64, 64,
6868 64, 64, 64, 64, 64, 64, 64, 64,
6869 64, 64, 64, 64, 64, 64, 64, 64,
6870 64, 64, 64, 64, 64, 64, 64, 64,
6871 64, 64, 64, 64, 64, 64, 64, 64,
6873 if ((m_limit - m_cursor) < 5)
6886 goto basic_json_parser_28;
6890 goto basic_json_parser_30;
6894 goto basic_json_parser_4;
6901 goto basic_json_parser_2;
6905 goto basic_json_parser_30;
6915 goto basic_json_parser_27;
6919 goto basic_json_parser_30;
6921 goto basic_json_parser_16;
6929 goto basic_json_parser_23;
6931 goto basic_json_parser_30;
6937 goto basic_json_parser_24;
6941 goto basic_json_parser_26;
6943 goto basic_json_parser_18;
6956 goto basic_json_parser_8;
6960 goto basic_json_parser_30;
6962 goto basic_json_parser_10;
6968 goto basic_json_parser_22;
6972 goto basic_json_parser_30;
6974 goto basic_json_parser_20;
6983 goto basic_json_parser_21;
6987 goto basic_json_parser_30;
6989 goto basic_json_parser_12;
6997 goto basic_json_parser_30;
6999 goto basic_json_parser_14;
7005 goto basic_json_parser_6;
7007 goto basic_json_parser_30;
7012 basic_json_parser_2:
7015 goto basic_json_parser_5;
7016 basic_json_parser_3:
7020 basic_json_parser_4:
7022 if (m_limit <= m_cursor)
7027 basic_json_parser_5:
7028 if (yybm[0 + yych] & 32)
7030 goto basic_json_parser_4;
7032 goto basic_json_parser_3;
7033 basic_json_parser_6:
7035 yych = *(m_marker = ++m_cursor);
7038 goto basic_json_parser_64;
7040 basic_json_parser_7:
7042 return token_type::parse_error;
7044 basic_json_parser_8:
7047 return token_type::begin_array;
7049 basic_json_parser_10:
7052 return token_type::end_array;
7054 basic_json_parser_12:
7057 return token_type::begin_object;
7059 basic_json_parser_14:
7062 return token_type::end_object;
7064 basic_json_parser_16:
7067 return token_type::value_separator;
7069 basic_json_parser_18:
7072 return token_type::name_separator;
7074 basic_json_parser_20:
7076 yych = *(m_marker = ++m_cursor);
7079 goto basic_json_parser_60;
7081 goto basic_json_parser_7;
7082 basic_json_parser_21:
7084 yych = *(m_marker = ++m_cursor);
7087 goto basic_json_parser_56;
7089 goto basic_json_parser_7;
7090 basic_json_parser_22:
7092 yych = *(m_marker = ++m_cursor);
7095 goto basic_json_parser_51;
7097 goto basic_json_parser_7;
7098 basic_json_parser_23:
7102 goto basic_json_parser_7;
7106 goto basic_json_parser_50;
7110 goto basic_json_parser_41;
7112 goto basic_json_parser_7;
7113 basic_json_parser_24:
7115 yych = *(m_marker = ++m_cursor);
7120 goto basic_json_parser_43;
7127 goto basic_json_parser_44;
7131 goto basic_json_parser_44;
7134 basic_json_parser_25:
7136 return token_type::value_number;
7138 basic_json_parser_26:
7140 yych = *(m_marker = ++m_cursor);
7141 goto basic_json_parser_42;
7142 basic_json_parser_27:
7144 yych = *(m_marker = ++m_cursor);
7147 goto basic_json_parser_7;
7149 goto basic_json_parser_32;
7150 basic_json_parser_28:
7153 return token_type::end_of_input;
7155 basic_json_parser_30:
7157 goto basic_json_parser_7;
7158 basic_json_parser_31:
7160 if (m_limit <= m_cursor)
7165 basic_json_parser_32:
7166 if (yybm[0 + yych] & 64)
7168 goto basic_json_parser_31;
7172 goto basic_json_parser_33;
7176 goto basic_json_parser_35;
7178 goto basic_json_parser_34;
7179 basic_json_parser_33:
7180 m_cursor = m_marker;
7183 goto basic_json_parser_7;
7187 goto basic_json_parser_25;
7189 basic_json_parser_34:
7191 if (m_limit <= m_cursor)
7202 goto basic_json_parser_31;
7206 goto basic_json_parser_33;
7208 goto basic_json_parser_31;
7216 goto basic_json_parser_33;
7218 goto basic_json_parser_31;
7224 goto basic_json_parser_31;
7226 goto basic_json_parser_33;
7236 goto basic_json_parser_31;
7240 goto basic_json_parser_31;
7242 goto basic_json_parser_33;
7250 goto basic_json_parser_31;
7252 goto basic_json_parser_33;
7258 goto basic_json_parser_31;
7262 goto basic_json_parser_37;
7264 goto basic_json_parser_33;
7268 basic_json_parser_35:
7271 return token_type::value_string;
7273 basic_json_parser_37:
7275 if (m_limit <= m_cursor)
7284 goto basic_json_parser_33;
7288 goto basic_json_parser_33;
7295 goto basic_json_parser_38;
7299 goto basic_json_parser_33;
7303 goto basic_json_parser_33;
7306 basic_json_parser_38:
7308 if (m_limit <= m_cursor)
7317 goto basic_json_parser_33;
7321 goto basic_json_parser_33;
7328 goto basic_json_parser_39;
7332 goto basic_json_parser_33;
7336 goto basic_json_parser_33;
7339 basic_json_parser_39:
7341 if (m_limit <= m_cursor)
7350 goto basic_json_parser_33;
7354 goto basic_json_parser_33;
7361 goto basic_json_parser_40;
7365 goto basic_json_parser_33;
7369 goto basic_json_parser_33;
7372 basic_json_parser_40:
7374 if (m_limit <= m_cursor)
7383 goto basic_json_parser_33;
7387 goto basic_json_parser_31;
7389 goto basic_json_parser_33;
7395 goto basic_json_parser_31;
7399 goto basic_json_parser_33;
7403 goto basic_json_parser_31;
7405 goto basic_json_parser_33;
7407 basic_json_parser_41:
7409 m_marker = ++m_cursor;
7410 if ((m_limit - m_cursor) < 3)
7415 basic_json_parser_42:
7416 if (yybm[0 + yych] & 128)
7418 goto basic_json_parser_41;
7424 goto basic_json_parser_25;
7431 goto basic_json_parser_44;
7435 goto basic_json_parser_44;
7437 goto basic_json_parser_25;
7439 basic_json_parser_43:
7443 goto basic_json_parser_33;
7447 goto basic_json_parser_48;
7449 goto basic_json_parser_33;
7450 basic_json_parser_44:
7456 goto basic_json_parser_33;
7463 goto basic_json_parser_45;
7467 goto basic_json_parser_33;
7471 goto basic_json_parser_46;
7473 goto basic_json_parser_33;
7475 basic_json_parser_45:
7479 goto basic_json_parser_33;
7483 goto basic_json_parser_33;
7485 basic_json_parser_46:
7487 if (m_limit <= m_cursor)
7494 goto basic_json_parser_25;
7498 goto basic_json_parser_46;
7500 goto basic_json_parser_25;
7501 basic_json_parser_48:
7503 m_marker = ++m_cursor;
7504 if ((m_limit - m_cursor) < 3)
7513 goto basic_json_parser_25;
7517 goto basic_json_parser_48;
7519 goto basic_json_parser_25;
7525 goto basic_json_parser_44;
7529 goto basic_json_parser_44;
7531 goto basic_json_parser_25;
7533 basic_json_parser_50:
7535 yych = *(m_marker = ++m_cursor);
7540 goto basic_json_parser_43;
7542 goto basic_json_parser_25;
7548 goto basic_json_parser_44;
7552 goto basic_json_parser_44;
7554 goto basic_json_parser_25;
7556 basic_json_parser_51:
7560 goto basic_json_parser_33;
7565 goto basic_json_parser_33;
7570 goto basic_json_parser_33;
7574 return token_type::literal_false;
7576 basic_json_parser_56:
7580 goto basic_json_parser_33;
7585 goto basic_json_parser_33;
7589 return token_type::literal_true;
7591 basic_json_parser_60:
7595 goto basic_json_parser_33;
7600 goto basic_json_parser_33;
7604 return token_type::literal_null;
7606 basic_json_parser_64:
7610 goto basic_json_parser_33;
7622 void yyfill() noexcept
7624 if (m_stream ==
nullptr or not * m_stream)
7629 const ssize_t offset_start = m_start - m_content;
7630 const ssize_t offset_marker = m_marker - m_start;
7631 const ssize_t offset_cursor = m_cursor - m_start;
7633 m_buffer.erase(0, static_cast<size_t>(offset_start));
7635 assert(m_stream !=
nullptr);
7636 std::getline(*m_stream, line);
7637 m_buffer +=
"\n" + line;
7639 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7640 assert(m_content !=
nullptr);
7641 m_start = m_content;
7642 m_marker = m_start + offset_marker;
7643 m_cursor = m_start + offset_cursor;
7644 m_limit = m_start + m_buffer.size() - 1;
7648 string_t get_token()
const noexcept
7650 assert(m_start !=
nullptr);
7651 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7652 static_cast<size_t>(m_cursor - m_start));
7679 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7682 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7738 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7739 4).c_str(),
nullptr, 16);
7742 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7745 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7747 throw std::invalid_argument(
"missing low surrogate");
7751 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7752 (i + 7), 4).c_str(),
nullptr, 16);
7753 result += to_unicode(codepoint, codepoint2);
7760 result += to_unicode(codepoint);
7772 result.append(1, static_cast<typename string_t::value_type>(*i));
7799 long double str_to_float_t(
long double* ,
char** endptr)
const 7801 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7805 double str_to_float_t(
double*,
char** endptr)
const 7807 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7811 float str_to_float_t(
float*,
char** endptr)
const 7813 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7836 typename string_t::value_type* endptr;
7837 assert(m_start !=
nullptr);
7838 number_float_t float_val = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
7842 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7847 std::istream* m_stream =
nullptr;
7851 const lexer_char_t* m_content =
nullptr;
7853 const lexer_char_t* m_start =
nullptr;
7855 const lexer_char_t* m_marker =
nullptr;
7857 const lexer_char_t* m_cursor =
nullptr;
7859 const lexer_char_t* m_limit =
nullptr;
7872 : callback(cb), m_lexer(s)
7880 : callback(cb), m_lexer(&_is)
7889 basic_json result = parse_internal(
true);
7891 expect(lexer::token_type::end_of_input);
7900 basic_json parse_internal(
bool keep)
7902 auto result = basic_json(value_t::discarded);
7906 case lexer::token_type::begin_object:
7908 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7911 result.m_type = value_t::object;
7912 result.m_value = json_value(value_t::object);
7919 if (last_token == lexer::token_type::end_object)
7922 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7924 result = basic_json(value_t::discarded);
7930 unexpect(lexer::token_type::value_separator);
7936 if (last_token == lexer::token_type::value_separator)
7942 expect(lexer::token_type::value_string);
7943 const auto key = m_lexer.get_string();
7945 bool keep_tag =
false;
7951 keep_tag = callback(depth, parse_event_t::key, k);
7961 expect(lexer::token_type::name_separator);
7965 auto value = parse_internal(keep);
7966 if (keep and keep_tag and not value.is_discarded())
7968 result[key] = std::move(value);
7971 while (last_token == lexer::token_type::value_separator);
7974 expect(lexer::token_type::end_object);
7976 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7978 result = basic_json(value_t::discarded);
7984 case lexer::token_type::begin_array:
7986 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7989 result.m_type = value_t::array;
7990 result.m_value = json_value(value_t::array);
7997 if (last_token == lexer::token_type::end_array)
8000 if (callback and not callback(--depth, parse_event_t::array_end, result))
8002 result = basic_json(value_t::discarded);
8008 unexpect(lexer::token_type::value_separator);
8014 if (last_token == lexer::token_type::value_separator)
8020 auto value = parse_internal(keep);
8021 if (keep and not value.is_discarded())
8023 result.push_back(std::move(value));
8026 while (last_token == lexer::token_type::value_separator);
8029 expect(lexer::token_type::end_array);
8031 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8033 result = basic_json(value_t::discarded);
8039 case lexer::token_type::literal_null:
8042 result.m_type = value_t::null;
8046 case lexer::token_type::value_string:
8048 const auto s = m_lexer.get_string();
8050 result = basic_json(s);
8054 case lexer::token_type::literal_true:
8057 result.m_type = value_t::boolean;
8058 result.m_value =
true;
8062 case lexer::token_type::literal_false:
8065 result.m_type = value_t::boolean;
8066 result.m_value =
false;
8070 case lexer::token_type::value_number:
8072 result.m_value = m_lexer.get_number();
8076 if (std::isnan(result.m_value.number_float))
8078 throw std::invalid_argument(std::string(
"parse error - ") +
8079 m_lexer.get_token() +
" is not a number");
8085 const auto int_val =
static_cast<number_integer_t>(result.m_value.number_float);
8086 if (result.m_value.number_float == static_cast<number_float_t>(int_val) and
8087 result.m_value.number_integer != json_value(-0.0f).number_integer)
8090 result.m_type = value_t::number_integer;
8091 result.m_value = int_val;
8096 result.m_type = value_t::number_float;
8104 unexpect(last_token);
8108 if (keep and callback and not callback(depth, parse_event_t::value, result))
8110 result = basic_json(value_t::discarded);
8116 typename lexer::token_type get_token()
8118 last_token = m_lexer.scan();
8122 void expect(
typename lexer::token_type t)
const 8124 if (t != last_token)
8126 std::string error_msg =
"parse error - unexpected ";
8127 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8128 lexer::token_type_name(last_token));
8129 error_msg +=
"; expected " + lexer::token_type_name(t);
8130 throw std::invalid_argument(error_msg);
8134 void unexpect(
typename lexer::token_type t)
const 8136 if (t == last_token)
8138 std::string error_msg =
"parse error - unexpected ";
8139 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8140 lexer::token_type_name(last_token));
8141 throw std::invalid_argument(error_msg);
8151 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8189 is_nothrow_move_constructible<nlohmann::json>::value and
8190 is_nothrow_move_assignable<nlohmann::json>::value
8208 const auto& h = hash<nlohmann::json::string_t>();
8226 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8232 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8233 #pragma GCC diagnostic pop bool operator!=(const const_iterator &other) const
comparison: not equal
iterator insert(const_iterator pos, basic_json &&val)
inserts element
iterator operator++(int)
post-increment (it++)
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
const_reference operator[](size_type idx) const
access specified array element
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
const_iterator & operator--()
pre-decrement (–it)
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
const_iterator & operator=(const_iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
reference & operator=(basic_json other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
copy assignment
const_reference operator[](T *key) const
read-only access specified object element
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
json_reverse_iterator operator--(int)
post-decrement (it–)
StringType string_t
a type for a string
void push_back(const typename object_t::value_type &val)
add an object to an object
basic_json(boolean_t val)
create a boolean (explicit)
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
iterator & operator++()
pre-increment (++it)
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
const_iterator & operator++()
pre-increment (++it)
difference_type operator-(const json_reverse_iterator &other) const
return difference
basic_json<> json
default JSON class
reference front()
access the first element
bool is_array() const noexcept
return whether value is an array
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
json_reverse_iterator(const typename base_iterator::iterator_type &it)
create reverse iterator from iterator
a class to store JSON values
json_reverse_iterator & operator--()
pre-decrement (–it)
basic_json(const object_t &val)
create an object (explicit)
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
void push_back(basic_json &&val)
add an object to an array
const_iterator cbegin() const
returns a const iterator to the first element
reference operator[](T *key)
access specified object element
bool is_string() const noexcept
return whether value is a string
iterator & operator+=(difference_type i)
add to iterator
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
basic_json(const CompatibleStringType &val)
create a string (implicit)
reference operator+=(basic_json &&val)
add an object to an array
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
a mutable random access iterator for the basic_json class
iterator & operator-=(difference_type i)
subtract from iterator
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
reference operator[](const typename object_t::key_type &key)
access specified object element
difference_type operator-(const iterator &other) const
reference value() const
return the value of an iterator
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
const_iterator end() const
returns a const iterator to one past the last element
const_iterator(const const_iterator &other) noexcept
copy constructor
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
object_t::key_type key() const
return the key of an object iterator
iterator end()
returns an iterator to one past the last element
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
reference operator*()
return a reference to the value pointed to by the iterator
reverse_iterator rend()
returns an iterator to the reverse-end
bool is_object() const noexcept
return whether value is an object
const_iterator operator-(difference_type i)
subtract from iterator
bool is_discarded() const noexcept
return whether value is discarded
basic_json(const CompatibleArrayType &val)
create an array (implicit)
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
const_reverse_iterator rend() const
returns a const reverse iterator to one before the first
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
bool is_boolean() const noexcept
return whether value is a boolean
iterator begin()
returns an iterator to the first element
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
reference operator+=(const basic_json &val)
add an object to an array
AllocatorType< basic_json > allocator_type
the allocator type
basic_json(const number_float_t val)
create a floating-point number (explicit)
reference operator[](T *(&key)[n])
access specified object element
bool is_number_integer() const noexcept
return whether value is an integer number
iterator operator+(difference_type i)
add to iterator
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
basic_json(const typename string_t::value_type *val)
create a string (explicit)
iterator find(typename object_t::key_type key)
find an element in a JSON object
basic_json(const value_t value_type)
create an empty value with a given type
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
iterator & operator--()
pre-decrement (–it)
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
pointer operator->() const
dereference the iterator
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
const_iterator cend() const
returns a const iterator to one past the last element
typename Base::reference reference
the reference type for the pointed-to element
size_type size() const noexcept
returns the number of elements
static allocator_type get_allocator()
returns the allocator associated with the container
object (unordered set of name/value pairs)
ReferenceType get_ref()
get a reference value (implicit)
reference at(size_type idx)
access specified array element with bounds checking
json_reverse_iterator(const base_iterator &it)
create reverse iterator from base class
value_t type() const noexcept
return the type of the JSON value (explicit)
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
object_t::key_type key() const
return the key of an object iterator
bool is_structured() const noexcept
return whether type is structured
namespace for Niels Lohmann
typename basic_json::difference_type difference_type
a type to represent differences between iterators
void swap(array_t &other)
exchanges the values
reverse_iterator rbegin()
returns an iterator to the reverse-beginning
reference operator+=(const typename object_t::value_type &val)
add an object to an object
basic_json(const number_integer_t val)
create an integer number (explicit)
reference operator[](difference_type n) const
access to successor
std::size_t size_type
a type to represent container sizes
const_reverse_iterator rbegin() const
returns a const reverse iterator to the last element
basic_json(const basic_json &other)
copy constructor
const_iterator operator+(difference_type i)
add to iterator
value_t
the JSON type enumeration
const value_type & const_reference
the type of an element const reference
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
ReferenceType get_ref() const
get a reference value (implicit)
bool is_null() const noexcept
return whether value is null
void swap(string_t &other)
exchanges the values
reference value() const
return the value of an iterator
const_iterator operator--(int)
post-decrement (it–)
ValueType get() const
get a value (explicit)
void erase(const size_type idx)
remove element from a JSON array given an index
void clear() noexcept
clears the contents
pointer operator->()
dereference the iterator
basic_json value_type
the type of elements in a basic_json container
array (ordered collection of values)
const_reference front() const
access the first element
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
std::ptrdiff_t difference_type
a type to represent differences between iterators
const_iterator & operator+=(difference_type i)
add to iterator
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
difference_type operator-(const const_iterator &other) const
return difference
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
bool is_number() const noexcept
return whether value is a number
BooleanType boolean_t
a type for a boolean
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
bool empty() const noexcept
checks whether the container is empty
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
void swap(reference other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
exchanges the values
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
const_reverse_iterator crbegin() const
returns a const reverse iterator to the last element
reference value() const
return the value of an iterator
const_iterator(pointer object)
constructor for a given JSON instance
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON types
iterator(pointer object) noexcept
constructor for a given JSON instance
bool operator<(const const_iterator &other) const
comparison: smaller
string_t dump(const int indent=-1) const
serialization
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
const_iterator & operator-=(difference_type i)
subtract from iterator
basic_json(const int val)
create an integer number from an enum type (explicit)
basic_json(const array_t &val)
create an array (explicit)
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
json_reverse_iterator operator++(int)
post-increment (it++)
PointerType get_ptr() noexcept
get a pointer value (implicit)
const_iterator(const iterator &other)
copy constructor given a nonconst iterator
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
InteratorType erase(InteratorType pos)
remove element given an iterator
bool operator<=(const const_iterator &other) const
comparison: less than or equal
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
reference back()
access the last element
bool is_number_float() const noexcept
return whether value is a floating-point number
const_iterator operator++(int)
post-increment (it++)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
basic_json(const string_t &val)
create a string (explicit)
iterator(const iterator &other) noexcept
copy constructor
const_reference back() const
access the last element
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
size_type max_size() const noexcept
returns the maximum possible number of elements
void push_back(const basic_json &val)
add an object to an array
bool operator==(const const_iterator &other) const
comparison: equal
json_reverse_iterator & operator++()
pre-increment (++it)
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
bool operator>(const const_iterator &other) const
comparison: greater than
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
basic_json(basic_json &&other) noexcept
move constructor
const_iterator begin() const
returns a const iterator to the first element
const_reference at(size_type idx) const
access specified array element with bounds checking
json_reverse_iterator & operator+=(difference_type i)
add to iterator
a const random access iterator for the basic_json class
a template for a reverse iterator class
void swap(object_t &other)
exchanges the values
std::bidirectional_iterator_tag iterator_category
the category of the iterator
bool is_primitive() const noexcept
return whether type is primitive
iterator insert(const_iterator pos, const basic_json &val)
inserts element
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
reference operator[](difference_type n) const
access to successor
NumberIntegerType number_integer_t
a type for a number (integer)
reference operator[](difference_type n) const
access to successor
reference operator*() const
return a reference to the value pointed to by the iterator
value_type & reference
the type of an element reference
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
NumberFloatType number_float_t
a type for a number (floating-point)
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
iterator & operator=(iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
basic_json(const CompatibleObjectType &val)
create an object (implicit)
reference operator[](size_type idx)
access specified array element
iterator operator--(int)
post-decrement (it–)
json_reverse_iterator operator+(difference_type i) const
add to iterator
parse_event_t
JSON callback events.
iterator operator-(difference_type i)
subtract from iterator