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;
185 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
186 template<
typename U,
typename... Args>
class ArrayType = std::vector,
187 class StringType = std::string,
188 class BooleanType = bool,
189 class NumberIntegerType = int64_t,
190 class NumberUnsignedType = uint64_t,
191 class NumberFloatType = double,
192 template<
typename U>
class AllocatorType = std::allocator
233 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
235 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
350 using object_t = ObjectType<StringType,
352 std::less<StringType>,
353 AllocatorType<std::pair<
const StringType,
400 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
719 template<
typename T,
typename... Args>
720 static T* create(Args&& ... args)
722 AllocatorType<T> alloc;
723 auto deleter = [&](T * object)
725 alloc.deallocate(
object, 1);
727 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
728 alloc.construct(
object.
get(), std::forward<Args>(args)...);
729 return object.release();
761 json_value() noexcept =
default;
763 json_value(
boolean_t v) noexcept : boolean(v) {}
775 case value_t::object:
777 object = create<object_t>();
783 array = create<array_t>();
787 case value_t::string:
789 string = create<string_t>(
"");
793 case value_t::boolean:
799 case value_t::number_integer:
805 case value_t::number_unsigned:
811 case value_t::number_float:
827 string = create<string_t>(value);
833 object = create<object_t>(value);
837 json_value(
const array_t& value)
839 array = create<array_t>(value);
922 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
972 : m_type(value_type), m_value(value_type)
994 basic_json() noexcept =
default;
1039 : m_type(
value_t::object), m_value(val)
1065 template <
class CompatibleObjectType,
typename 1067 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1068 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
1075 m_value.object = create<object_t>(begin(val), end(val));
1098 : m_type(
value_t::array), m_value(val)
1124 template <
class CompatibleArrayType,
typename 1126 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1127 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1128 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1129 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1130 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1131 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1132 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1139 m_value.array = create<array_t>(begin(val), end(val));
1164 : m_type(
value_t::string), m_value(val)
1214 template <
class CompatibleStringType,
typename 1216 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1237 : m_type(
value_t::boolean), m_value(val)
1265 template<
typename T,
1266 typename std::enable_if<
1267 not (std::is_same<T, int>::value)
1268 and std::is_same<T, number_integer_t>::value
1272 : m_type(
value_t::number_integer), m_value(val)
1301 : m_type(
value_t::number_integer),
1330 template<
typename CompatibleNumberIntegerType,
typename 1332 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1333 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1334 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1335 CompatibleNumberIntegerType>::type
1338 : m_type(value_t::number_integer),
1339 m_value(static_cast<number_integer_t>(val))
1359 template<
typename T,
1360 typename std::enable_if<
1361 not (std::is_same<T, int>::value)
1362 and std::is_same<T, number_unsigned_t>::value
1366 : m_type(
value_t::number_unsigned), m_value(val)
1389 template <
typename CompatibleNumberUnsignedType,
typename 1391 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1392 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1393 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1394 CompatibleNumberUnsignedType >::type
1397 : m_type(value_t::number_unsigned),
1398 m_value(static_cast<number_unsigned_t>(val))
1426 : m_type(
value_t::number_float), m_value(val)
1429 if (not std::isfinite(val))
1431 m_type = value_t::null;
1432 m_value = json_value();
1466 template<
typename CompatibleNumberFloatType,
typename =
typename 1468 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1469 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1545 bool type_deduction =
true,
1546 value_t manual_type = value_t::array)
1549 bool is_an_object =
true;
1553 for (
const auto& element : init)
1555 if (not element.is_array() or element.size() != 2
1556 or not element[0].is_string())
1560 is_an_object =
false;
1566 if (not type_deduction)
1569 if (manual_type == value_t::array)
1571 is_an_object =
false;
1575 if (manual_type == value_t::object and not is_an_object)
1577 throw std::domain_error(
"cannot create object from initializer list");
1584 m_type = value_t::object;
1585 m_value = value_t::object;
1587 assert(m_value.object !=
nullptr);
1589 for (
auto& element : init)
1591 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1597 m_type = value_t::array;
1598 m_value.array = create<array_t>(std::move(init));
1636 static basic_json
array(std::initializer_list<basic_json> init =
1637 std::initializer_list<basic_json>())
1639 return basic_json(init,
false, value_t::array);
1676 static basic_json
object(std::initializer_list<basic_json> init =
1677 std::initializer_list<basic_json>())
1679 return basic_json(init,
false, value_t::object);
1703 m_value.array = create<array_t>(cnt, val);
1740 template <
class InputIT,
typename 1742 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1743 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1746 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1749 if (first.m_object != last.m_object)
1751 throw std::domain_error(
"iterators are not compatible");
1757 case value_t::boolean:
1758 case value_t::number_float:
1759 case value_t::number_integer:
1760 case value_t::number_unsigned:
1761 case value_t::string:
1763 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1765 throw std::out_of_range(
"iterators out of range");
1778 case value_t::number_integer:
1780 assert(first.m_object !=
nullptr);
1781 m_value.number_integer = first.m_object->m_value.number_integer;
1785 case value_t::number_unsigned:
1787 assert(first.m_object !=
nullptr);
1788 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1792 case value_t::number_float:
1794 assert(first.m_object !=
nullptr);
1795 m_value.number_float = first.m_object->m_value.number_float;
1799 case value_t::boolean:
1801 assert(first.m_object !=
nullptr);
1802 m_value.boolean = first.m_object->m_value.boolean;
1806 case value_t::string:
1808 assert(first.m_object !=
nullptr);
1809 m_value = *first.m_object->m_value.string;
1813 case value_t::object:
1815 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1819 case value_t::array:
1821 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1827 assert(first.m_object !=
nullptr);
1828 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1858 : m_type(other.m_type)
1862 case value_t::object:
1864 assert(other.m_value.object !=
nullptr);
1865 m_value = *other.m_value.object;
1869 case value_t::array:
1871 assert(other.m_value.array !=
nullptr);
1872 m_value = *other.m_value.array;
1876 case value_t::string:
1878 assert(other.m_value.string !=
nullptr);
1879 m_value = *other.m_value.string;
1883 case value_t::boolean:
1885 m_value = other.m_value.boolean;
1889 case value_t::number_integer:
1891 m_value = other.m_value.number_integer;
1895 case value_t::number_unsigned:
1897 m_value = other.m_value.number_unsigned;
1901 case value_t::number_float:
1903 m_value = other.m_value.number_float;
1933 : m_type(
std::move(other.m_type)),
1934 m_value(
std::move(other.m_value))
1937 other.m_type = value_t::null;
1963 std::is_nothrow_move_constructible<value_t>::value and
1964 std::is_nothrow_move_assignable<value_t>::value and
1965 std::is_nothrow_move_constructible<json_value>::value and
1966 std::is_nothrow_move_assignable<json_value>::value
1970 swap(m_type, other.m_type);
1971 swap(m_value, other.m_value);
1992 case value_t::object:
1994 AllocatorType<object_t> alloc;
1995 alloc.destroy(m_value.object);
1996 alloc.deallocate(m_value.object, 1);
2000 case value_t::array:
2002 AllocatorType<array_t> alloc;
2003 alloc.destroy(m_value.array);
2004 alloc.deallocate(m_value.array, 1);
2008 case value_t::string:
2010 AllocatorType<string_t> alloc;
2011 alloc.destroy(m_value.string);
2012 alloc.deallocate(m_value.string, 1);
2059 std::stringstream ss;
2063 dump(ss,
true, static_cast<unsigned int>(indent));
2111 return is_null() or is_string() or is_boolean() or is_number();
2131 return is_array() or is_object();
2150 return m_type == value_t::null;
2169 return m_type == value_t::boolean;
2196 return is_number_integer() or is_number_float();
2222 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2247 return m_type == value_t::number_unsigned;
2272 return m_type == value_t::number_float;
2291 return m_type == value_t::object;
2310 return m_type == value_t::array;
2329 return m_type == value_t::string;
2353 return m_type == value_t::discarded;
2384 template <
class T,
typename 2386 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2387 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2389 T get_impl(T*)
const 2393 assert(m_value.object !=
nullptr);
2394 return T(m_value.object->begin(), m_value.object->end());
2398 throw std::domain_error(
"type must be object, but is " + type_name());
2407 assert(m_value.object !=
nullptr);
2408 return *(m_value.object);
2412 throw std::domain_error(
"type must be object, but is " + type_name());
2417 template <
class T,
typename 2419 std::is_convertible<basic_json_t, typename T::value_type>::value and
2420 not std::is_same<basic_json_t, typename T::value_type>::value and
2421 not std::is_arithmetic<T>::value and
2422 not std::is_convertible<std::string, T>::value and
2423 not has_mapped_type<T>::value
2425 T get_impl(T*)
const 2430 assert(m_value.array !=
nullptr);
2431 std::transform(m_value.array->begin(), m_value.array->end(),
2432 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2434 return i.
get<
typename T::value_type>();
2440 throw std::domain_error(
"type must be array, but is " + type_name());
2445 template <
class T,
typename 2447 std::is_convertible<basic_json_t, T>::value and
2448 not std::is_same<basic_json_t, T>::value
2450 std::vector<T> get_impl(std::vector<T>*)
const 2454 std::vector<T> to_vector;
2455 assert(m_value.array !=
nullptr);
2456 to_vector.reserve(m_value.array->size());
2457 std::transform(m_value.array->begin(), m_value.array->end(),
2458 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2466 throw std::domain_error(
"type must be array, but is " + type_name());
2471 template <
class T,
typename 2473 std::is_same<basic_json, typename T::value_type>::value and
2474 not has_mapped_type<T>::value
2476 T get_impl(T*)
const 2480 assert(m_value.array !=
nullptr);
2481 return T(m_value.array->begin(), m_value.array->end());
2485 throw std::domain_error(
"type must be array, but is " + type_name());
2494 assert(m_value.array !=
nullptr);
2495 return *(m_value.array);
2499 throw std::domain_error(
"type must be array, but is " + type_name());
2504 template <
typename T,
typename 2506 std::is_convertible<string_t, T>::value
2508 T get_impl(T*)
const 2512 assert(m_value.string !=
nullptr);
2513 return *m_value.string;
2517 throw std::domain_error(
"type must be string, but is " + type_name());
2522 template<
typename T,
typename 2524 std::is_arithmetic<T>::value
2526 T get_impl(T*)
const 2530 case value_t::number_integer:
2532 return static_cast<T
>(m_value.number_integer);
2535 case value_t::number_unsigned:
2537 return static_cast<T
>(m_value.number_unsigned);
2540 case value_t::number_float:
2542 return static_cast<T
>(m_value.number_float);
2547 throw std::domain_error(
"type must be number, but is " + type_name());
2557 return m_value.boolean;
2561 throw std::domain_error(
"type must be boolean, but is " + type_name());
2568 return is_object() ? m_value.object :
nullptr;
2574 return is_object() ? m_value.object :
nullptr;
2580 return is_array() ? m_value.array :
nullptr;
2586 return is_array() ? m_value.array :
nullptr;
2592 return is_string() ? m_value.string :
nullptr;
2598 return is_string() ? m_value.string :
nullptr;
2604 return is_boolean() ? &m_value.boolean :
nullptr;
2610 return is_boolean() ? &m_value.boolean :
nullptr;
2616 return is_number_integer() ? &m_value.number_integer :
nullptr;
2622 return is_number_integer() ? &m_value.number_integer :
nullptr;
2628 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2634 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2640 return is_number_float() ? &m_value.number_float :
nullptr;
2646 return is_number_float() ? &m_value.number_float :
nullptr;
2660 template<
typename ReferenceType,
typename ThisType>
2661 static ReferenceType get_ref_impl(ThisType& obj)
2664 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2665 auto ptr = obj.template get_ptr<PointerType>();
2673 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2716 template<
typename ValueType,
typename 2718 not std::is_pointer<ValueType>::value
2720 ValueType
get()
const 2722 return get_impl(static_cast<ValueType*>(
nullptr));
2751 template<
typename PointerType,
typename 2753 std::is_pointer<PointerType>::value
2755 PointerType
get() noexcept
2758 return get_ptr<PointerType>();
2765 template<
typename PointerType,
typename 2767 std::is_pointer<PointerType>::value
2769 const PointerType
get()
const noexcept
2772 return get_ptr<PointerType>();
2800 template<
typename PointerType,
typename 2802 std::is_pointer<PointerType>::value
2807 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2814 template<
typename PointerType,
typename 2816 std::is_pointer<PointerType>::value
2817 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2822 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2851 template<
typename ReferenceType,
typename 2853 std::is_reference<ReferenceType>::value
2858 return get_ref_impl<ReferenceType>(*this);
2865 template<
typename ReferenceType,
typename 2867 std::is_reference<ReferenceType>::value
2868 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2873 return get_ref_impl<ReferenceType>(*this);
2904 template <
typename ValueType,
typename 2906 not std::is_pointer<ValueType>::value
2907 and not std::is_same<ValueType, typename string_t::value_type>::value
2908 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2909 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2912 operator ValueType()
const 2915 return get<ValueType>();
2957 assert(m_value.array !=
nullptr);
2958 return m_value.array->at(idx);
2960 catch (std::out_of_range&)
2963 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2968 throw std::domain_error(
"cannot use at() with " + type_name());
3001 assert(m_value.array !=
nullptr);
3002 return m_value.array->at(idx);
3004 catch (std::out_of_range&)
3007 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3012 throw std::domain_error(
"cannot use at() with " + type_name());
3049 assert(m_value.object !=
nullptr);
3050 return m_value.object->at(key);
3052 catch (std::out_of_range&)
3055 throw std::out_of_range(
"key '" + key +
"' not found");
3060 throw std::domain_error(
"cannot use at() with " + type_name());
3097 assert(m_value.object !=
nullptr);
3098 return m_value.object->at(key);
3100 catch (std::out_of_range&)
3103 throw std::out_of_range(
"key '" + key +
"' not found");
3108 throw std::domain_error(
"cannot use at() with " + type_name());
3142 m_type = value_t::array;
3143 m_value.
array = create<array_t>();
3149 assert(m_value.array !=
nullptr);
3150 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3152 m_value.array->push_back(basic_json());
3155 return m_value.array->operator[](idx);
3159 throw std::domain_error(
"cannot use operator[] with " + type_name());
3187 assert(m_value.array !=
nullptr);
3188 return m_value.array->operator[](idx);
3192 throw std::domain_error(
"cannot use operator[] with " + type_name());
3228 m_type = value_t::object;
3229 m_value.
object = create<object_t>();
3235 assert(m_value.object !=
nullptr);
3236 return m_value.object->operator[](key);
3240 throw std::domain_error(
"cannot use operator[] with " + type_name());
3276 assert(m_value.object !=
nullptr);
3277 assert(m_value.object->find(key) != m_value.object->end());
3278 return m_value.object->find(key)->second;
3282 throw std::domain_error(
"cannot use operator[] with " + type_name());
3313 template<
typename T, std::
size_t n>
3316 return operator[](static_cast<const T>(key));
3348 template<
typename T, std::
size_t n>
3351 return operator[](static_cast<const T>(key));
3381 template<
typename T>
3387 m_type = value_t::object;
3388 m_value = value_t::object;
3394 assert(m_value.object !=
nullptr);
3395 return m_value.object->operator[](key);
3399 throw std::domain_error(
"cannot use operator[] with " + type_name());
3430 template<
typename T>
3436 assert(m_value.object !=
nullptr);
3437 assert(m_value.object->find(key) != m_value.object->end());
3438 return m_value.object->find(key)->second;
3442 throw std::domain_error(
"cannot use operator[] with " + type_name());
3494 template <
class ValueType,
typename 3496 std::is_convertible<basic_json_t, ValueType>::value
3498 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3504 const auto it = find(key);
3511 return default_value;
3516 throw std::domain_error(
"cannot use value() with " + type_name());
3524 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3526 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;
4206 template<
typename IteratorType>
class iteration_proxy;
4222 return iteration_proxy<iterator>(cont);
4230 return iteration_proxy<const_iterator>(cont);
4282 case value_t::array:
4284 assert(m_value.array !=
nullptr);
4285 return m_value.array->empty();
4288 case value_t::object:
4290 assert(m_value.object !=
nullptr);
4291 return m_value.object->empty();
4340 case value_t::array:
4342 assert(m_value.array !=
nullptr);
4343 return m_value.array->size();
4346 case value_t::object:
4348 assert(m_value.object !=
nullptr);
4349 return m_value.object->size();
4396 case value_t::array:
4398 assert(m_value.array !=
nullptr);
4399 return m_value.array->max_size();
4402 case value_t::object:
4404 assert(m_value.object !=
nullptr);
4405 return m_value.object->max_size();
4455 case value_t::number_integer:
4457 m_value.number_integer = 0;
4461 case value_t::number_unsigned:
4463 m_value.number_unsigned = 0;
4467 case value_t::number_float:
4469 m_value.number_float = 0.0;
4473 case value_t::boolean:
4475 m_value.boolean =
false;
4479 case value_t::string:
4481 assert(m_value.string !=
nullptr);
4482 m_value.string->clear();
4486 case value_t::array:
4488 assert(m_value.array !=
nullptr);
4489 m_value.array->clear();
4493 case value_t::object:
4495 assert(m_value.object !=
nullptr);
4496 m_value.object->clear();
4530 if (not(is_null() or is_array()))
4532 throw std::domain_error(
"cannot use push_back() with " + type_name());
4538 m_type = value_t::array;
4539 m_value = value_t::array;
4543 assert(m_value.array !=
nullptr);
4544 m_value.array->push_back(std::move(val));
4546 val.m_type = value_t::null;
4555 push_back(std::move(val));
4566 if (not(is_null() or is_array()))
4568 throw std::domain_error(
"cannot use push_back() with " + type_name());
4574 m_type = value_t::array;
4575 m_value = value_t::array;
4579 assert(m_value.array !=
nullptr);
4580 m_value.array->push_back(val);
4616 if (not(is_null() or is_object()))
4618 throw std::domain_error(
"cannot use push_back() with " + type_name());
4624 m_type = value_t::object;
4625 m_value = value_t::object;
4629 assert(m_value.object !=
nullptr);
4630 m_value.object->insert(val);
4640 return operator[](val.first);
4671 if (pos.m_object !=
this)
4673 throw std::domain_error(
"iterator does not fit current value");
4678 assert(m_value.array !=
nullptr);
4679 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4684 throw std::domain_error(
"cannot use insert() with " + type_name());
4694 return insert(pos, val);
4727 if (pos.m_object !=
this)
4729 throw std::domain_error(
"iterator does not fit current value");
4734 assert(m_value.array !=
nullptr);
4735 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4740 throw std::domain_error(
"cannot use insert() with " + type_name());
4779 throw std::domain_error(
"cannot use insert() with " + type_name());
4783 if (pos.m_object !=
this)
4785 throw std::domain_error(
"iterator does not fit current value");
4788 if (first.m_object != last.m_object)
4790 throw std::domain_error(
"iterators do not fit");
4793 if (first.m_object ==
this or last.m_object ==
this)
4795 throw std::domain_error(
"passed iterators may not belong to container");
4800 assert(m_value.array !=
nullptr);
4801 result.m_it.array_iterator = m_value.array->insert(
4802 pos.m_it.array_iterator,
4803 first.m_it.array_iterator,
4804 last.m_it.array_iterator);
4837 throw std::domain_error(
"cannot use insert() with " + type_name());
4841 if (pos.m_object !=
this)
4843 throw std::domain_error(
"iterator does not fit current value");
4848 assert(m_value.array !=
nullptr);
4849 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4871 std::is_nothrow_move_constructible<value_t>::value and
4872 std::is_nothrow_move_assignable<value_t>::value and
4873 std::is_nothrow_move_constructible<json_value>::value and
4874 std::is_nothrow_move_assignable<json_value>::value
4877 std::swap(m_type, other.m_type);
4878 std::swap(m_value, other.m_value);
4906 assert(m_value.array !=
nullptr);
4907 std::swap(*(m_value.array), other);
4911 throw std::domain_error(
"cannot use swap() with " + type_name());
4940 assert(m_value.object !=
nullptr);
4941 std::swap(*(m_value.object), other);
4945 throw std::domain_error(
"cannot use swap() with " + type_name());
4974 assert(m_value.string !=
nullptr);
4975 std::swap(*(m_value.string), other);
4979 throw std::domain_error(
"cannot use swap() with " + type_name());
5005 static constexpr std::array<uint8_t, 8> order = {{
5018 if (lhs == value_t::discarded or rhs == value_t::discarded)
5023 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5052 const auto lhs_type = lhs.type();
5053 const auto rhs_type = rhs.type();
5055 if (lhs_type == rhs_type)
5059 case value_t::array:
5061 assert(lhs.m_value.array !=
nullptr);
5062 assert(rhs.m_value.array !=
nullptr);
5063 return *lhs.m_value.array == *rhs.m_value.array;
5065 case value_t::object:
5067 assert(lhs.m_value.object !=
nullptr);
5068 assert(rhs.m_value.object !=
nullptr);
5069 return *lhs.m_value.object == *rhs.m_value.object;
5075 case value_t::string:
5077 assert(lhs.m_value.string !=
nullptr);
5078 assert(rhs.m_value.string !=
nullptr);
5079 return *lhs.m_value.string == *rhs.m_value.string;
5081 case value_t::boolean:
5083 return lhs.m_value.boolean == rhs.m_value.boolean;
5085 case value_t::number_integer:
5087 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5089 case value_t::number_unsigned:
5091 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5093 case value_t::number_float:
5095 return lhs.m_value.number_float == rhs.m_value.number_float;
5103 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5105 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5107 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5109 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5111 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5113 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5115 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5117 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5119 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5121 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5123 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5125 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5181 return not (lhs == rhs);
5213 return not v.is_null();
5242 const auto lhs_type = lhs.type();
5243 const auto rhs_type = rhs.type();
5245 if (lhs_type == rhs_type)
5249 case value_t::array:
5251 assert(lhs.m_value.array !=
nullptr);
5252 assert(rhs.m_value.array !=
nullptr);
5253 return *lhs.m_value.array < *rhs.m_value.array;
5255 case value_t::object:
5257 assert(lhs.m_value.object !=
nullptr);
5258 assert(rhs.m_value.object !=
nullptr);
5259 return *lhs.m_value.object < *rhs.m_value.object;
5265 case value_t::string:
5267 assert(lhs.m_value.string !=
nullptr);
5268 assert(rhs.m_value.string !=
nullptr);
5269 return *lhs.m_value.string < *rhs.m_value.string;
5271 case value_t::boolean:
5273 return lhs.m_value.boolean < rhs.m_value.boolean;
5275 case value_t::number_integer:
5277 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5279 case value_t::number_unsigned:
5281 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5283 case value_t::number_float:
5285 return lhs.m_value.number_float < rhs.m_value.number_float;
5293 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5295 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5297 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5299 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5301 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5303 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5305 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5307 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5309 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5311 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5313 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5315 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5321 return operator<(lhs_type, rhs_type);
5343 return not (rhs < lhs);
5365 return not (lhs <= rhs);
5387 return not (lhs < rhs);
5422 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5425 const bool pretty_print = (o.width() > 0);
5426 const auto indentation = (pretty_print ? o.width() : 0);
5432 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5440 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5481 return parser(s, cb).
parse();
5510 return parser(i, cb).
parse();
5518 return parser(i, cb).
parse();
5546 j = parser(i).
parse();
5556 j = parser(i).
parse();
5575 case value_t::object:
5577 case value_t::array:
5579 case value_t::string:
5581 case value_t::boolean:
5583 case value_t::discarded:
5598 static std::size_t extra_space(
const string_t& s) noexcept
5600 std::size_t result = 0;
5602 for (
const auto& c : s)
5621 if (c >= 0x00 and c <= 0x1f)
5649 const auto space = extra_space(s);
5656 string_t result(s.size() + space,
'\\');
5657 std::size_t pos = 0;
5659 for (
const auto& c : s)
5666 result[pos + 1] =
'"';
5682 result[pos + 1] =
'b';
5690 result[pos + 1] =
'f';
5698 result[pos + 1] =
'n';
5706 result[pos + 1] =
'r';
5714 result[pos + 1] =
't';
5721 if (c >= 0x00 and c <= 0x1f)
5724 auto hexify = [](
const char v) ->
char 5726 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5731 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5769 void dump(std::ostream& o,
5770 const bool pretty_print,
5771 const unsigned int indent_step,
5772 const unsigned int current_indent = 0)
const 5775 unsigned int new_indent = current_indent;
5779 case value_t::object:
5781 assert(m_value.object !=
nullptr);
5783 if (m_value.object->empty())
5794 new_indent += indent_step;
5798 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5800 if (i != m_value.object->cbegin())
5802 o << (pretty_print ?
",\n" :
",");
5804 o <<
string_t(new_indent,
' ') <<
"\"" 5805 << escape_string(i->first) <<
"\":" 5806 << (pretty_print ?
" " :
"");
5807 i->second.dump(o, pretty_print, indent_step, new_indent);
5813 new_indent -= indent_step;
5817 o <<
string_t(new_indent,
' ') +
"}";
5821 case value_t::array:
5823 assert(m_value.array !=
nullptr);
5825 if (m_value.array->empty())
5836 new_indent += indent_step;
5840 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5842 if (i != m_value.array->cbegin())
5844 o << (pretty_print ?
",\n" :
",");
5847 i->dump(o, pretty_print, indent_step, new_indent);
5853 new_indent -= indent_step;
5857 o <<
string_t(new_indent,
' ') <<
"]";
5861 case value_t::string:
5863 assert(m_value.string !=
nullptr);
5864 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5868 case value_t::boolean:
5870 o << (m_value.boolean ?
"true" :
"false");
5874 case value_t::number_integer:
5876 o << m_value.number_integer;
5880 case value_t::number_unsigned:
5882 o << m_value.number_unsigned;
5886 case value_t::number_float:
5894 if (std::fmod(m_value.number_float, 1) == 0)
5896 o << std::fixed << std::setprecision(1);
5901 o.unsetf(std::ios_base::floatfield);
5902 o << std::setprecision(std::numeric_limits<double>::digits10);
5904 o << m_value.number_float;
5908 case value_t::discarded:
5928 value_t m_type = value_t::null;
5931 json_value m_value = {};
5948 class primitive_iterator_t
5964 bool is_begin()
const 5966 return (m_it == begin_value);
5972 return (m_it == end_value);
5992 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6002 struct internal_iterator
6005 typename object_t::iterator object_iterator;
6007 typename array_t::iterator array_iterator;
6009 primitive_iterator_t primitive_iterator;
6013 : object_iterator(), array_iterator(), primitive_iterator()
6018 template<
typename IteratorType>
6019 class iteration_proxy
6023 class iteration_proxy_internal
6027 IteratorType anchor;
6029 size_t array_index = 0;
6032 iteration_proxy_internal(IteratorType it)
6037 iteration_proxy_internal& operator*()
6043 iteration_proxy_internal& operator++()
6052 bool operator!= (
const iteration_proxy_internal& o)
const 6054 return anchor != o.anchor;
6060 assert(anchor.m_object !=
nullptr);
6062 switch (anchor.m_object->type())
6065 case value_t::array:
6067 return std::to_string(array_index);
6071 case value_t::object:
6073 return anchor.key();
6085 typename IteratorType::reference value()
const 6087 return anchor.value();
6092 typename IteratorType::reference container;
6096 iteration_proxy(
typename IteratorType::reference cont)
6101 iteration_proxy_internal begin()
6103 return iteration_proxy_internal(container.begin());
6107 iteration_proxy_internal end()
6109 return iteration_proxy_internal(container.end());
6127 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6130 friend class basic_json;
6150 assert(m_object !=
nullptr);
6152 switch (m_object->m_type)
6156 m_it.object_iterator =
typename object_t::iterator();
6162 m_it.array_iterator =
typename array_t::iterator();
6168 m_it.primitive_iterator = primitive_iterator_t();
6177 assert(m_object !=
nullptr);
6179 switch (m_object->m_type)
6183 m_it.object_iterator = other.m_it.object_iterator;
6189 m_it.array_iterator = other.m_it.array_iterator;
6195 m_it.primitive_iterator = other.m_it.primitive_iterator;
6203 : m_object(other.m_object), m_it(other.m_it)
6208 std::is_nothrow_move_constructible<pointer>::value and
6209 std::is_nothrow_move_assignable<pointer>::value and
6210 std::is_nothrow_move_constructible<internal_iterator>::value and
6211 std::is_nothrow_move_assignable<internal_iterator>::value
6214 std::swap(m_object, other.m_object);
6215 std::swap(m_it, other.m_it);
6223 assert(m_object !=
nullptr);
6225 switch (m_object->m_type)
6229 assert(m_object->m_value.object !=
nullptr);
6230 m_it.object_iterator = m_object->m_value.object->begin();
6236 assert(m_object->m_value.array !=
nullptr);
6237 m_it.array_iterator = m_object->m_value.array->begin();
6244 m_it.primitive_iterator.set_end();
6250 m_it.primitive_iterator.set_begin();
6259 assert(m_object !=
nullptr);
6261 switch (m_object->m_type)
6265 assert(m_object->m_value.object !=
nullptr);
6266 m_it.object_iterator = m_object->m_value.object->end();
6272 assert(m_object->m_value.array !=
nullptr);
6273 m_it.array_iterator = m_object->m_value.array->end();
6279 m_it.primitive_iterator.set_end();
6289 assert(m_object !=
nullptr);
6291 switch (m_object->m_type)
6295 assert(m_object->m_value.object);
6296 assert(m_it.object_iterator != m_object->m_value.object->end());
6297 return m_it.object_iterator->second;
6302 assert(m_object->m_value.array);
6303 assert(m_it.array_iterator != m_object->m_value.array->end());
6304 return *m_it.array_iterator;
6309 throw std::out_of_range(
"cannot get value");
6314 if (m_it.primitive_iterator.is_begin())
6320 throw std::out_of_range(
"cannot get value");
6329 assert(m_object !=
nullptr);
6331 switch (m_object->m_type)
6335 assert(m_object->m_value.object);
6336 assert(m_it.object_iterator != m_object->m_value.object->end());
6337 return &(m_it.object_iterator->second);
6342 assert(m_object->m_value.array);
6343 assert(m_it.array_iterator != m_object->m_value.array->end());
6344 return &*m_it.array_iterator;
6349 if (m_it.primitive_iterator.is_begin())
6355 throw std::out_of_range(
"cannot get value");
6364 auto result = *
this;
6372 assert(m_object !=
nullptr);
6374 switch (m_object->m_type)
6378 ++m_it.object_iterator;
6384 ++m_it.array_iterator;
6390 ++m_it.primitive_iterator;
6401 auto result = *
this;
6409 assert(m_object !=
nullptr);
6411 switch (m_object->m_type)
6415 --m_it.object_iterator;
6421 --m_it.array_iterator;
6427 --m_it.primitive_iterator;
6439 if (m_object != other.m_object)
6441 throw std::domain_error(
"cannot compare iterators of different containers");
6444 assert(m_object !=
nullptr);
6446 switch (m_object->m_type)
6450 return (m_it.object_iterator == other.m_it.object_iterator);
6455 return (m_it.array_iterator == other.m_it.array_iterator);
6460 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6468 return not operator==(other);
6475 if (m_object != other.m_object)
6477 throw std::domain_error(
"cannot compare iterators of different containers");
6480 assert(m_object !=
nullptr);
6482 switch (m_object->m_type)
6486 throw std::domain_error(
"cannot compare order of object iterators");
6491 return (m_it.array_iterator < other.m_it.array_iterator);
6496 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6504 return not other.operator < (*this);
6510 return not operator<=(other);
6516 return not operator<(other);
6522 assert(m_object !=
nullptr);
6524 switch (m_object->m_type)
6528 throw std::domain_error(
"cannot use offsets with object iterators");
6533 m_it.array_iterator += i;
6539 m_it.primitive_iterator += i;
6550 return operator+=(-i);
6556 auto result = *
this;
6564 auto result = *
this;
6572 assert(m_object !=
nullptr);
6574 switch (m_object->m_type)
6578 throw std::domain_error(
"cannot use offsets with object iterators");
6583 return m_it.array_iterator - other.m_it.array_iterator;
6588 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6596 assert(m_object !=
nullptr);
6598 switch (m_object->m_type)
6602 throw std::domain_error(
"cannot use operator[] for object iterators");
6607 return *(m_it.array_iterator + n);
6612 throw std::out_of_range(
"cannot get value");
6617 if (m_it.primitive_iterator == -n)
6623 throw std::out_of_range(
"cannot get value");
6630 typename object_t::key_type
key()
const 6632 assert(m_object !=
nullptr);
6634 if (m_object->is_object())
6636 return m_it.object_iterator->first;
6640 throw std::domain_error(
"cannot use key() for non-object iterators");
6654 internal_iterator m_it = internal_iterator();
6691 std::is_nothrow_move_constructible<pointer>::value and
6692 std::is_nothrow_move_assignable<pointer>::value and
6693 std::is_nothrow_move_constructible<internal_iterator>::value and
6694 std::is_nothrow_move_assignable<internal_iterator>::value
6697 base_iterator::operator=(other);
6704 return const_cast<reference>(base_iterator::operator*());
6710 return const_cast<pointer>(base_iterator::operator->());
6717 base_iterator::operator++();
6724 base_iterator::operator++();
6732 base_iterator::operator--();
6739 base_iterator::operator--();
6746 base_iterator::operator+=(i);
6753 base_iterator::operator-=(i);
6760 auto result = *
this;
6768 auto result = *
this;
6775 return base_iterator::operator-(other);
6781 return const_cast<reference>(base_iterator::operator[](n));
6787 return const_cast<reference>(base_iterator::value());
6808 template<
typename Base>
6830 return base_iterator::operator++(1);
6836 base_iterator::operator++();
6843 return base_iterator::operator--(1);
6849 base_iterator::operator--();
6856 base_iterator::operator+=(i);
6863 auto result = *
this;
6871 auto result = *
this;
6879 return this->base() - other.base();
6885 return *(this->operator+(n));
6889 typename object_t::key_type
key()
const 6891 auto it = --this->base();
6898 auto it = --this->base();
6899 return it.operator * ();
6920 enum class token_type
6939 using lexer_char_t =
unsigned char;
6942 explicit lexer(
const string_t& s) noexcept
6943 : m_stream(
nullptr), m_buffer(s)
6945 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6946 assert(m_content !=
nullptr);
6947 m_start = m_cursor = m_content;
6948 m_limit = m_content + s.size();
6952 explicit lexer(std::istream* s) noexcept
6953 : m_stream(s), m_buffer()
6955 assert(m_stream !=
nullptr);
6956 getline(*m_stream, m_buffer);
6957 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6958 assert(m_content !=
nullptr);
6959 m_start = m_cursor = m_content;
6960 m_limit = m_content + m_buffer.size();
6967 lexer(
const lexer&) =
delete;
6968 lexer operator=(
const lexer&) =
delete;
6985 static string_t to_unicode(
const std::size_t codepoint1,
6986 const std::size_t codepoint2 = 0)
6991 std::size_t codepoint = codepoint1;
6994 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6997 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7011 throw std::invalid_argument(
"missing or wrong low surrogate");
7015 if (codepoint < 0x80)
7018 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7020 else if (codepoint <= 0x7ff)
7023 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7024 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7026 else if (codepoint <= 0xffff)
7029 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7030 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7031 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7033 else if (codepoint <= 0x10ffff)
7036 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7037 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7038 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7039 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7043 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7050 static std::string token_type_name(token_type t)
7054 case token_type::uninitialized:
7055 return "<uninitialized>";
7056 case token_type::literal_true:
7057 return "true literal";
7058 case token_type::literal_false:
7059 return "false literal";
7060 case token_type::literal_null:
7061 return "null literal";
7062 case token_type::value_string:
7063 return "string literal";
7064 case token_type::value_number:
7065 return "number literal";
7066 case token_type::begin_array:
7068 case token_type::begin_object:
7070 case token_type::end_array:
7072 case token_type::end_object:
7074 case token_type::name_separator:
7076 case token_type::value_separator:
7078 case token_type::parse_error:
7079 return "<parse error>";
7080 case token_type::end_of_input:
7081 return "end of input";
7085 return "unknown token";
7100 token_type scan() noexcept
7107 assert(m_start !=
nullptr);
7112 unsigned int yyaccept = 0;
7113 static const unsigned char yybm[] =
7115 0, 0, 0, 0, 0, 0, 0, 0,
7116 0, 32, 32, 0, 0, 32, 0, 0,
7117 64, 64, 64, 64, 64, 64, 64, 64,
7118 64, 64, 64, 64, 64, 64, 64, 64,
7119 96, 64, 0, 64, 64, 64, 64, 64,
7120 64, 64, 64, 64, 64, 64, 64, 64,
7121 192, 192, 192, 192, 192, 192, 192, 192,
7122 192, 192, 64, 64, 64, 64, 64, 64,
7123 64, 64, 64, 64, 64, 64, 64, 64,
7124 64, 64, 64, 64, 64, 64, 64, 64,
7125 64, 64, 64, 64, 64, 64, 64, 64,
7126 64, 64, 64, 64, 0, 64, 64, 64,
7127 64, 64, 64, 64, 64, 64, 64, 64,
7128 64, 64, 64, 64, 64, 64, 64, 64,
7129 64, 64, 64, 64, 64, 64, 64, 64,
7130 64, 64, 64, 64, 64, 64, 64, 64,
7131 64, 64, 64, 64, 64, 64, 64, 64,
7132 64, 64, 64, 64, 64, 64, 64, 64,
7133 64, 64, 64, 64, 64, 64, 64, 64,
7134 64, 64, 64, 64, 64, 64, 64, 64,
7135 64, 64, 64, 64, 64, 64, 64, 64,
7136 64, 64, 64, 64, 64, 64, 64, 64,
7137 64, 64, 64, 64, 64, 64, 64, 64,
7138 64, 64, 64, 64, 64, 64, 64, 64,
7139 64, 64, 64, 64, 64, 64, 64, 64,
7140 64, 64, 64, 64, 64, 64, 64, 64,
7141 64, 64, 64, 64, 64, 64, 64, 64,
7142 64, 64, 64, 64, 64, 64, 64, 64,
7143 64, 64, 64, 64, 64, 64, 64, 64,
7144 64, 64, 64, 64, 64, 64, 64, 64,
7145 64, 64, 64, 64, 64, 64, 64, 64,
7146 64, 64, 64, 64, 64, 64, 64, 64,
7148 if ((m_limit - m_cursor) < 5)
7161 goto basic_json_parser_28;
7165 goto basic_json_parser_30;
7169 goto basic_json_parser_4;
7176 goto basic_json_parser_2;
7180 goto basic_json_parser_30;
7190 goto basic_json_parser_27;
7194 goto basic_json_parser_30;
7196 goto basic_json_parser_16;
7204 goto basic_json_parser_23;
7206 goto basic_json_parser_30;
7212 goto basic_json_parser_24;
7216 goto basic_json_parser_26;
7218 goto basic_json_parser_18;
7231 goto basic_json_parser_8;
7235 goto basic_json_parser_30;
7237 goto basic_json_parser_10;
7243 goto basic_json_parser_22;
7247 goto basic_json_parser_30;
7249 goto basic_json_parser_20;
7258 goto basic_json_parser_21;
7262 goto basic_json_parser_30;
7264 goto basic_json_parser_12;
7272 goto basic_json_parser_30;
7274 goto basic_json_parser_14;
7280 goto basic_json_parser_6;
7282 goto basic_json_parser_30;
7287 basic_json_parser_2:
7290 goto basic_json_parser_5;
7291 basic_json_parser_3:
7295 basic_json_parser_4:
7297 if (m_limit <= m_cursor)
7302 basic_json_parser_5:
7303 if (yybm[0 + yych] & 32)
7305 goto basic_json_parser_4;
7307 goto basic_json_parser_3;
7308 basic_json_parser_6:
7310 yych = *(m_marker = ++m_cursor);
7313 goto basic_json_parser_64;
7315 basic_json_parser_7:
7317 return token_type::parse_error;
7319 basic_json_parser_8:
7322 return token_type::begin_array;
7324 basic_json_parser_10:
7327 return token_type::end_array;
7329 basic_json_parser_12:
7332 return token_type::begin_object;
7334 basic_json_parser_14:
7337 return token_type::end_object;
7339 basic_json_parser_16:
7342 return token_type::value_separator;
7344 basic_json_parser_18:
7347 return token_type::name_separator;
7349 basic_json_parser_20:
7351 yych = *(m_marker = ++m_cursor);
7354 goto basic_json_parser_60;
7356 goto basic_json_parser_7;
7357 basic_json_parser_21:
7359 yych = *(m_marker = ++m_cursor);
7362 goto basic_json_parser_56;
7364 goto basic_json_parser_7;
7365 basic_json_parser_22:
7367 yych = *(m_marker = ++m_cursor);
7370 goto basic_json_parser_51;
7372 goto basic_json_parser_7;
7373 basic_json_parser_23:
7377 goto basic_json_parser_7;
7381 goto basic_json_parser_50;
7385 goto basic_json_parser_41;
7387 goto basic_json_parser_7;
7388 basic_json_parser_24:
7390 yych = *(m_marker = ++m_cursor);
7395 goto basic_json_parser_43;
7402 goto basic_json_parser_44;
7406 goto basic_json_parser_44;
7409 basic_json_parser_25:
7411 return token_type::value_number;
7413 basic_json_parser_26:
7415 yych = *(m_marker = ++m_cursor);
7416 goto basic_json_parser_42;
7417 basic_json_parser_27:
7419 yych = *(m_marker = ++m_cursor);
7422 goto basic_json_parser_7;
7424 goto basic_json_parser_32;
7425 basic_json_parser_28:
7428 return token_type::end_of_input;
7430 basic_json_parser_30:
7432 goto basic_json_parser_7;
7433 basic_json_parser_31:
7435 if (m_limit <= m_cursor)
7440 basic_json_parser_32:
7441 if (yybm[0 + yych] & 64)
7443 goto basic_json_parser_31;
7447 goto basic_json_parser_33;
7451 goto basic_json_parser_35;
7453 goto basic_json_parser_34;
7454 basic_json_parser_33:
7455 m_cursor = m_marker;
7458 goto basic_json_parser_7;
7462 goto basic_json_parser_25;
7464 basic_json_parser_34:
7466 if (m_limit <= m_cursor)
7477 goto basic_json_parser_31;
7481 goto basic_json_parser_33;
7483 goto basic_json_parser_31;
7491 goto basic_json_parser_33;
7493 goto basic_json_parser_31;
7499 goto basic_json_parser_31;
7501 goto basic_json_parser_33;
7511 goto basic_json_parser_31;
7515 goto basic_json_parser_31;
7517 goto basic_json_parser_33;
7525 goto basic_json_parser_31;
7527 goto basic_json_parser_33;
7533 goto basic_json_parser_31;
7537 goto basic_json_parser_37;
7539 goto basic_json_parser_33;
7543 basic_json_parser_35:
7546 return token_type::value_string;
7548 basic_json_parser_37:
7550 if (m_limit <= m_cursor)
7559 goto basic_json_parser_33;
7563 goto basic_json_parser_33;
7570 goto basic_json_parser_38;
7574 goto basic_json_parser_33;
7578 goto basic_json_parser_33;
7581 basic_json_parser_38:
7583 if (m_limit <= m_cursor)
7592 goto basic_json_parser_33;
7596 goto basic_json_parser_33;
7603 goto basic_json_parser_39;
7607 goto basic_json_parser_33;
7611 goto basic_json_parser_33;
7614 basic_json_parser_39:
7616 if (m_limit <= m_cursor)
7625 goto basic_json_parser_33;
7629 goto basic_json_parser_33;
7636 goto basic_json_parser_40;
7640 goto basic_json_parser_33;
7644 goto basic_json_parser_33;
7647 basic_json_parser_40:
7649 if (m_limit <= m_cursor)
7658 goto basic_json_parser_33;
7662 goto basic_json_parser_31;
7664 goto basic_json_parser_33;
7670 goto basic_json_parser_31;
7674 goto basic_json_parser_33;
7678 goto basic_json_parser_31;
7680 goto basic_json_parser_33;
7682 basic_json_parser_41:
7684 m_marker = ++m_cursor;
7685 if ((m_limit - m_cursor) < 3)
7690 basic_json_parser_42:
7691 if (yybm[0 + yych] & 128)
7693 goto basic_json_parser_41;
7699 goto basic_json_parser_25;
7706 goto basic_json_parser_44;
7710 goto basic_json_parser_44;
7712 goto basic_json_parser_25;
7714 basic_json_parser_43:
7718 goto basic_json_parser_33;
7722 goto basic_json_parser_48;
7724 goto basic_json_parser_33;
7725 basic_json_parser_44:
7731 goto basic_json_parser_33;
7738 goto basic_json_parser_45;
7742 goto basic_json_parser_33;
7746 goto basic_json_parser_46;
7748 goto basic_json_parser_33;
7750 basic_json_parser_45:
7754 goto basic_json_parser_33;
7758 goto basic_json_parser_33;
7760 basic_json_parser_46:
7762 if (m_limit <= m_cursor)
7769 goto basic_json_parser_25;
7773 goto basic_json_parser_46;
7775 goto basic_json_parser_25;
7776 basic_json_parser_48:
7778 m_marker = ++m_cursor;
7779 if ((m_limit - m_cursor) < 3)
7788 goto basic_json_parser_25;
7792 goto basic_json_parser_48;
7794 goto basic_json_parser_25;
7800 goto basic_json_parser_44;
7804 goto basic_json_parser_44;
7806 goto basic_json_parser_25;
7808 basic_json_parser_50:
7810 yych = *(m_marker = ++m_cursor);
7815 goto basic_json_parser_43;
7817 goto basic_json_parser_25;
7823 goto basic_json_parser_44;
7827 goto basic_json_parser_44;
7829 goto basic_json_parser_25;
7831 basic_json_parser_51:
7835 goto basic_json_parser_33;
7840 goto basic_json_parser_33;
7845 goto basic_json_parser_33;
7849 return token_type::literal_false;
7851 basic_json_parser_56:
7855 goto basic_json_parser_33;
7860 goto basic_json_parser_33;
7864 return token_type::literal_true;
7866 basic_json_parser_60:
7870 goto basic_json_parser_33;
7875 goto basic_json_parser_33;
7879 return token_type::literal_null;
7881 basic_json_parser_64:
7885 goto basic_json_parser_33;
7897 void yyfill() noexcept
7899 if (m_stream ==
nullptr or not * m_stream)
7904 const ssize_t offset_start = m_start - m_content;
7905 const ssize_t offset_marker = m_marker - m_start;
7906 const ssize_t offset_cursor = m_cursor - m_start;
7908 m_buffer.erase(0, static_cast<size_t>(offset_start));
7910 assert(m_stream !=
nullptr);
7911 std::getline(*m_stream, line);
7912 m_buffer +=
"\n" + line;
7914 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7915 assert(m_content !=
nullptr);
7916 m_start = m_content;
7917 m_marker = m_start + offset_marker;
7918 m_cursor = m_start + offset_cursor;
7919 m_limit = m_start + m_buffer.size() - 1;
7923 string_t get_token()
const noexcept
7925 assert(m_start !=
nullptr);
7926 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7927 static_cast<size_t>(m_cursor - m_start));
7954 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7957 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8013 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8014 4).c_str(),
nullptr, 16);
8017 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8020 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8022 throw std::invalid_argument(
"missing low surrogate");
8026 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8027 (i + 7), 4).c_str(),
nullptr, 16);
8028 result += to_unicode(codepoint, codepoint2);
8035 result += to_unicode(codepoint);
8047 result.append(1, static_cast<typename string_t::value_type>(*i));
8074 long double str_to_float_t(
long double* ,
char** endptr)
const 8076 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8093 double str_to_float_t(
double* ,
char** endptr)
const 8095 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8112 float str_to_float_t(
float* ,
char** endptr)
const 8114 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8129 template <
typename T_A,
typename T_B>
8130 bool attempt_cast(T_A source, T_B& dest)
const 8132 dest =
static_cast<T_B
>(source);
8133 return (source == static_cast<T_A>(dest));
8174 void get_number(basic_json& result)
const 8176 typename string_t::value_type* endptr;
8177 assert(m_start !=
nullptr);
8182 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8186 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8187 10), result.m_value.number_unsigned))
8189 result.m_type = value_t::number_unsigned;
8194 result.m_type = value_t::number_float;
8201 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8202 10), result.m_value.number_unsigned))
8204 result.m_type = value_t::number_integer;
8209 result.m_type = value_t::number_float;
8215 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8217 result.m_type = value_t::number_float;
8220 if (result.m_type == value_t::number_float)
8227 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8230 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8232 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8239 std::istream* m_stream =
nullptr;
8243 const lexer_char_t* m_content =
nullptr;
8245 const lexer_char_t* m_start =
nullptr;
8247 const lexer_char_t* m_marker =
nullptr;
8249 const lexer_char_t* m_cursor =
nullptr;
8251 const lexer_char_t* m_limit =
nullptr;
8264 : callback(cb), m_lexer(s)
8272 : callback(cb), m_lexer(&_is)
8281 basic_json result = parse_internal(
true);
8283 expect(lexer::token_type::end_of_input);
8292 basic_json parse_internal(
bool keep)
8294 auto result = basic_json(value_t::discarded);
8298 case lexer::token_type::begin_object:
8300 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8303 result.m_type = value_t::object;
8304 result.m_value = json_value(value_t::object);
8311 if (last_token == lexer::token_type::end_object)
8314 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8316 result = basic_json(value_t::discarded);
8322 unexpect(lexer::token_type::value_separator);
8328 if (last_token == lexer::token_type::value_separator)
8334 expect(lexer::token_type::value_string);
8335 const auto key = m_lexer.get_string();
8337 bool keep_tag =
false;
8343 keep_tag = callback(depth, parse_event_t::key, k);
8353 expect(lexer::token_type::name_separator);
8357 auto value = parse_internal(keep);
8358 if (keep and keep_tag and not value.is_discarded())
8360 result[key] = std::move(value);
8363 while (last_token == lexer::token_type::value_separator);
8366 expect(lexer::token_type::end_object);
8368 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8370 result = basic_json(value_t::discarded);
8376 case lexer::token_type::begin_array:
8378 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8381 result.m_type = value_t::array;
8382 result.m_value = json_value(value_t::array);
8389 if (last_token == lexer::token_type::end_array)
8392 if (callback and not callback(--depth, parse_event_t::array_end, result))
8394 result = basic_json(value_t::discarded);
8400 unexpect(lexer::token_type::value_separator);
8406 if (last_token == lexer::token_type::value_separator)
8412 auto value = parse_internal(keep);
8413 if (keep and not value.is_discarded())
8415 result.push_back(std::move(value));
8418 while (last_token == lexer::token_type::value_separator);
8421 expect(lexer::token_type::end_array);
8423 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8425 result = basic_json(value_t::discarded);
8431 case lexer::token_type::literal_null:
8434 result.m_type = value_t::null;
8438 case lexer::token_type::value_string:
8440 const auto s = m_lexer.get_string();
8442 result = basic_json(s);
8446 case lexer::token_type::literal_true:
8449 result.m_type = value_t::boolean;
8450 result.m_value =
true;
8454 case lexer::token_type::literal_false:
8457 result.m_type = value_t::boolean;
8458 result.m_value =
false;
8462 case lexer::token_type::value_number:
8464 m_lexer.get_number(result);
8472 unexpect(last_token);
8476 if (keep and callback and not callback(depth, parse_event_t::value, result))
8478 result = basic_json(value_t::discarded);
8484 typename lexer::token_type get_token()
8486 last_token = m_lexer.scan();
8490 void expect(
typename lexer::token_type t)
const 8492 if (t != last_token)
8494 std::string error_msg =
"parse error - unexpected ";
8495 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8496 lexer::token_type_name(last_token));
8497 error_msg +=
"; expected " + lexer::token_type_name(t);
8498 throw std::invalid_argument(error_msg);
8502 void unexpect(
typename lexer::token_type t)
const 8504 if (t == last_token)
8506 std::string error_msg =
"parse error - unexpected ";
8507 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8508 lexer::token_type_name(last_token));
8509 throw std::invalid_argument(error_msg);
8519 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8557 is_nothrow_move_constructible<nlohmann::json>::value and
8558 is_nothrow_move_assignable<nlohmann::json>::value
8576 const auto& h = hash<nlohmann::json::string_t>();
8594 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8600 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8601 #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
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.