11 #ifndef NLOHMANN_JSON_HPP 12 #define NLOHMANN_JSON_HPP 23 #include <initializer_list> 33 #include <type_traits> 40 #include <sys/types.h> 45 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 46 #pragma GCC diagnostic push 47 #pragma GCC diagnostic ignored "-Wfloat-equal" 53 using ssize_t = SSIZE_T;
76 struct has_mapped_type
79 template<
typename C>
static char test(
typename C::mapped_type*);
80 template<
typename C>
static char (&test(...))[2];
82 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
159 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
160 template<
typename U,
typename... Args>
class ArrayType = std::vector,
161 class StringType = std::string,
162 class BooleanType = bool,
163 class NumberIntegerType = int64_t,
164 class NumberUnsignedType = uint64_t,
165 class NumberFloatType = double,
166 template<
typename U>
class AllocatorType = std::allocator
207 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
209 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
324 using object_t = ObjectType<StringType,
326 std::less<StringType>,
327 AllocatorType<std::pair<
const StringType,
374 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
693 template<
typename T,
typename... Args>
694 static T* create(Args&& ... args)
696 AllocatorType<T> alloc;
697 auto deleter = [&](T * object)
699 alloc.deallocate(
object, 1);
701 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
702 alloc.construct(
object.
get(), std::forward<Args>(args)...);
703 return object.release();
735 json_value() noexcept =
default;
737 json_value(
boolean_t v) noexcept : boolean(v) {}
749 case value_t::object:
751 object = create<object_t>();
757 array = create<array_t>();
761 case value_t::string:
763 string = create<string_t>(
"");
767 case value_t::boolean:
773 case value_t::number_integer:
779 case value_t::number_unsigned:
785 case value_t::number_float:
801 string = create<string_t>(value);
807 object = create<object_t>(value);
811 json_value(
const array_t& value)
813 array = create<array_t>(value);
896 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
946 : m_type(value_type), m_value(value_type)
970 basic_json() noexcept =
default;
1015 : m_type(
value_t::object), m_value(val)
1041 template <
class CompatibleObjectType,
typename 1043 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1044 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
1051 m_value.object = create<object_t>(begin(val), end(val));
1074 : m_type(
value_t::array), m_value(val)
1100 template <
class CompatibleArrayType,
typename 1102 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1103 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1104 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1105 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1106 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1107 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1108 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1115 m_value.array = create<array_t>(begin(val), end(val));
1140 : m_type(
value_t::string), m_value(val)
1190 template <
class CompatibleStringType,
typename 1192 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1213 : m_type(
value_t::boolean), m_value(val)
1241 template<
typename T,
1242 typename std::enable_if<
1243 not (std::is_same<T, int>::value)
1244 and std::is_same<T, number_integer_t>::value
1248 : m_type(
value_t::number_integer), m_value(val)
1277 : m_type(
value_t::number_integer),
1306 template<
typename CompatibleNumberIntegerType,
typename 1308 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1309 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1310 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1311 CompatibleNumberIntegerType>::type
1314 : m_type(value_t::number_integer),
1315 m_value(static_cast<number_integer_t>(val))
1335 template<
typename T,
1336 typename std::enable_if<
1337 not (std::is_same<T, int>::value)
1338 and std::is_same<T, number_unsigned_t>::value
1342 : m_type(
value_t::number_unsigned), m_value(val)
1365 template <
typename CompatibleNumberUnsignedType,
typename 1367 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1368 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1369 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1370 CompatibleNumberUnsignedType >::type
1373 : m_type(value_t::number_unsigned),
1374 m_value(static_cast<number_unsigned_t>(val))
1402 : m_type(
value_t::number_float), m_value(val)
1405 if (not std::isfinite(val))
1407 m_type = value_t::null;
1408 m_value = json_value();
1442 template<
typename CompatibleNumberFloatType,
typename =
typename 1444 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1445 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1521 bool type_deduction =
true,
1522 value_t manual_type = value_t::array)
1525 bool is_an_object =
true;
1529 for (
const auto& element : init)
1531 if (not element.is_array() or element.size() != 2
1532 or not element[0].is_string())
1536 is_an_object =
false;
1542 if (not type_deduction)
1545 if (manual_type == value_t::array)
1547 is_an_object =
false;
1551 if (manual_type == value_t::object and not is_an_object)
1553 throw std::domain_error(
"cannot create object from initializer list");
1560 m_type = value_t::object;
1561 m_value = value_t::object;
1563 assert(m_value.object !=
nullptr);
1565 for (
auto& element : init)
1567 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1573 m_type = value_t::array;
1574 m_value.array = create<array_t>(std::move(init));
1612 static basic_json
array(std::initializer_list<basic_json> init =
1613 std::initializer_list<basic_json>())
1615 return basic_json(init,
false, value_t::array);
1652 static basic_json
object(std::initializer_list<basic_json> init =
1653 std::initializer_list<basic_json>())
1655 return basic_json(init,
false, value_t::object);
1679 m_value.array = create<array_t>(cnt, val);
1716 template <
class InputIT,
typename 1718 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1719 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1722 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1725 if (first.m_object != last.m_object)
1727 throw std::domain_error(
"iterators are not compatible");
1733 case value_t::boolean:
1734 case value_t::number_float:
1735 case value_t::number_integer:
1736 case value_t::number_unsigned:
1737 case value_t::string:
1739 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1741 throw std::out_of_range(
"iterators out of range");
1754 case value_t::number_integer:
1756 assert(first.m_object !=
nullptr);
1757 m_value.number_integer = first.m_object->m_value.number_integer;
1761 case value_t::number_unsigned:
1763 assert(first.m_object !=
nullptr);
1764 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1768 case value_t::number_float:
1770 assert(first.m_object !=
nullptr);
1771 m_value.number_float = first.m_object->m_value.number_float;
1775 case value_t::boolean:
1777 assert(first.m_object !=
nullptr);
1778 m_value.boolean = first.m_object->m_value.boolean;
1782 case value_t::string:
1784 assert(first.m_object !=
nullptr);
1785 m_value = *first.m_object->m_value.string;
1789 case value_t::object:
1791 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1795 case value_t::array:
1797 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1803 assert(first.m_object !=
nullptr);
1804 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1836 : m_type(other.m_type)
1840 case value_t::object:
1842 assert(other.m_value.object !=
nullptr);
1843 m_value = *other.m_value.object;
1847 case value_t::array:
1849 assert(other.m_value.array !=
nullptr);
1850 m_value = *other.m_value.array;
1854 case value_t::string:
1856 assert(other.m_value.string !=
nullptr);
1857 m_value = *other.m_value.string;
1861 case value_t::boolean:
1863 m_value = other.m_value.boolean;
1867 case value_t::number_integer:
1869 m_value = other.m_value.number_integer;
1873 case value_t::number_unsigned:
1875 m_value = other.m_value.number_unsigned;
1879 case value_t::number_float:
1881 m_value = other.m_value.number_float;
1911 : m_type(
std::move(other.m_type)),
1912 m_value(
std::move(other.m_value))
1915 other.m_type = value_t::null;
1943 std::is_nothrow_move_constructible<value_t>::value and
1944 std::is_nothrow_move_assignable<value_t>::value and
1945 std::is_nothrow_move_constructible<json_value>::value and
1946 std::is_nothrow_move_assignable<json_value>::value
1950 swap(m_type, other.m_type);
1951 swap(m_value, other.m_value);
1974 case value_t::object:
1976 AllocatorType<object_t> alloc;
1977 alloc.destroy(m_value.object);
1978 alloc.deallocate(m_value.object, 1);
1982 case value_t::array:
1984 AllocatorType<array_t> alloc;
1985 alloc.destroy(m_value.array);
1986 alloc.deallocate(m_value.array, 1);
1990 case value_t::string:
1992 AllocatorType<string_t> alloc;
1993 alloc.destroy(m_value.string);
1994 alloc.deallocate(m_value.string, 1);
2041 std::stringstream ss;
2045 dump(ss,
true, static_cast<unsigned int>(indent));
2099 return is_null() or is_string() or is_boolean() or is_number();
2123 return is_array() or is_object();
2142 return m_type == value_t::null;
2161 return m_type == value_t::boolean;
2188 return is_number_integer() or is_number_float();
2214 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2239 return m_type == value_t::number_unsigned;
2264 return m_type == value_t::number_float;
2283 return m_type == value_t::object;
2302 return m_type == value_t::array;
2321 return m_type == value_t::string;
2345 return m_type == value_t::discarded;
2376 template <
class T,
typename 2378 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2379 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2381 T get_impl(T*)
const 2385 assert(m_value.object !=
nullptr);
2386 return T(m_value.object->begin(), m_value.object->end());
2390 throw std::domain_error(
"type must be object, but is " + type_name());
2399 assert(m_value.object !=
nullptr);
2400 return *(m_value.object);
2404 throw std::domain_error(
"type must be object, but is " + type_name());
2409 template <
class T,
typename 2411 std::is_convertible<basic_json_t, typename T::value_type>::value and
2412 not std::is_same<basic_json_t, typename T::value_type>::value and
2413 not std::is_arithmetic<T>::value and
2414 not std::is_convertible<std::string, T>::value and
2415 not has_mapped_type<T>::value
2417 T get_impl(T*)
const 2422 assert(m_value.array !=
nullptr);
2423 std::transform(m_value.array->begin(), m_value.array->end(),
2424 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2426 return i.
get<
typename T::value_type>();
2432 throw std::domain_error(
"type must be array, but is " + type_name());
2437 template <
class T,
typename 2439 std::is_convertible<basic_json_t, T>::value and
2440 not std::is_same<basic_json_t, T>::value
2442 std::vector<T> get_impl(std::vector<T>*)
const 2446 std::vector<T> to_vector;
2447 assert(m_value.array !=
nullptr);
2448 to_vector.reserve(m_value.array->size());
2449 std::transform(m_value.array->begin(), m_value.array->end(),
2450 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2458 throw std::domain_error(
"type must be array, but is " + type_name());
2463 template <
class T,
typename 2465 std::is_same<basic_json, typename T::value_type>::value and
2466 not has_mapped_type<T>::value
2468 T get_impl(T*)
const 2472 assert(m_value.array !=
nullptr);
2473 return T(m_value.array->begin(), m_value.array->end());
2477 throw std::domain_error(
"type must be array, but is " + type_name());
2486 assert(m_value.array !=
nullptr);
2487 return *(m_value.array);
2491 throw std::domain_error(
"type must be array, but is " + type_name());
2496 template <
typename T,
typename 2498 std::is_convertible<string_t, T>::value
2500 T get_impl(T*)
const 2504 assert(m_value.string !=
nullptr);
2505 return *m_value.string;
2509 throw std::domain_error(
"type must be string, but is " + type_name());
2514 template<
typename T,
typename 2516 std::is_arithmetic<T>::value
2518 T get_impl(T*)
const 2522 case value_t::number_integer:
2524 return static_cast<T
>(m_value.number_integer);
2527 case value_t::number_unsigned:
2529 return static_cast<T
>(m_value.number_unsigned);
2532 case value_t::number_float:
2534 return static_cast<T
>(m_value.number_float);
2539 throw std::domain_error(
"type must be number, but is " + type_name());
2549 return m_value.boolean;
2553 throw std::domain_error(
"type must be boolean, but is " + type_name());
2560 return is_object() ? m_value.object :
nullptr;
2566 return is_object() ? m_value.object :
nullptr;
2572 return is_array() ? m_value.array :
nullptr;
2578 return is_array() ? m_value.array :
nullptr;
2584 return is_string() ? m_value.string :
nullptr;
2590 return is_string() ? m_value.string :
nullptr;
2596 return is_boolean() ? &m_value.boolean :
nullptr;
2602 return is_boolean() ? &m_value.boolean :
nullptr;
2608 return is_number_integer() ? &m_value.number_integer :
nullptr;
2614 return is_number_integer() ? &m_value.number_integer :
nullptr;
2620 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2626 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2632 return is_number_float() ? &m_value.number_float :
nullptr;
2638 return is_number_float() ? &m_value.number_float :
nullptr;
2652 template<
typename ReferenceType,
typename ThisType>
2653 static ReferenceType get_ref_impl(ThisType& obj)
2656 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2657 auto ptr = obj.template get_ptr<PointerType>();
2665 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2708 template<
typename ValueType,
typename 2710 not std::is_pointer<ValueType>::value
2712 ValueType
get()
const 2714 return get_impl(static_cast<ValueType*>(
nullptr));
2743 template<
typename PointerType,
typename 2745 std::is_pointer<PointerType>::value
2747 PointerType
get() noexcept
2750 return get_ptr<PointerType>();
2757 template<
typename PointerType,
typename 2759 std::is_pointer<PointerType>::value
2761 const PointerType
get()
const noexcept
2764 return get_ptr<PointerType>();
2792 template<
typename PointerType,
typename 2794 std::is_pointer<PointerType>::value
2799 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2806 template<
typename PointerType,
typename 2808 std::is_pointer<PointerType>::value
2809 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2814 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2843 template<
typename ReferenceType,
typename 2845 std::is_reference<ReferenceType>::value
2850 return get_ref_impl<ReferenceType>(*this);
2857 template<
typename ReferenceType,
typename 2859 std::is_reference<ReferenceType>::value
2860 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2865 return get_ref_impl<ReferenceType>(*this);
2896 template <
typename ValueType,
typename 2898 not std::is_pointer<ValueType>::value
2899 and not std::is_same<ValueType, typename string_t::value_type>::value
2900 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2901 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2904 operator ValueType()
const 2907 return get<ValueType>();
2949 assert(m_value.array !=
nullptr);
2950 return m_value.array->at(idx);
2952 catch (std::out_of_range&)
2955 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2960 throw std::domain_error(
"cannot use at() with " + type_name());
2993 assert(m_value.array !=
nullptr);
2994 return m_value.array->at(idx);
2996 catch (std::out_of_range&)
2999 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3004 throw std::domain_error(
"cannot use at() with " + type_name());
3041 assert(m_value.object !=
nullptr);
3042 return m_value.object->at(key);
3044 catch (std::out_of_range&)
3047 throw std::out_of_range(
"key '" + key +
"' not found");
3052 throw std::domain_error(
"cannot use at() with " + type_name());
3089 assert(m_value.object !=
nullptr);
3090 return m_value.object->at(key);
3092 catch (std::out_of_range&)
3095 throw std::out_of_range(
"key '" + key +
"' not found");
3100 throw std::domain_error(
"cannot use at() with " + type_name());
3134 m_type = value_t::array;
3135 m_value.
array = create<array_t>();
3141 assert(m_value.array !=
nullptr);
3142 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3144 m_value.array->push_back(basic_json());
3147 return m_value.array->operator[](idx);
3151 throw std::domain_error(
"cannot use operator[] with " + type_name());
3179 assert(m_value.array !=
nullptr);
3180 return m_value.array->operator[](idx);
3184 throw std::domain_error(
"cannot use operator[] with " + type_name());
3220 m_type = value_t::object;
3221 m_value.
object = create<object_t>();
3227 assert(m_value.object !=
nullptr);
3228 return m_value.object->operator[](key);
3232 throw std::domain_error(
"cannot use operator[] with " + type_name());
3268 assert(m_value.object !=
nullptr);
3269 assert(m_value.object->find(key) != m_value.object->end());
3270 return m_value.object->find(key)->second;
3274 throw std::domain_error(
"cannot use operator[] with " + type_name());
3305 template<
typename T, std::
size_t n>
3308 return operator[](static_cast<const T>(key));
3340 template<
typename T, std::
size_t n>
3343 return operator[](static_cast<const T>(key));
3373 template<
typename T>
3379 m_type = value_t::object;
3380 m_value = value_t::object;
3386 assert(m_value.object !=
nullptr);
3387 return m_value.object->operator[](key);
3391 throw std::domain_error(
"cannot use operator[] with " + type_name());
3422 template<
typename T>
3428 assert(m_value.object !=
nullptr);
3429 assert(m_value.object->find(key) != m_value.object->end());
3430 return m_value.object->find(key)->second;
3434 throw std::domain_error(
"cannot use operator[] with " + type_name());
3486 template <
class ValueType,
typename 3488 std::is_convertible<basic_json_t, ValueType>::value
3490 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3496 const auto it = find(key);
3503 return default_value;
3508 throw std::domain_error(
"cannot use value() with " + type_name());
3516 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3518 return value(key,
string_t(default_value));
3644 template <
class InteratorType,
typename 3646 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3647 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3653 if (
this != pos.m_object)
3655 throw std::domain_error(
"iterator does not fit current value");
3658 InteratorType result = end();
3662 case value_t::boolean:
3663 case value_t::number_float:
3664 case value_t::number_integer:
3665 case value_t::number_unsigned:
3666 case value_t::string:
3668 if (not pos.m_it.primitive_iterator.is_begin())
3670 throw std::out_of_range(
"iterator out of range");
3675 delete m_value.string;
3676 m_value.string =
nullptr;
3679 m_type = value_t::null;
3683 case value_t::object:
3685 assert(m_value.object !=
nullptr);
3686 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3690 case value_t::array:
3692 assert(m_value.array !=
nullptr);
3693 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3699 throw std::domain_error(
"cannot use erase() with " + type_name());
3750 template <
class InteratorType,
typename 3752 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3753 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3756 InteratorType
erase(InteratorType first, InteratorType last)
3759 if (
this != first.m_object or
this != last.m_object)
3761 throw std::domain_error(
"iterators do not fit current value");
3764 InteratorType result = end();
3768 case value_t::boolean:
3769 case value_t::number_float:
3770 case value_t::number_integer:
3771 case value_t::number_unsigned:
3772 case value_t::string:
3774 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3776 throw std::out_of_range(
"iterators out of range");
3781 delete m_value.string;
3782 m_value.string =
nullptr;
3785 m_type = value_t::null;
3789 case value_t::object:
3791 assert(m_value.object !=
nullptr);
3792 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3793 last.m_it.object_iterator);
3797 case value_t::array:
3799 assert(m_value.array !=
nullptr);
3800 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3801 last.m_it.array_iterator);
3807 throw std::domain_error(
"cannot use erase() with " + type_name());
3845 assert(m_value.object !=
nullptr);
3846 return m_value.object->erase(key);
3850 throw std::domain_error(
"cannot use erase() with " + type_name());
3885 throw std::out_of_range(
"index out of range");
3888 assert(m_value.array !=
nullptr);
3889 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3893 throw std::domain_error(
"cannot use erase() with " + type_name());
3916 auto result = end();
3920 assert(m_value.object !=
nullptr);
3921 result.m_it.object_iterator = m_value.object->find(key);
3933 auto result = cend();
3937 assert(m_value.object !=
nullptr);
3938 result.m_it.object_iterator = m_value.object->find(key);
3965 assert(not is_object() or m_value.object !=
nullptr);
3966 return is_object() ? m_value.object->count(key) : 0;
4254 template<
typename IteratorType>
class iteration_proxy;
4270 return iteration_proxy<iterator>(cont);
4278 return iteration_proxy<const_iterator>(cont);
4334 case value_t::array:
4336 assert(m_value.array !=
nullptr);
4337 return m_value.array->empty();
4340 case value_t::object:
4342 assert(m_value.object !=
nullptr);
4343 return m_value.object->empty();
4397 case value_t::array:
4399 assert(m_value.array !=
nullptr);
4400 return m_value.array->size();
4403 case value_t::object:
4405 assert(m_value.object !=
nullptr);
4406 return m_value.object->size();
4457 case value_t::array:
4459 assert(m_value.array !=
nullptr);
4460 return m_value.array->max_size();
4463 case value_t::object:
4465 assert(m_value.object !=
nullptr);
4466 return m_value.object->max_size();
4516 case value_t::number_integer:
4518 m_value.number_integer = 0;
4522 case value_t::number_unsigned:
4524 m_value.number_unsigned = 0;
4528 case value_t::number_float:
4530 m_value.number_float = 0.0;
4534 case value_t::boolean:
4536 m_value.boolean =
false;
4540 case value_t::string:
4542 assert(m_value.string !=
nullptr);
4543 m_value.string->clear();
4547 case value_t::array:
4549 assert(m_value.array !=
nullptr);
4550 m_value.array->clear();
4554 case value_t::object:
4556 assert(m_value.object !=
nullptr);
4557 m_value.object->clear();
4591 if (not(is_null() or is_array()))
4593 throw std::domain_error(
"cannot use push_back() with " + type_name());
4599 m_type = value_t::array;
4600 m_value = value_t::array;
4604 assert(m_value.array !=
nullptr);
4605 m_value.array->push_back(std::move(val));
4607 val.m_type = value_t::null;
4616 push_back(std::move(val));
4627 if (not(is_null() or is_array()))
4629 throw std::domain_error(
"cannot use push_back() with " + type_name());
4635 m_type = value_t::array;
4636 m_value = value_t::array;
4640 assert(m_value.array !=
nullptr);
4641 m_value.array->push_back(val);
4677 if (not(is_null() or is_object()))
4679 throw std::domain_error(
"cannot use push_back() with " + type_name());
4685 m_type = value_t::object;
4686 m_value = value_t::object;
4690 assert(m_value.object !=
nullptr);
4691 m_value.object->insert(val);
4701 return operator[](val.first);
4732 if (pos.m_object !=
this)
4734 throw std::domain_error(
"iterator does not fit current value");
4739 assert(m_value.array !=
nullptr);
4740 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4745 throw std::domain_error(
"cannot use insert() with " + type_name());
4755 return insert(pos, val);
4788 if (pos.m_object !=
this)
4790 throw std::domain_error(
"iterator does not fit current value");
4795 assert(m_value.array !=
nullptr);
4796 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4801 throw std::domain_error(
"cannot use insert() with " + type_name());
4840 throw std::domain_error(
"cannot use insert() with " + type_name());
4844 if (pos.m_object !=
this)
4846 throw std::domain_error(
"iterator does not fit current value");
4849 if (first.m_object != last.m_object)
4851 throw std::domain_error(
"iterators do not fit");
4854 if (first.m_object ==
this or last.m_object ==
this)
4856 throw std::domain_error(
"passed iterators may not belong to container");
4861 assert(m_value.array !=
nullptr);
4862 result.m_it.array_iterator = m_value.array->insert(
4863 pos.m_it.array_iterator,
4864 first.m_it.array_iterator,
4865 last.m_it.array_iterator);
4898 throw std::domain_error(
"cannot use insert() with " + type_name());
4902 if (pos.m_object !=
this)
4904 throw std::domain_error(
"iterator does not fit current value");
4909 assert(m_value.array !=
nullptr);
4910 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4932 std::is_nothrow_move_constructible<value_t>::value and
4933 std::is_nothrow_move_assignable<value_t>::value and
4934 std::is_nothrow_move_constructible<json_value>::value and
4935 std::is_nothrow_move_assignable<json_value>::value
4938 std::swap(m_type, other.m_type);
4939 std::swap(m_value, other.m_value);
4967 assert(m_value.array !=
nullptr);
4968 std::swap(*(m_value.array), other);
4972 throw std::domain_error(
"cannot use swap() with " + type_name());
5001 assert(m_value.object !=
nullptr);
5002 std::swap(*(m_value.object), other);
5006 throw std::domain_error(
"cannot use swap() with " + type_name());
5035 assert(m_value.string !=
nullptr);
5036 std::swap(*(m_value.string), other);
5040 throw std::domain_error(
"cannot use swap() with " + type_name());
5066 static constexpr std::array<uint8_t, 8> order = {{
5079 if (lhs == value_t::discarded or rhs == value_t::discarded)
5084 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5113 const auto lhs_type = lhs.type();
5114 const auto rhs_type = rhs.type();
5116 if (lhs_type == rhs_type)
5120 case value_t::array:
5122 assert(lhs.m_value.array !=
nullptr);
5123 assert(rhs.m_value.array !=
nullptr);
5124 return *lhs.m_value.array == *rhs.m_value.array;
5126 case value_t::object:
5128 assert(lhs.m_value.object !=
nullptr);
5129 assert(rhs.m_value.object !=
nullptr);
5130 return *lhs.m_value.object == *rhs.m_value.object;
5136 case value_t::string:
5138 assert(lhs.m_value.string !=
nullptr);
5139 assert(rhs.m_value.string !=
nullptr);
5140 return *lhs.m_value.string == *rhs.m_value.string;
5142 case value_t::boolean:
5144 return lhs.m_value.boolean == rhs.m_value.boolean;
5146 case value_t::number_integer:
5148 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5150 case value_t::number_unsigned:
5152 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5154 case value_t::number_float:
5156 return lhs.m_value.number_float == rhs.m_value.number_float;
5164 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5166 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5168 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5170 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5172 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5174 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5176 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5178 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5180 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5182 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5184 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5186 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5242 return not (lhs == rhs);
5274 return not v.is_null();
5303 const auto lhs_type = lhs.type();
5304 const auto rhs_type = rhs.type();
5306 if (lhs_type == rhs_type)
5310 case value_t::array:
5312 assert(lhs.m_value.array !=
nullptr);
5313 assert(rhs.m_value.array !=
nullptr);
5314 return *lhs.m_value.array < *rhs.m_value.array;
5316 case value_t::object:
5318 assert(lhs.m_value.object !=
nullptr);
5319 assert(rhs.m_value.object !=
nullptr);
5320 return *lhs.m_value.object < *rhs.m_value.object;
5326 case value_t::string:
5328 assert(lhs.m_value.string !=
nullptr);
5329 assert(rhs.m_value.string !=
nullptr);
5330 return *lhs.m_value.string < *rhs.m_value.string;
5332 case value_t::boolean:
5334 return lhs.m_value.boolean < rhs.m_value.boolean;
5336 case value_t::number_integer:
5338 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5340 case value_t::number_unsigned:
5342 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5344 case value_t::number_float:
5346 return lhs.m_value.number_float < rhs.m_value.number_float;
5354 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5356 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5358 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5360 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5362 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5364 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5366 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5368 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5370 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5372 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5374 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5376 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5382 return operator<(lhs_type, rhs_type);
5404 return not (rhs < lhs);
5426 return not (lhs <= rhs);
5448 return not (lhs < rhs);
5483 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5486 const bool pretty_print = (o.width() > 0);
5487 const auto indentation = (pretty_print ? o.width() : 0);
5493 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5501 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5542 return parser(s, cb).
parse();
5571 return parser(i, cb).
parse();
5579 return parser(i, cb).
parse();
5607 j = parser(i).
parse();
5617 j = parser(i).
parse();
5636 case value_t::object:
5638 case value_t::array:
5640 case value_t::string:
5642 case value_t::boolean:
5644 case value_t::discarded:
5659 static std::size_t extra_space(
const string_t& s) noexcept
5661 std::size_t result = 0;
5663 for (
const auto& c : s)
5682 if (c >= 0x00 and c <= 0x1f)
5710 const auto space = extra_space(s);
5717 string_t result(s.size() + space,
'\\');
5718 std::size_t pos = 0;
5720 for (
const auto& c : s)
5727 result[pos + 1] =
'"';
5743 result[pos + 1] =
'b';
5751 result[pos + 1] =
'f';
5759 result[pos + 1] =
'n';
5767 result[pos + 1] =
'r';
5775 result[pos + 1] =
't';
5782 if (c >= 0x00 and c <= 0x1f)
5786 auto hexify = [](
const char v) ->
char 5788 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5793 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5831 void dump(std::ostream& o,
5832 const bool pretty_print,
5833 const unsigned int indent_step,
5834 const unsigned int current_indent = 0)
const 5837 unsigned int new_indent = current_indent;
5841 case value_t::object:
5843 assert(m_value.object !=
nullptr);
5845 if (m_value.object->empty())
5856 new_indent += indent_step;
5860 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5862 if (i != m_value.object->cbegin())
5864 o << (pretty_print ?
",\n" :
",");
5866 o <<
string_t(new_indent,
' ') <<
"\"" 5867 << escape_string(i->first) <<
"\":" 5868 << (pretty_print ?
" " :
"");
5869 i->second.dump(o, pretty_print, indent_step, new_indent);
5875 new_indent -= indent_step;
5879 o <<
string_t(new_indent,
' ') +
"}";
5883 case value_t::array:
5885 assert(m_value.array !=
nullptr);
5887 if (m_value.array->empty())
5898 new_indent += indent_step;
5902 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5904 if (i != m_value.array->cbegin())
5906 o << (pretty_print ?
",\n" :
",");
5909 i->dump(o, pretty_print, indent_step, new_indent);
5915 new_indent -= indent_step;
5919 o <<
string_t(new_indent,
' ') <<
"]";
5923 case value_t::string:
5925 assert(m_value.string !=
nullptr);
5926 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5930 case value_t::boolean:
5932 o << (m_value.boolean ?
"true" :
"false");
5936 case value_t::number_integer:
5938 o << m_value.number_integer;
5942 case value_t::number_unsigned:
5944 o << m_value.number_unsigned;
5948 case value_t::number_float:
5956 if (std::fmod(m_value.number_float, 1) == 0)
5958 o << std::fixed << std::setprecision(1);
5963 o.unsetf(std::ios_base::floatfield);
5964 o << std::setprecision(std::numeric_limits<double>::digits10);
5966 o << m_value.number_float;
5970 case value_t::discarded:
5990 value_t m_type = value_t::null;
5993 json_value m_value = {};
6010 class primitive_iterator_t
6026 bool is_begin()
const 6028 return (m_it == begin_value);
6034 return (m_it == end_value);
6054 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6064 struct internal_iterator
6067 typename object_t::iterator object_iterator;
6069 typename array_t::iterator array_iterator;
6071 primitive_iterator_t primitive_iterator;
6075 : object_iterator(), array_iterator(), primitive_iterator()
6080 template<
typename IteratorType>
6081 class iteration_proxy
6085 class iteration_proxy_internal
6089 IteratorType anchor;
6091 size_t array_index = 0;
6094 iteration_proxy_internal(IteratorType it)
6099 iteration_proxy_internal& operator*()
6105 iteration_proxy_internal& operator++()
6114 bool operator!= (
const iteration_proxy_internal& o)
const 6116 return anchor != o.anchor;
6122 assert(anchor.m_object !=
nullptr);
6124 switch (anchor.m_object->type())
6127 case value_t::array:
6129 return std::to_string(array_index);
6133 case value_t::object:
6135 return anchor.key();
6147 typename IteratorType::reference value()
const 6149 return anchor.value();
6154 typename IteratorType::reference container;
6158 iteration_proxy(
typename IteratorType::reference cont)
6163 iteration_proxy_internal begin()
6165 return iteration_proxy_internal(container.begin());
6169 iteration_proxy_internal end()
6171 return iteration_proxy_internal(container.end());
6189 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6192 friend class basic_json;
6212 assert(m_object !=
nullptr);
6214 switch (m_object->m_type)
6218 m_it.object_iterator =
typename object_t::iterator();
6224 m_it.array_iterator =
typename array_t::iterator();
6230 m_it.primitive_iterator = primitive_iterator_t();
6239 assert(m_object !=
nullptr);
6241 switch (m_object->m_type)
6245 m_it.object_iterator = other.m_it.object_iterator;
6251 m_it.array_iterator = other.m_it.array_iterator;
6257 m_it.primitive_iterator = other.m_it.primitive_iterator;
6265 : m_object(other.m_object), m_it(other.m_it)
6270 std::is_nothrow_move_constructible<pointer>::value and
6271 std::is_nothrow_move_assignable<pointer>::value and
6272 std::is_nothrow_move_constructible<internal_iterator>::value and
6273 std::is_nothrow_move_assignable<internal_iterator>::value
6276 std::swap(m_object, other.m_object);
6277 std::swap(m_it, other.m_it);
6285 assert(m_object !=
nullptr);
6287 switch (m_object->m_type)
6291 assert(m_object->m_value.object !=
nullptr);
6292 m_it.object_iterator = m_object->m_value.object->begin();
6298 assert(m_object->m_value.array !=
nullptr);
6299 m_it.array_iterator = m_object->m_value.array->begin();
6306 m_it.primitive_iterator.set_end();
6312 m_it.primitive_iterator.set_begin();
6321 assert(m_object !=
nullptr);
6323 switch (m_object->m_type)
6327 assert(m_object->m_value.object !=
nullptr);
6328 m_it.object_iterator = m_object->m_value.object->end();
6334 assert(m_object->m_value.array !=
nullptr);
6335 m_it.array_iterator = m_object->m_value.array->end();
6341 m_it.primitive_iterator.set_end();
6351 assert(m_object !=
nullptr);
6353 switch (m_object->m_type)
6357 assert(m_object->m_value.object);
6358 assert(m_it.object_iterator != m_object->m_value.object->end());
6359 return m_it.object_iterator->second;
6364 assert(m_object->m_value.array);
6365 assert(m_it.array_iterator != m_object->m_value.array->end());
6366 return *m_it.array_iterator;
6371 throw std::out_of_range(
"cannot get value");
6376 if (m_it.primitive_iterator.is_begin())
6382 throw std::out_of_range(
"cannot get value");
6391 assert(m_object !=
nullptr);
6393 switch (m_object->m_type)
6397 assert(m_object->m_value.object);
6398 assert(m_it.object_iterator != m_object->m_value.object->end());
6399 return &(m_it.object_iterator->second);
6404 assert(m_object->m_value.array);
6405 assert(m_it.array_iterator != m_object->m_value.array->end());
6406 return &*m_it.array_iterator;
6411 if (m_it.primitive_iterator.is_begin())
6417 throw std::out_of_range(
"cannot get value");
6426 auto result = *
this;
6434 assert(m_object !=
nullptr);
6436 switch (m_object->m_type)
6440 ++m_it.object_iterator;
6446 ++m_it.array_iterator;
6452 ++m_it.primitive_iterator;
6463 auto result = *
this;
6471 assert(m_object !=
nullptr);
6473 switch (m_object->m_type)
6477 --m_it.object_iterator;
6483 --m_it.array_iterator;
6489 --m_it.primitive_iterator;
6501 if (m_object != other.m_object)
6503 throw std::domain_error(
"cannot compare iterators of different containers");
6506 assert(m_object !=
nullptr);
6508 switch (m_object->m_type)
6512 return (m_it.object_iterator == other.m_it.object_iterator);
6517 return (m_it.array_iterator == other.m_it.array_iterator);
6522 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6530 return not operator==(other);
6537 if (m_object != other.m_object)
6539 throw std::domain_error(
"cannot compare iterators of different containers");
6542 assert(m_object !=
nullptr);
6544 switch (m_object->m_type)
6548 throw std::domain_error(
"cannot compare order of object iterators");
6553 return (m_it.array_iterator < other.m_it.array_iterator);
6558 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6566 return not other.operator < (*this);
6572 return not operator<=(other);
6578 return not operator<(other);
6584 assert(m_object !=
nullptr);
6586 switch (m_object->m_type)
6590 throw std::domain_error(
"cannot use offsets with object iterators");
6595 m_it.array_iterator += i;
6601 m_it.primitive_iterator += i;
6612 return operator+=(-i);
6618 auto result = *
this;
6626 auto result = *
this;
6634 assert(m_object !=
nullptr);
6636 switch (m_object->m_type)
6640 throw std::domain_error(
"cannot use offsets with object iterators");
6645 return m_it.array_iterator - other.m_it.array_iterator;
6650 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6658 assert(m_object !=
nullptr);
6660 switch (m_object->m_type)
6664 throw std::domain_error(
"cannot use operator[] for object iterators");
6669 return *(m_it.array_iterator + n);
6674 throw std::out_of_range(
"cannot get value");
6679 if (m_it.primitive_iterator == -n)
6685 throw std::out_of_range(
"cannot get value");
6692 typename object_t::key_type
key()
const 6694 assert(m_object !=
nullptr);
6696 if (m_object->is_object())
6698 return m_it.object_iterator->first;
6702 throw std::domain_error(
"cannot use key() for non-object iterators");
6716 internal_iterator m_it = internal_iterator();
6753 std::is_nothrow_move_constructible<pointer>::value and
6754 std::is_nothrow_move_assignable<pointer>::value and
6755 std::is_nothrow_move_constructible<internal_iterator>::value and
6756 std::is_nothrow_move_assignable<internal_iterator>::value
6759 base_iterator::operator=(other);
6766 return const_cast<reference>(base_iterator::operator*());
6772 return const_cast<pointer>(base_iterator::operator->());
6779 base_iterator::operator++();
6786 base_iterator::operator++();
6794 base_iterator::operator--();
6801 base_iterator::operator--();
6808 base_iterator::operator+=(i);
6815 base_iterator::operator-=(i);
6822 auto result = *
this;
6830 auto result = *
this;
6838 return base_iterator::operator-(other);
6844 return const_cast<reference>(base_iterator::operator[](n));
6850 return const_cast<reference>(base_iterator::value());
6871 template<
typename Base>
6893 return base_iterator::operator++(1);
6899 base_iterator::operator++();
6906 return base_iterator::operator--(1);
6912 base_iterator::operator--();
6919 base_iterator::operator+=(i);
6926 auto result = *
this;
6934 auto result = *
this;
6942 return this->base() - other.base();
6948 return *(this->operator+(n));
6952 typename object_t::key_type
key()
const 6954 auto it = --this->base();
6961 auto it = --this->base();
6962 return it.operator * ();
6983 enum class token_type
7002 using lexer_char_t =
unsigned char;
7005 explicit lexer(
const string_t& s) noexcept
7006 : m_stream(
nullptr), m_buffer(s)
7008 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7009 assert(m_content !=
nullptr);
7010 m_start = m_cursor = m_content;
7011 m_limit = m_content + s.size();
7015 explicit lexer(std::istream* s) noexcept
7016 : m_stream(s), m_buffer()
7018 assert(m_stream !=
nullptr);
7019 getline(*m_stream, m_buffer);
7020 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7021 assert(m_content !=
nullptr);
7022 m_start = m_cursor = m_content;
7023 m_limit = m_content + m_buffer.size();
7030 lexer(
const lexer&) =
delete;
7031 lexer operator=(
const lexer&) =
delete;
7048 static string_t to_unicode(
const std::size_t codepoint1,
7049 const std::size_t codepoint2 = 0)
7052 std::size_t codepoint = codepoint1;
7055 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7058 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7072 throw std::invalid_argument(
"missing or wrong low surrogate");
7078 if (codepoint < 0x80)
7081 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7083 else if (codepoint <= 0x7ff)
7086 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7087 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7089 else if (codepoint <= 0xffff)
7092 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7093 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7094 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7096 else if (codepoint <= 0x10ffff)
7099 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7100 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7101 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7102 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7106 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7113 static std::string token_type_name(token_type t)
7117 case token_type::uninitialized:
7118 return "<uninitialized>";
7119 case token_type::literal_true:
7120 return "true literal";
7121 case token_type::literal_false:
7122 return "false literal";
7123 case token_type::literal_null:
7124 return "null literal";
7125 case token_type::value_string:
7126 return "string literal";
7127 case token_type::value_number:
7128 return "number literal";
7129 case token_type::begin_array:
7131 case token_type::begin_object:
7133 case token_type::end_array:
7135 case token_type::end_object:
7137 case token_type::name_separator:
7139 case token_type::value_separator:
7141 case token_type::parse_error:
7142 return "<parse error>";
7143 case token_type::end_of_input:
7144 return "end of input";
7148 return "unknown token";
7163 token_type scan() noexcept
7170 assert(m_start !=
nullptr);
7175 unsigned int yyaccept = 0;
7176 static const unsigned char yybm[] =
7178 0, 0, 0, 0, 0, 0, 0, 0,
7179 0, 32, 32, 0, 0, 32, 0, 0,
7180 128, 128, 128, 128, 128, 128, 128, 128,
7181 128, 128, 128, 128, 128, 128, 128, 128,
7182 160, 128, 0, 128, 128, 128, 128, 128,
7183 128, 128, 128, 128, 128, 128, 128, 128,
7184 192, 192, 192, 192, 192, 192, 192, 192,
7185 192, 192, 128, 128, 128, 128, 128, 128,
7186 128, 128, 128, 128, 128, 128, 128, 128,
7187 128, 128, 128, 128, 128, 128, 128, 128,
7188 128, 128, 128, 128, 128, 128, 128, 128,
7189 128, 128, 128, 128, 0, 128, 128, 128,
7190 128, 128, 128, 128, 128, 128, 128, 128,
7191 128, 128, 128, 128, 128, 128, 128, 128,
7192 128, 128, 128, 128, 128, 128, 128, 128,
7193 128, 128, 128, 128, 128, 128, 128, 128,
7194 128, 128, 128, 128, 128, 128, 128, 128,
7195 128, 128, 128, 128, 128, 128, 128, 128,
7196 128, 128, 128, 128, 128, 128, 128, 128,
7197 128, 128, 128, 128, 128, 128, 128, 128,
7198 128, 128, 128, 128, 128, 128, 128, 128,
7199 128, 128, 128, 128, 128, 128, 128, 128,
7200 128, 128, 128, 128, 128, 128, 128, 128,
7201 128, 128, 128, 128, 128, 128, 128, 128,
7202 128, 128, 128, 128, 128, 128, 128, 128,
7203 128, 128, 128, 128, 128, 128, 128, 128,
7204 128, 128, 128, 128, 128, 128, 128, 128,
7205 128, 128, 128, 128, 128, 128, 128, 128,
7206 128, 128, 128, 128, 128, 128, 128, 128,
7207 128, 128, 128, 128, 128, 128, 128, 128,
7208 128, 128, 128, 128, 128, 128, 128, 128,
7209 128, 128, 128, 128, 128, 128, 128, 128,
7211 if ((m_limit - m_cursor) < 5)
7216 if (yybm[0 + yych] & 32)
7218 goto basic_json_parser_6;
7228 goto basic_json_parser_2;
7232 goto basic_json_parser_4;
7234 goto basic_json_parser_9;
7240 goto basic_json_parser_4;
7244 goto basic_json_parser_10;
7246 goto basic_json_parser_12;
7255 goto basic_json_parser_4;
7259 goto basic_json_parser_13;
7261 goto basic_json_parser_15;
7267 goto basic_json_parser_17;
7271 goto basic_json_parser_19;
7273 goto basic_json_parser_4;
7285 goto basic_json_parser_21;
7289 goto basic_json_parser_4;
7291 goto basic_json_parser_23;
7297 goto basic_json_parser_24;
7301 goto basic_json_parser_4;
7303 goto basic_json_parser_25;
7312 goto basic_json_parser_26;
7314 goto basic_json_parser_4;
7320 goto basic_json_parser_28;
7324 goto basic_json_parser_30;
7326 goto basic_json_parser_4;
7330 basic_json_parser_2:
7333 return token_type::end_of_input;
7335 basic_json_parser_4:
7337 basic_json_parser_5:
7339 return token_type::parse_error;
7341 basic_json_parser_6:
7343 if (m_limit <= m_cursor)
7348 if (yybm[0 + yych] & 32)
7350 goto basic_json_parser_6;
7355 basic_json_parser_9:
7357 yych = *(m_marker = ++m_cursor);
7360 goto basic_json_parser_5;
7362 goto basic_json_parser_32;
7363 basic_json_parser_10:
7366 return token_type::value_separator;
7368 basic_json_parser_12:
7372 goto basic_json_parser_5;
7376 goto basic_json_parser_13;
7380 goto basic_json_parser_15;
7382 goto basic_json_parser_5;
7383 basic_json_parser_13:
7385 yych = *(m_marker = ++m_cursor);
7390 goto basic_json_parser_37;
7397 goto basic_json_parser_38;
7401 goto basic_json_parser_38;
7404 basic_json_parser_14:
7406 return token_type::value_number;
7408 basic_json_parser_15:
7410 m_marker = ++m_cursor;
7411 if ((m_limit - m_cursor) < 3)
7416 if (yybm[0 + yych] & 64)
7418 goto basic_json_parser_15;
7424 goto basic_json_parser_37;
7426 goto basic_json_parser_14;
7432 goto basic_json_parser_38;
7436 goto basic_json_parser_38;
7438 goto basic_json_parser_14;
7440 basic_json_parser_17:
7443 return token_type::name_separator;
7445 basic_json_parser_19:
7448 return token_type::begin_array;
7450 basic_json_parser_21:
7453 return token_type::end_array;
7455 basic_json_parser_23:
7457 yych = *(m_marker = ++m_cursor);
7460 goto basic_json_parser_39;
7462 goto basic_json_parser_5;
7463 basic_json_parser_24:
7465 yych = *(m_marker = ++m_cursor);
7468 goto basic_json_parser_40;
7470 goto basic_json_parser_5;
7471 basic_json_parser_25:
7473 yych = *(m_marker = ++m_cursor);
7476 goto basic_json_parser_41;
7478 goto basic_json_parser_5;
7479 basic_json_parser_26:
7482 return token_type::begin_object;
7484 basic_json_parser_28:
7487 return token_type::end_object;
7489 basic_json_parser_30:
7491 yych = *(m_marker = ++m_cursor);
7494 goto basic_json_parser_42;
7496 goto basic_json_parser_5;
7497 basic_json_parser_31:
7499 if (m_limit <= m_cursor)
7504 basic_json_parser_32:
7505 if (yybm[0 + yych] & 128)
7507 goto basic_json_parser_31;
7511 goto basic_json_parser_33;
7515 goto basic_json_parser_34;
7517 goto basic_json_parser_36;
7518 basic_json_parser_33:
7519 m_cursor = m_marker;
7522 goto basic_json_parser_5;
7526 goto basic_json_parser_14;
7528 basic_json_parser_34:
7531 return token_type::value_string;
7533 basic_json_parser_36:
7535 if (m_limit <= m_cursor)
7546 goto basic_json_parser_31;
7550 goto basic_json_parser_33;
7552 goto basic_json_parser_31;
7560 goto basic_json_parser_33;
7562 goto basic_json_parser_31;
7568 goto basic_json_parser_31;
7570 goto basic_json_parser_33;
7580 goto basic_json_parser_31;
7584 goto basic_json_parser_31;
7586 goto basic_json_parser_33;
7594 goto basic_json_parser_31;
7596 goto basic_json_parser_33;
7602 goto basic_json_parser_31;
7606 goto basic_json_parser_43;
7608 goto basic_json_parser_33;
7612 basic_json_parser_37:
7616 goto basic_json_parser_33;
7620 goto basic_json_parser_44;
7622 goto basic_json_parser_33;
7623 basic_json_parser_38:
7629 goto basic_json_parser_46;
7631 goto basic_json_parser_33;
7637 goto basic_json_parser_46;
7641 goto basic_json_parser_33;
7645 goto basic_json_parser_47;
7647 goto basic_json_parser_33;
7649 basic_json_parser_39:
7653 goto basic_json_parser_49;
7655 goto basic_json_parser_33;
7656 basic_json_parser_40:
7660 goto basic_json_parser_50;
7662 goto basic_json_parser_33;
7663 basic_json_parser_41:
7667 goto basic_json_parser_51;
7669 goto basic_json_parser_33;
7670 basic_json_parser_42:
7674 goto basic_json_parser_52;
7676 goto basic_json_parser_33;
7677 basic_json_parser_43:
7679 if (m_limit <= m_cursor)
7688 goto basic_json_parser_33;
7692 goto basic_json_parser_54;
7694 goto basic_json_parser_33;
7700 goto basic_json_parser_54;
7704 goto basic_json_parser_33;
7708 goto basic_json_parser_54;
7710 goto basic_json_parser_33;
7712 basic_json_parser_44:
7714 m_marker = ++m_cursor;
7715 if ((m_limit - m_cursor) < 3)
7724 goto basic_json_parser_14;
7728 goto basic_json_parser_44;
7730 goto basic_json_parser_14;
7736 goto basic_json_parser_38;
7740 goto basic_json_parser_38;
7742 goto basic_json_parser_14;
7744 basic_json_parser_46:
7748 goto basic_json_parser_33;
7752 goto basic_json_parser_33;
7754 basic_json_parser_47:
7756 if (m_limit <= m_cursor)
7763 goto basic_json_parser_14;
7767 goto basic_json_parser_47;
7769 goto basic_json_parser_14;
7770 basic_json_parser_49:
7774 goto basic_json_parser_55;
7776 goto basic_json_parser_33;
7777 basic_json_parser_50:
7781 goto basic_json_parser_56;
7783 goto basic_json_parser_33;
7784 basic_json_parser_51:
7788 goto basic_json_parser_58;
7790 goto basic_json_parser_33;
7791 basic_json_parser_52:
7796 basic_json_parser_54:
7798 if (m_limit <= m_cursor)
7807 goto basic_json_parser_33;
7811 goto basic_json_parser_60;
7813 goto basic_json_parser_33;
7819 goto basic_json_parser_60;
7823 goto basic_json_parser_33;
7827 goto basic_json_parser_60;
7829 goto basic_json_parser_33;
7831 basic_json_parser_55:
7835 goto basic_json_parser_61;
7837 goto basic_json_parser_33;
7838 basic_json_parser_56:
7841 return token_type::literal_null;
7843 basic_json_parser_58:
7846 return token_type::literal_true;
7848 basic_json_parser_60:
7850 if (m_limit <= m_cursor)
7859 goto basic_json_parser_33;
7863 goto basic_json_parser_63;
7865 goto basic_json_parser_33;
7871 goto basic_json_parser_63;
7875 goto basic_json_parser_33;
7879 goto basic_json_parser_63;
7881 goto basic_json_parser_33;
7883 basic_json_parser_61:
7886 return token_type::literal_false;
7888 basic_json_parser_63:
7890 if (m_limit <= m_cursor)
7899 goto basic_json_parser_33;
7903 goto basic_json_parser_31;
7905 goto basic_json_parser_33;
7911 goto basic_json_parser_31;
7915 goto basic_json_parser_33;
7919 goto basic_json_parser_31;
7921 goto basic_json_parser_33;
7929 void yyfill() noexcept
7931 if (m_stream ==
nullptr or not * m_stream)
7936 const ssize_t offset_start = m_start - m_content;
7937 const ssize_t offset_marker = m_marker - m_start;
7938 const ssize_t offset_cursor = m_cursor - m_start;
7940 m_buffer.erase(0, static_cast<size_t>(offset_start));
7942 assert(m_stream !=
nullptr);
7943 std::getline(*m_stream, line);
7944 m_buffer +=
"\n" + line;
7946 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7947 assert(m_content !=
nullptr);
7948 m_start = m_content;
7949 m_marker = m_start + offset_marker;
7950 m_cursor = m_start + offset_cursor;
7951 m_limit = m_start + m_buffer.size() - 1;
7955 string_t get_token()
const noexcept
7957 assert(m_start !=
nullptr);
7958 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7959 static_cast<size_t>(m_cursor - m_start));
7986 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7989 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8045 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8046 4).c_str(),
nullptr, 16);
8049 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8052 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8054 throw std::invalid_argument(
"missing low surrogate");
8058 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8059 (i + 7), 4).c_str(),
nullptr, 16);
8060 result += to_unicode(codepoint, codepoint2);
8067 result += to_unicode(codepoint);
8079 result.append(1, static_cast<typename string_t::value_type>(*i));
8106 long double str_to_float_t(
long double* ,
char** endptr)
const 8108 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8126 double str_to_float_t(
double* ,
char** endptr)
const 8128 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8146 float str_to_float_t(
float* ,
char** endptr)
const 8148 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8163 template <
typename T_A,
typename T_B>
8164 bool attempt_cast(T_A source, T_B& dest)
const 8166 dest =
static_cast<T_B
>(source);
8167 return (source == static_cast<T_A>(dest));
8208 void get_number(basic_json& result)
const 8210 typename string_t::value_type* endptr;
8211 assert(m_start !=
nullptr);
8216 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8220 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8221 10), result.m_value.number_unsigned))
8223 result.m_type = value_t::number_unsigned;
8228 result.m_type = value_t::number_float;
8235 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8236 10), result.m_value.number_integer))
8238 result.m_type = value_t::number_integer;
8243 result.m_type = value_t::number_float;
8249 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8251 result.m_type = value_t::number_float;
8254 if (result.m_type == value_t::number_float)
8261 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8264 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8266 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8273 std::istream* m_stream =
nullptr;
8277 const lexer_char_t* m_content =
nullptr;
8279 const lexer_char_t* m_start =
nullptr;
8281 const lexer_char_t* m_marker =
nullptr;
8283 const lexer_char_t* m_cursor =
nullptr;
8285 const lexer_char_t* m_limit =
nullptr;
8298 : callback(cb), m_lexer(s)
8306 : callback(cb), m_lexer(&_is)
8315 basic_json result = parse_internal(
true);
8317 expect(lexer::token_type::end_of_input);
8326 basic_json parse_internal(
bool keep)
8328 auto result = basic_json(value_t::discarded);
8332 case lexer::token_type::begin_object:
8334 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8337 result.m_type = value_t::object;
8338 result.m_value = json_value(value_t::object);
8345 if (last_token == lexer::token_type::end_object)
8348 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8350 result = basic_json(value_t::discarded);
8356 unexpect(lexer::token_type::value_separator);
8362 if (last_token == lexer::token_type::value_separator)
8368 expect(lexer::token_type::value_string);
8369 const auto key = m_lexer.get_string();
8371 bool keep_tag =
false;
8377 keep_tag = callback(depth, parse_event_t::key, k);
8387 expect(lexer::token_type::name_separator);
8391 auto value = parse_internal(keep);
8392 if (keep and keep_tag and not value.is_discarded())
8394 result[key] = std::move(value);
8397 while (last_token == lexer::token_type::value_separator);
8400 expect(lexer::token_type::end_object);
8402 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8404 result = basic_json(value_t::discarded);
8410 case lexer::token_type::begin_array:
8412 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8415 result.m_type = value_t::array;
8416 result.m_value = json_value(value_t::array);
8423 if (last_token == lexer::token_type::end_array)
8426 if (callback and not callback(--depth, parse_event_t::array_end, result))
8428 result = basic_json(value_t::discarded);
8434 unexpect(lexer::token_type::value_separator);
8440 if (last_token == lexer::token_type::value_separator)
8446 auto value = parse_internal(keep);
8447 if (keep and not value.is_discarded())
8449 result.push_back(std::move(value));
8452 while (last_token == lexer::token_type::value_separator);
8455 expect(lexer::token_type::end_array);
8457 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8459 result = basic_json(value_t::discarded);
8465 case lexer::token_type::literal_null:
8468 result.m_type = value_t::null;
8472 case lexer::token_type::value_string:
8474 const auto s = m_lexer.get_string();
8476 result = basic_json(s);
8480 case lexer::token_type::literal_true:
8483 result.m_type = value_t::boolean;
8484 result.m_value =
true;
8488 case lexer::token_type::literal_false:
8491 result.m_type = value_t::boolean;
8492 result.m_value =
false;
8496 case lexer::token_type::value_number:
8498 m_lexer.get_number(result);
8506 unexpect(last_token);
8510 if (keep and callback and not callback(depth, parse_event_t::value, result))
8512 result = basic_json(value_t::discarded);
8518 typename lexer::token_type get_token()
8520 last_token = m_lexer.scan();
8524 void expect(
typename lexer::token_type t)
const 8526 if (t != last_token)
8528 std::string error_msg =
"parse error - unexpected ";
8529 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8530 lexer::token_type_name(last_token));
8531 error_msg +=
"; expected " + lexer::token_type_name(t);
8532 throw std::invalid_argument(error_msg);
8536 void unexpect(
typename lexer::token_type t)
const 8538 if (t == last_token)
8540 std::string error_msg =
"parse error - unexpected ";
8541 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8542 lexer::token_type_name(last_token));
8543 throw std::invalid_argument(error_msg);
8553 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8591 is_nothrow_move_constructible<nlohmann::json>::value and
8592 is_nothrow_move_assignable<nlohmann::json>::value
8610 const auto& h = hash<nlohmann::json::string_t>();
8628 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8634 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8635 #pragma GCC diagnostic pop bool is_null() const noexcept
return whether value is null
reference operator*()
return a reference to the value pointed to by the iterator
reverse_iterator rbegin()
returns an iterator to the reverse-beginning
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
basic_json(const value_t value_type)
create an empty value with a given type
basic_json(const array_t &val)
create an array (explicit)
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
value_t type() const noexcept
return the type of the JSON value (explicit)
bool is_number_integer() const noexcept
return whether value is an integer number
const_reference operator[](size_type idx) const
access specified array element
reference value() const
return the value of an iterator
json_reverse_iterator & operator--()
pre-decrement (–it)
bool is_boolean() const noexcept
return whether value is a boolean
void clear() noexcept
clears the contents
bool operator==(const const_iterator &other) const
comparison: equal
json_reverse_iterator operator--(int)
post-decrement (it–)
reference operator[](T *(&key)[n])
access specified object element
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
bool is_number() const noexcept
return whether value is a number
iterator & operator+=(difference_type i)
add to 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_iterator operator-(difference_type i)
subtract from iterator
BooleanType boolean_t
a type for a boolean
reference operator+=(const typename object_t::value_type &val)
add an object to an object
bool is_array() const noexcept
return whether value is an array
basic_json(const typename string_t::value_type *val)
create a string (explicit)
basic_json(boolean_t val)
create a boolean (explicit)
reference operator[](difference_type n) const
access to successor
iterator find(typename object_t::key_type key)
find an element in a JSON object
basic_json(const number_unsigned_t val)
create an unsigned integer number (explicit)
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
basic_json(const string_t &val)
create a string (explicit)
void push_back(const basic_json &val)
add an object to an array
void erase(const size_type idx)
remove element from a JSON array given an index
basic_json<> json
default JSON class
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
bool is_structured() const noexcept
return whether type is structured
reference front()
access the first element
void swap(object_t &other)
exchanges the values
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
const_iterator & operator+=(difference_type i)
add to iterator
a class to store JSON values
basic_json(const number_float_t val)
create a floating-point number (explicit)
pointer operator->()
dereference the iterator
reference value() const
return the value of an iterator
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
const_reverse_iterator crbegin() const
returns a const reverse iterator to the last element
NumberIntegerType number_integer_t
a type for a number (integer)
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
const_iterator operator+(difference_type i)
add to iterator
const_reverse_iterator rbegin() const
returns a const reverse iterator to the last element
a mutable random access iterator for the basic_json class
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
const_iterator operator++(int)
post-increment (it++)
bool is_string() const noexcept
return whether value is a string
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
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
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
PointerType get_ptr() noexcept
get a pointer value (implicit)
reference back()
access the last element
const value_type & const_reference
the type of an element const reference
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
void push_back(const typename object_t::value_type &val)
add an object to an object
iterator end()
returns an iterator to one past the last element
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
reference operator[](difference_type n) const
access to successor
static allocator_type get_allocator()
returns the allocator associated with the container
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
const_reference operator[](T *key) const
read-only access specified object element
json_reverse_iterator operator+(difference_type i) const
add to iterator
bool empty() const noexcept
checks whether the container is empty
std::size_t size_type
a type to represent container sizes
object_t::key_type key() const
return the key of an object iterator
basic_json(const CompatibleArrayType &val)
create an array (implicit)
const_reference at(size_type idx) const
access specified array element with bounds checking
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
const_iterator(const iterator &other)
copy constructor given a nonconst iterator
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
iterator insert(const_iterator pos, const basic_json &val)
inserts element
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
iterator & operator++()
pre-increment (++it)
bool operator<(const const_iterator &other) const
comparison: smaller
iterator operator++(int)
post-increment (it++)
basic_json(basic_json &&other) noexcept
move constructor
const_iterator operator--(int)
post-decrement (it–)
bool is_discarded() const noexcept
return whether value is discarded
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
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
object (unordered set of name/value pairs)
size_type max_size() const noexcept
returns the maximum possible number of elements
iterator operator--(int)
post-decrement (it–)
iterator operator-(difference_type i)
subtract from iterator
const_iterator & operator--()
pre-decrement (–it)
const_iterator cend() const
returns a const iterator to one past the last element
string_t dump(const int indent=-1) const
serialization
basic_json value_type
the type of elements in a basic_json container
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
AllocatorType< basic_json > allocator_type
the allocator type
StringType string_t
a type for a string
reference operator+=(const basic_json &val)
add an object to an array
iterator begin()
returns an iterator to the first element
difference_type operator-(const const_iterator &other) const
return difference
value_type & reference
the type of an element reference
const_iterator begin() const
returns a const iterator to the first element
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
difference_type operator-(const iterator &other) const
return difference
basic_json(const int val)
create an integer number from an enum type (explicit)
iterator(const iterator &other) noexcept
copy constructor
namespace for Niels Lohmann
typename basic_json::difference_type difference_type
a type to represent differences between iterators
void swap(string_t &other)
exchanges the values
json_reverse_iterator(const base_iterator &it)
create reverse iterator from base class
basic_json(const number_integer_t val)
create an integer number (explicit)
reverse_iterator rend()
returns an iterator to the reverse-end
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
const_reference front() const
access the first element
bool operator>(const const_iterator &other) const
comparison: greater than
bool is_object() const noexcept
return whether value is an object
pointer operator->() const
dereference the iterator
NumberFloatType number_float_t
a type for a number (floating-point)
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
value_t
the JSON type enumeration
const_reverse_iterator rend() const
returns a const reverse iterator to one before the first
std::ptrdiff_t difference_type
a type to represent differences between iterators
bool is_primitive() const noexcept
return whether type is primitive
ValueType get() const
get a value (explicit)
void swap(array_t &other)
exchanges the values
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
typename Base::reference reference
the reference type for the pointed-to element
const_reference back() const
access the last element
void push_back(basic_json &&val)
add an object to an array
array (ordered collection of values)
json_reverse_iterator & operator++()
pre-increment (++it)
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
ReferenceType get_ref() const
get a reference value (implicit)
basic_json(const CompatibleNumberUnsignedType val) noexcept
create an unsigned number (implicit)
const_iterator(pointer object)
constructor for a given JSON instance
reference operator*() const
return a reference to the value pointed to by the iterator
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON types
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
iterator operator+(difference_type i)
add to iterator
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
bool operator<=(const const_iterator &other) const
comparison: less than or equal
InteratorType erase(InteratorType pos)
remove element given an 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
iterator(pointer object) noexcept
constructor for a given JSON instance
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
json_reverse_iterator(const typename base_iterator::iterator_type &it)
create reverse iterator from iterator
const_iterator & operator++()
pre-increment (++it)
bool is_number_float() const noexcept
return whether value is a floating-point number
reference value() const
return the value of an iterator
std::bidirectional_iterator_tag iterator_category
the category of the iterator
difference_type operator-(const json_reverse_iterator &other) const
return difference
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
basic_json(const CompatibleObjectType &val)
create an object (implicit)
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
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
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
reference operator[](const typename object_t::key_type &key)
access specified object element
object_t::key_type key() const
return the key of an object iterator
const_iterator end() const
returns a const iterator to one past the last element
reference operator+=(basic_json &&val)
add an object to an array
reference operator[](difference_type n) const
access to successor
a const random access iterator for the basic_json class
a template for a reverse iterator class
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
json_reverse_iterator operator++(int)
post-increment (it++)
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
reference operator[](size_type idx)
access specified array element
bool operator!=(const const_iterator &other) const
comparison: not equal
json_reverse_iterator & operator+=(difference_type i)
add to iterator
reference at(size_type idx)
access specified array element with bounds checking
size_type size() const noexcept
returns the number of elements
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
const_iterator cbegin() const
returns a const iterator to the first element
iterator & operator-=(difference_type i)
subtract from iterator
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
basic_json(const object_t &val)
create an object (explicit)
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
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
const_iterator(const const_iterator &other) noexcept
copy constructor
iterator & operator--()
pre-decrement (–it)
iterator insert(const_iterator pos, basic_json &&val)
inserts element
ReferenceType get_ref()
get a reference value (implicit)
const_iterator & operator-=(difference_type i)
subtract from iterator
basic_json(const CompatibleStringType &val)
create a string (implicit)
basic_json(const basic_json &other)
copy constructor
reference operator[](T *key)
access specified object element
parse_event_t
JSON callback events.