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[] = {
6839 0, 0, 0, 0, 0, 0, 0, 0,
6840 0, 32, 32, 0, 0, 32, 0, 0,
6841 128, 128, 128, 128, 128, 128, 128, 128,
6842 128, 128, 128, 128, 128, 128, 128, 128,
6843 160, 128, 0, 128, 128, 128, 128, 128,
6844 128, 128, 128, 128, 128, 128, 128, 128,
6845 192, 192, 192, 192, 192, 192, 192, 192,
6846 192, 192, 128, 128, 128, 128, 128, 128,
6847 128, 128, 128, 128, 128, 128, 128, 128,
6848 128, 128, 128, 128, 128, 128, 128, 128,
6849 128, 128, 128, 128, 128, 128, 128, 128,
6850 128, 128, 128, 128, 0, 128, 128, 128,
6851 128, 128, 128, 128, 128, 128, 128, 128,
6852 128, 128, 128, 128, 128, 128, 128, 128,
6853 128, 128, 128, 128, 128, 128, 128, 128,
6854 128, 128, 128, 128, 128, 128, 128, 128,
6855 128, 128, 128, 128, 128, 128, 128, 128,
6856 128, 128, 128, 128, 128, 128, 128, 128,
6857 128, 128, 128, 128, 128, 128, 128, 128,
6858 128, 128, 128, 128, 128, 128, 128, 128,
6859 128, 128, 128, 128, 128, 128, 128, 128,
6860 128, 128, 128, 128, 128, 128, 128, 128,
6861 128, 128, 128, 128, 128, 128, 128, 128,
6862 128, 128, 128, 128, 128, 128, 128, 128,
6863 128, 128, 128, 128, 128, 128, 128, 128,
6864 128, 128, 128, 128, 128, 128, 128, 128,
6865 128, 128, 128, 128, 128, 128, 128, 128,
6866 128, 128, 128, 128, 128, 128, 128, 128,
6867 128, 128, 128, 128, 128, 128, 128, 128,
6868 128, 128, 128, 128, 128, 128, 128, 128,
6869 128, 128, 128, 128, 128, 128, 128, 128,
6870 128, 128, 128, 128, 128, 128, 128, 128,
6872 if ((m_limit - m_cursor) < 5) yyfill();
6874 if (yybm[0+yych] & 32) {
6875 goto basic_json_parser_6;
6880 if (yych <= 0x00)
goto basic_json_parser_2;
6881 if (yych <=
'!')
goto basic_json_parser_4;
6882 goto basic_json_parser_9;
6884 if (yych <=
'+')
goto basic_json_parser_4;
6885 if (yych <=
',')
goto basic_json_parser_10;
6886 goto basic_json_parser_12;
6890 if (yych <=
'/')
goto basic_json_parser_4;
6891 if (yych <=
'0')
goto basic_json_parser_13;
6892 goto basic_json_parser_15;
6894 if (yych <=
':')
goto basic_json_parser_17;
6895 if (yych ==
'[')
goto basic_json_parser_19;
6896 goto basic_json_parser_4;
6902 if (yych <=
']')
goto basic_json_parser_21;
6903 if (yych <=
'e')
goto basic_json_parser_4;
6904 goto basic_json_parser_23;
6906 if (yych ==
'n')
goto basic_json_parser_24;
6907 if (yych <=
's')
goto basic_json_parser_4;
6908 goto basic_json_parser_25;
6912 if (yych ==
'{')
goto basic_json_parser_26;
6913 goto basic_json_parser_4;
6915 if (yych <=
'}')
goto basic_json_parser_28;
6916 if (yych == 0xEF)
goto basic_json_parser_30;
6917 goto basic_json_parser_4;
6921 basic_json_parser_2:
6923 {
return token_type::end_of_input; }
6924 basic_json_parser_4:
6926 basic_json_parser_5:
6927 {
return token_type::parse_error; }
6928 basic_json_parser_6:
6930 if (m_limit <= m_cursor) yyfill();
6932 if (yybm[0+yych] & 32) {
6933 goto basic_json_parser_6;
6936 basic_json_parser_9:
6938 yych = *(m_marker = ++m_cursor);
6939 if (yych <= 0x0F)
goto basic_json_parser_5;
6940 goto basic_json_parser_32;
6941 basic_json_parser_10:
6943 {
return token_type::value_separator; }
6944 basic_json_parser_12:
6946 if (yych <=
'/')
goto basic_json_parser_5;
6947 if (yych <=
'0')
goto basic_json_parser_13;
6948 if (yych <=
'9')
goto basic_json_parser_15;
6949 goto basic_json_parser_5;
6950 basic_json_parser_13:
6952 yych = *(m_marker = ++m_cursor);
6954 if (yych ==
'.')
goto basic_json_parser_37;
6956 if (yych <=
'E')
goto basic_json_parser_38;
6957 if (yych ==
'e')
goto basic_json_parser_38;
6959 basic_json_parser_14:
6960 {
return token_type::value_number; }
6961 basic_json_parser_15:
6963 m_marker = ++m_cursor;
6964 if ((m_limit - m_cursor) < 3) yyfill();
6966 if (yybm[0+yych] & 64) {
6967 goto basic_json_parser_15;
6970 if (yych ==
'.')
goto basic_json_parser_37;
6971 goto basic_json_parser_14;
6973 if (yych <=
'E')
goto basic_json_parser_38;
6974 if (yych ==
'e')
goto basic_json_parser_38;
6975 goto basic_json_parser_14;
6977 basic_json_parser_17:
6979 {
return token_type::name_separator; }
6980 basic_json_parser_19:
6982 {
return token_type::begin_array; }
6983 basic_json_parser_21:
6985 {
return token_type::end_array; }
6986 basic_json_parser_23:
6988 yych = *(m_marker = ++m_cursor);
6989 if (yych ==
'a')
goto basic_json_parser_39;
6990 goto basic_json_parser_5;
6991 basic_json_parser_24:
6993 yych = *(m_marker = ++m_cursor);
6994 if (yych ==
'u')
goto basic_json_parser_40;
6995 goto basic_json_parser_5;
6996 basic_json_parser_25:
6998 yych = *(m_marker = ++m_cursor);
6999 if (yych ==
'r')
goto basic_json_parser_41;
7000 goto basic_json_parser_5;
7001 basic_json_parser_26:
7003 {
return token_type::begin_object; }
7004 basic_json_parser_28:
7006 {
return token_type::end_object; }
7007 basic_json_parser_30:
7009 yych = *(m_marker = ++m_cursor);
7010 if (yych == 0xBB)
goto basic_json_parser_42;
7011 goto basic_json_parser_5;
7012 basic_json_parser_31:
7014 if (m_limit <= m_cursor) yyfill();
7016 basic_json_parser_32:
7017 if (yybm[0+yych] & 128) {
7018 goto basic_json_parser_31;
7020 if (yych <= 0x0F)
goto basic_json_parser_33;
7021 if (yych <=
'"')
goto basic_json_parser_34;
7022 goto basic_json_parser_36;
7023 basic_json_parser_33:
7024 m_cursor = m_marker;
7025 if (yyaccept == 0) {
7026 goto basic_json_parser_5;
7028 goto basic_json_parser_14;
7030 basic_json_parser_34:
7032 {
return token_type::value_string; }
7033 basic_json_parser_36:
7035 if (m_limit <= m_cursor) yyfill();
7039 if (yych ==
'"')
goto basic_json_parser_31;
7040 if (yych <=
'.')
goto basic_json_parser_33;
7041 goto basic_json_parser_31;
7044 if (yych <=
'[')
goto basic_json_parser_33;
7045 goto basic_json_parser_31;
7047 if (yych ==
'b')
goto basic_json_parser_31;
7048 goto basic_json_parser_33;
7053 if (yych <=
'f')
goto basic_json_parser_31;
7054 if (yych ==
'n')
goto basic_json_parser_31;
7055 goto basic_json_parser_33;
7058 if (yych <=
'r')
goto basic_json_parser_31;
7059 goto basic_json_parser_33;
7061 if (yych <=
't')
goto basic_json_parser_31;
7062 if (yych <=
'u')
goto basic_json_parser_43;
7063 goto basic_json_parser_33;
7067 basic_json_parser_37:
7069 if (yych <=
'/')
goto basic_json_parser_33;
7070 if (yych <=
'9')
goto basic_json_parser_44;
7071 goto basic_json_parser_33;
7072 basic_json_parser_38:
7075 if (yych ==
'+')
goto basic_json_parser_46;
7076 goto basic_json_parser_33;
7078 if (yych <=
'-')
goto basic_json_parser_46;
7079 if (yych <=
'/')
goto basic_json_parser_33;
7080 if (yych <=
'9')
goto basic_json_parser_47;
7081 goto basic_json_parser_33;
7083 basic_json_parser_39:
7085 if (yych ==
'l')
goto basic_json_parser_49;
7086 goto basic_json_parser_33;
7087 basic_json_parser_40:
7089 if (yych ==
'l')
goto basic_json_parser_50;
7090 goto basic_json_parser_33;
7091 basic_json_parser_41:
7093 if (yych ==
'u')
goto basic_json_parser_51;
7094 goto basic_json_parser_33;
7095 basic_json_parser_42:
7097 if (yych == 0xBF)
goto basic_json_parser_52;
7098 goto basic_json_parser_33;
7099 basic_json_parser_43:
7101 if (m_limit <= m_cursor) yyfill();
7104 if (yych <=
'/')
goto basic_json_parser_33;
7105 if (yych <=
'9')
goto basic_json_parser_54;
7106 goto basic_json_parser_33;
7108 if (yych <=
'F')
goto basic_json_parser_54;
7109 if (yych <=
'`')
goto basic_json_parser_33;
7110 if (yych <=
'f')
goto basic_json_parser_54;
7111 goto basic_json_parser_33;
7113 basic_json_parser_44:
7115 m_marker = ++m_cursor;
7116 if ((m_limit - m_cursor) < 3) yyfill();
7119 if (yych <=
'/')
goto basic_json_parser_14;
7120 if (yych <=
'9')
goto basic_json_parser_44;
7121 goto basic_json_parser_14;
7123 if (yych <=
'E')
goto basic_json_parser_38;
7124 if (yych ==
'e')
goto basic_json_parser_38;
7125 goto basic_json_parser_14;
7127 basic_json_parser_46:
7129 if (yych <=
'/')
goto basic_json_parser_33;
7130 if (yych >=
':')
goto basic_json_parser_33;
7131 basic_json_parser_47:
7133 if (m_limit <= m_cursor) yyfill();
7135 if (yych <=
'/')
goto basic_json_parser_14;
7136 if (yych <=
'9')
goto basic_json_parser_47;
7137 goto basic_json_parser_14;
7138 basic_json_parser_49:
7140 if (yych ==
's')
goto basic_json_parser_55;
7141 goto basic_json_parser_33;
7142 basic_json_parser_50:
7144 if (yych ==
'l')
goto basic_json_parser_56;
7145 goto basic_json_parser_33;
7146 basic_json_parser_51:
7148 if (yych ==
'e')
goto basic_json_parser_58;
7149 goto basic_json_parser_33;
7150 basic_json_parser_52:
7153 basic_json_parser_54:
7155 if (m_limit <= m_cursor) yyfill();
7158 if (yych <=
'/')
goto basic_json_parser_33;
7159 if (yych <=
'9')
goto basic_json_parser_60;
7160 goto basic_json_parser_33;
7162 if (yych <=
'F')
goto basic_json_parser_60;
7163 if (yych <=
'`')
goto basic_json_parser_33;
7164 if (yych <=
'f')
goto basic_json_parser_60;
7165 goto basic_json_parser_33;
7167 basic_json_parser_55:
7169 if (yych ==
'e')
goto basic_json_parser_61;
7170 goto basic_json_parser_33;
7171 basic_json_parser_56:
7173 {
return token_type::literal_null; }
7174 basic_json_parser_58:
7176 {
return token_type::literal_true; }
7177 basic_json_parser_60:
7179 if (m_limit <= m_cursor) yyfill();
7182 if (yych <=
'/')
goto basic_json_parser_33;
7183 if (yych <=
'9')
goto basic_json_parser_63;
7184 goto basic_json_parser_33;
7186 if (yych <=
'F')
goto basic_json_parser_63;
7187 if (yych <=
'`')
goto basic_json_parser_33;
7188 if (yych <=
'f')
goto basic_json_parser_63;
7189 goto basic_json_parser_33;
7191 basic_json_parser_61:
7193 {
return token_type::literal_false; }
7194 basic_json_parser_63:
7196 if (m_limit <= m_cursor) yyfill();
7199 if (yych <=
'/')
goto basic_json_parser_33;
7200 if (yych <=
'9')
goto basic_json_parser_31;
7201 goto basic_json_parser_33;
7203 if (yych <=
'F')
goto basic_json_parser_31;
7204 if (yych <=
'`')
goto basic_json_parser_33;
7205 if (yych <=
'f')
goto basic_json_parser_31;
7206 goto basic_json_parser_33;
7214 void yyfill() noexcept
7216 if (m_stream ==
nullptr or not * m_stream)
7221 const ssize_t offset_start = m_start - m_content;
7222 const ssize_t offset_marker = m_marker - m_start;
7223 const ssize_t offset_cursor = m_cursor - m_start;
7225 m_buffer.erase(0, static_cast<size_t>(offset_start));
7227 assert(m_stream !=
nullptr);
7228 std::getline(*m_stream, line);
7229 m_buffer +=
"\n" + line;
7231 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7232 assert(m_content !=
nullptr);
7233 m_start = m_content;
7234 m_marker = m_start + offset_marker;
7235 m_cursor = m_start + offset_cursor;
7236 m_limit = m_start + m_buffer.size() - 1;
7240 string_t get_token()
const noexcept
7242 assert(m_start !=
nullptr);
7243 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7244 static_cast<size_t>(m_cursor - m_start));
7271 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7274 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7330 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7331 4).c_str(),
nullptr, 16);
7334 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7337 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7339 throw std::invalid_argument(
"missing low surrogate");
7343 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7344 (i + 7), 4).c_str(),
nullptr, 16);
7345 result += to_unicode(codepoint, codepoint2);
7352 result += to_unicode(codepoint);
7364 result.append(1, static_cast<typename string_t::value_type>(*i));
7391 long double str_to_float_t(
long double* ,
char** endptr)
const 7393 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7397 double str_to_float_t(
double*,
char** endptr)
const 7399 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7403 float str_to_float_t(
float*,
char** endptr)
const 7405 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
7428 typename string_t::value_type* endptr;
7429 assert(m_start !=
nullptr);
7430 number_float_t float_val = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
7434 return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
7439 std::istream* m_stream =
nullptr;
7443 const lexer_char_t* m_content =
nullptr;
7445 const lexer_char_t* m_start =
nullptr;
7447 const lexer_char_t* m_marker =
nullptr;
7449 const lexer_char_t* m_cursor =
nullptr;
7451 const lexer_char_t* m_limit =
nullptr;
7464 : callback(cb), m_lexer(s)
7472 : callback(cb), m_lexer(&_is)
7481 basic_json result = parse_internal(
true);
7483 expect(lexer::token_type::end_of_input);
7492 basic_json parse_internal(
bool keep)
7494 auto result = basic_json(value_t::discarded);
7498 case lexer::token_type::begin_object:
7500 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
7503 result.m_type = value_t::object;
7504 result.m_value = json_value(value_t::object);
7511 if (last_token == lexer::token_type::end_object)
7514 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7516 result = basic_json(value_t::discarded);
7522 unexpect(lexer::token_type::value_separator);
7528 if (last_token == lexer::token_type::value_separator)
7534 expect(lexer::token_type::value_string);
7535 const auto key = m_lexer.get_string();
7537 bool keep_tag =
false;
7543 keep_tag = callback(depth, parse_event_t::key, k);
7553 expect(lexer::token_type::name_separator);
7557 auto value = parse_internal(keep);
7558 if (keep and keep_tag and not value.is_discarded())
7560 result[key] = std::move(value);
7563 while (last_token == lexer::token_type::value_separator);
7566 expect(lexer::token_type::end_object);
7568 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
7570 result = basic_json(value_t::discarded);
7576 case lexer::token_type::begin_array:
7578 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
7581 result.m_type = value_t::array;
7582 result.m_value = json_value(value_t::array);
7589 if (last_token == lexer::token_type::end_array)
7592 if (callback and not callback(--depth, parse_event_t::array_end, result))
7594 result = basic_json(value_t::discarded);
7600 unexpect(lexer::token_type::value_separator);
7606 if (last_token == lexer::token_type::value_separator)
7612 auto value = parse_internal(keep);
7613 if (keep and not value.is_discarded())
7615 result.push_back(std::move(value));
7618 while (last_token == lexer::token_type::value_separator);
7621 expect(lexer::token_type::end_array);
7623 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
7625 result = basic_json(value_t::discarded);
7631 case lexer::token_type::literal_null:
7634 result.m_type = value_t::null;
7638 case lexer::token_type::value_string:
7640 const auto s = m_lexer.get_string();
7642 result = basic_json(s);
7646 case lexer::token_type::literal_true:
7649 result.m_type = value_t::boolean;
7650 result.m_value =
true;
7654 case lexer::token_type::literal_false:
7657 result.m_type = value_t::boolean;
7658 result.m_value =
false;
7662 case lexer::token_type::value_number:
7664 result.m_value = m_lexer.get_number();
7668 if (std::isnan(result.m_value.number_float))
7670 throw std::invalid_argument(std::string(
"parse error - ") +
7671 m_lexer.get_token() +
" is not a number");
7677 const auto int_val =
static_cast<number_integer_t>(result.m_value.number_float);
7678 if (result.m_value.number_float == static_cast<number_float_t>(int_val) and
7679 result.m_value.number_integer != json_value(-0.0f).number_integer)
7682 result.m_type = value_t::number_integer;
7683 result.m_value = int_val;
7688 result.m_type = value_t::number_float;
7696 unexpect(last_token);
7700 if (keep and callback and not callback(depth, parse_event_t::value, result))
7702 result = basic_json(value_t::discarded);
7708 typename lexer::token_type get_token()
7710 last_token = m_lexer.scan();
7714 void expect(
typename lexer::token_type t)
const 7716 if (t != last_token)
7718 std::string error_msg =
"parse error - unexpected ";
7719 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
7720 lexer::token_type_name(last_token));
7721 error_msg +=
"; expected " + lexer::token_type_name(t);
7722 throw std::invalid_argument(error_msg);
7726 void unexpect(
typename lexer::token_type t)
const 7728 if (t == last_token)
7730 std::string error_msg =
"parse error - unexpected ";
7731 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
7732 lexer::token_type_name(last_token));
7733 throw std::invalid_argument(error_msg);
7743 typename lexer::token_type last_token = lexer::token_type::uninitialized;
7781 is_nothrow_move_constructible<nlohmann::json>::value and
7782 is_nothrow_move_assignable<nlohmann::json>::value
7800 const auto& h = hash<nlohmann::json::string_t>();
7818 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
7824 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 7825 #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
bool is_array() const noexcept
return whether value is an array
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
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
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
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
bool is_number_integer() const noexcept
return whether value is an integer number
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
iterator & operator+=(difference_type i)
add to iterator
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
bool is_discarded() const noexcept
return whether value is discarded
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
bool is_structured() const noexcept
return whether type is structured
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
bool is_null() const noexcept
return whether value is null
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
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
reference operator*()
return a reference to the value pointed to by the iterator
reverse_iterator rend()
returns an iterator to the reverse-end
const_iterator operator-(difference_type i)
subtract from iterator
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
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
bool empty() const noexcept
checks whether the container is empty
reference operator+=(const basic_json &val)
add an object to an array
AllocatorType< basic_json > allocator_type
the allocator type
bool is_object() const noexcept
return whether value is an object
basic_json(const number_float_t val)
create a floating-point number (explicit)
reference operator[](T *(&key)[n])
access specified object element
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
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
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
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
bool is_boolean() const noexcept
return whether value is a boolean
object_t::key_type key() const
return the key of an object iterator
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
bool is_number_float() const noexcept
return whether value is a floating-point number
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
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
const_iterator & operator=(const_iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
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)
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 is_number() const noexcept
return whether value is a number
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
BooleanType boolean_t
a type for a boolean
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
bool is_string() const noexcept
return whether value is a string
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
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
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
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
bool is_primitive() const noexcept
return whether type is primitive
const_reference at(size_type idx) const
access specified array element with bounds checking
json_reverse_iterator & operator+=(difference_type i)
add to iterator
size_type max_size() const noexcept
returns the maximum possible number of elements
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
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
iterator & operator=(iterator other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
value_t type() const noexcept
return the type of the JSON value (explicit)
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
size_type size() const noexcept
returns the number of elements