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)
1044 template <
class CompatibleObjectType,
typename 1046 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1047 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
1054 m_value.object = create<object_t>(begin(val), end(val));
1077 : m_type(
value_t::array), m_value(val)
1106 template <
class CompatibleArrayType,
typename 1108 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1109 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1110 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1111 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1112 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1113 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1114 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1121 m_value.array = create<array_t>(begin(val), end(val));
1146 : m_type(
value_t::string), m_value(val)
1196 template <
class CompatibleStringType,
typename 1198 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1219 : m_type(
value_t::boolean), m_value(val)
1245 template<
typename T,
1246 typename std::enable_if<
1247 not (std::is_same<T, int>::value)
1248 and std::is_same<T, number_integer_t>::value
1252 : m_type(
value_t::number_integer), m_value(val)
1281 : m_type(
value_t::number_integer),
1310 template<
typename CompatibleNumberIntegerType,
typename 1312 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1313 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1314 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1315 CompatibleNumberIntegerType>::type
1318 : m_type(value_t::number_integer),
1319 m_value(static_cast<number_integer_t>(val))
1339 template<
typename T,
1340 typename std::enable_if<
1341 not (std::is_same<T, int>::value)
1342 and std::is_same<T, number_unsigned_t>::value
1346 : m_type(
value_t::number_unsigned), m_value(val)
1369 template <
typename CompatibleNumberUnsignedType,
typename 1371 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1372 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1373 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1374 CompatibleNumberUnsignedType >::type
1377 : m_type(value_t::number_unsigned),
1378 m_value(static_cast<number_unsigned_t>(val))
1406 : m_type(
value_t::number_float), m_value(val)
1409 if (not std::isfinite(val))
1411 m_type = value_t::null;
1412 m_value = json_value();
1446 template<
typename CompatibleNumberFloatType,
typename =
typename 1448 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1449 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1525 bool type_deduction =
true,
1526 value_t manual_type = value_t::array)
1529 bool is_an_object =
true;
1533 for (
const auto& element : init)
1535 if (not element.is_array() or element.size() != 2
1536 or not element[0].is_string())
1540 is_an_object =
false;
1546 if (not type_deduction)
1549 if (manual_type == value_t::array)
1551 is_an_object =
false;
1555 if (manual_type == value_t::object and not is_an_object)
1557 throw std::domain_error(
"cannot create object from initializer list");
1564 m_type = value_t::object;
1565 m_value = value_t::object;
1567 assert(m_value.object !=
nullptr);
1569 for (
auto& element : init)
1571 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1577 m_type = value_t::array;
1578 m_value.array = create<array_t>(std::move(init));
1616 static basic_json
array(std::initializer_list<basic_json> init =
1617 std::initializer_list<basic_json>())
1619 return basic_json(init,
false, value_t::array);
1656 static basic_json
object(std::initializer_list<basic_json> init =
1657 std::initializer_list<basic_json>())
1659 return basic_json(init,
false, value_t::object);
1683 m_value.array = create<array_t>(cnt, val);
1720 template <
class InputIT,
typename 1722 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1723 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1726 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1729 if (first.m_object != last.m_object)
1731 throw std::domain_error(
"iterators are not compatible");
1737 case value_t::boolean:
1738 case value_t::number_float:
1739 case value_t::number_integer:
1740 case value_t::number_unsigned:
1741 case value_t::string:
1743 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1745 throw std::out_of_range(
"iterators out of range");
1758 case value_t::number_integer:
1760 assert(first.m_object !=
nullptr);
1761 m_value.number_integer = first.m_object->m_value.number_integer;
1765 case value_t::number_unsigned:
1767 assert(first.m_object !=
nullptr);
1768 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1772 case value_t::number_float:
1774 assert(first.m_object !=
nullptr);
1775 m_value.number_float = first.m_object->m_value.number_float;
1779 case value_t::boolean:
1781 assert(first.m_object !=
nullptr);
1782 m_value.boolean = first.m_object->m_value.boolean;
1786 case value_t::string:
1788 assert(first.m_object !=
nullptr);
1789 m_value = *first.m_object->m_value.string;
1793 case value_t::object:
1795 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1799 case value_t::array:
1801 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1807 assert(first.m_object !=
nullptr);
1808 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1835 *
this = parser(i, cb).parse();
1865 : m_type(other.m_type)
1869 case value_t::object:
1871 assert(other.m_value.object !=
nullptr);
1872 m_value = *other.m_value.object;
1876 case value_t::array:
1878 assert(other.m_value.array !=
nullptr);
1879 m_value = *other.m_value.array;
1883 case value_t::string:
1885 assert(other.m_value.string !=
nullptr);
1886 m_value = *other.m_value.string;
1890 case value_t::boolean:
1892 m_value = other.m_value.boolean;
1896 case value_t::number_integer:
1898 m_value = other.m_value.number_integer;
1902 case value_t::number_unsigned:
1904 m_value = other.m_value.number_unsigned;
1908 case value_t::number_float:
1910 m_value = other.m_value.number_float;
1940 : m_type(
std::move(other.m_type)),
1941 m_value(
std::move(other.m_value))
1944 other.m_type = value_t::null;
1972 std::is_nothrow_move_constructible<value_t>::value and
1973 std::is_nothrow_move_assignable<value_t>::value and
1974 std::is_nothrow_move_constructible<json_value>::value and
1975 std::is_nothrow_move_assignable<json_value>::value
1979 swap(m_type, other.m_type);
1980 swap(m_value, other.m_value);
2003 case value_t::object:
2005 AllocatorType<object_t> alloc;
2006 alloc.destroy(m_value.object);
2007 alloc.deallocate(m_value.object, 1);
2011 case value_t::array:
2013 AllocatorType<array_t> alloc;
2014 alloc.destroy(m_value.array);
2015 alloc.deallocate(m_value.array, 1);
2019 case value_t::string:
2021 AllocatorType<string_t> alloc;
2022 alloc.destroy(m_value.string);
2023 alloc.deallocate(m_value.string, 1);
2070 std::stringstream ss;
2074 dump(ss,
true, static_cast<unsigned int>(indent));
2128 return is_null() or is_string() or is_boolean() or is_number();
2152 return is_array() or is_object();
2171 return m_type == value_t::null;
2190 return m_type == value_t::boolean;
2217 return is_number_integer() or is_number_float();
2243 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2268 return m_type == value_t::number_unsigned;
2293 return m_type == value_t::number_float;
2312 return m_type == value_t::object;
2331 return m_type == value_t::array;
2350 return m_type == value_t::string;
2374 return m_type == value_t::discarded;
2405 template <
class T,
typename 2407 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2408 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2410 T get_impl(T*)
const 2414 assert(m_value.object !=
nullptr);
2415 return T(m_value.object->begin(), m_value.object->end());
2419 throw std::domain_error(
"type must be object, but is " + type_name());
2428 assert(m_value.object !=
nullptr);
2429 return *(m_value.object);
2433 throw std::domain_error(
"type must be object, but is " + type_name());
2438 template <
class T,
typename 2440 std::is_convertible<basic_json_t, typename T::value_type>::value and
2441 not std::is_same<basic_json_t, typename T::value_type>::value and
2442 not std::is_arithmetic<T>::value and
2443 not std::is_convertible<std::string, T>::value and
2444 not has_mapped_type<T>::value
2446 T get_impl(T*)
const 2451 assert(m_value.array !=
nullptr);
2452 std::transform(m_value.array->begin(), m_value.array->end(),
2453 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2455 return i.
get<
typename T::value_type>();
2461 throw std::domain_error(
"type must be array, but is " + type_name());
2466 template <
class T,
typename 2468 std::is_convertible<basic_json_t, T>::value and
2469 not std::is_same<basic_json_t, T>::value
2471 std::vector<T> get_impl(std::vector<T>*)
const 2475 std::vector<T> to_vector;
2476 assert(m_value.array !=
nullptr);
2477 to_vector.reserve(m_value.array->size());
2478 std::transform(m_value.array->begin(), m_value.array->end(),
2479 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2487 throw std::domain_error(
"type must be array, but is " + type_name());
2492 template <
class T,
typename 2494 std::is_same<basic_json, typename T::value_type>::value and
2495 not has_mapped_type<T>::value
2497 T get_impl(T*)
const 2501 assert(m_value.array !=
nullptr);
2502 return T(m_value.array->begin(), m_value.array->end());
2506 throw std::domain_error(
"type must be array, but is " + type_name());
2515 assert(m_value.array !=
nullptr);
2516 return *(m_value.array);
2520 throw std::domain_error(
"type must be array, but is " + type_name());
2525 template <
typename T,
typename 2527 std::is_convertible<string_t, T>::value
2529 T get_impl(T*)
const 2533 assert(m_value.string !=
nullptr);
2534 return *m_value.string;
2538 throw std::domain_error(
"type must be string, but is " + type_name());
2543 template<
typename T,
typename 2545 std::is_arithmetic<T>::value
2547 T get_impl(T*)
const 2551 case value_t::number_integer:
2553 return static_cast<T
>(m_value.number_integer);
2556 case value_t::number_unsigned:
2558 return static_cast<T
>(m_value.number_unsigned);
2561 case value_t::number_float:
2563 return static_cast<T
>(m_value.number_float);
2568 throw std::domain_error(
"type must be number, but is " + type_name());
2578 return m_value.boolean;
2582 throw std::domain_error(
"type must be boolean, but is " + type_name());
2589 return is_object() ? m_value.object :
nullptr;
2595 return is_object() ? m_value.object :
nullptr;
2601 return is_array() ? m_value.array :
nullptr;
2607 return is_array() ? m_value.array :
nullptr;
2613 return is_string() ? m_value.string :
nullptr;
2619 return is_string() ? m_value.string :
nullptr;
2625 return is_boolean() ? &m_value.boolean :
nullptr;
2631 return is_boolean() ? &m_value.boolean :
nullptr;
2637 return is_number_integer() ? &m_value.number_integer :
nullptr;
2643 return is_number_integer() ? &m_value.number_integer :
nullptr;
2649 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2655 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2661 return is_number_float() ? &m_value.number_float :
nullptr;
2667 return is_number_float() ? &m_value.number_float :
nullptr;
2681 template<
typename ReferenceType,
typename ThisType>
2682 static ReferenceType get_ref_impl(ThisType& obj)
2685 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2686 auto ptr = obj.template get_ptr<PointerType>();
2694 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2737 template<
typename ValueType,
typename 2739 not std::is_pointer<ValueType>::value
2741 ValueType
get()
const 2743 return get_impl(static_cast<ValueType*>(
nullptr));
2772 template<
typename PointerType,
typename 2774 std::is_pointer<PointerType>::value
2776 PointerType
get() noexcept
2779 return get_ptr<PointerType>();
2786 template<
typename PointerType,
typename 2788 std::is_pointer<PointerType>::value
2790 const PointerType
get()
const noexcept
2793 return get_ptr<PointerType>();
2821 template<
typename PointerType,
typename 2823 std::is_pointer<PointerType>::value
2828 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2835 template<
typename PointerType,
typename 2837 std::is_pointer<PointerType>::value
2838 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2843 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2872 template<
typename ReferenceType,
typename 2874 std::is_reference<ReferenceType>::value
2879 return get_ref_impl<ReferenceType>(*this);
2886 template<
typename ReferenceType,
typename 2888 std::is_reference<ReferenceType>::value
2889 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2894 return get_ref_impl<ReferenceType>(*this);
2925 template <
typename ValueType,
typename 2927 not std::is_pointer<ValueType>::value
2928 and not std::is_same<ValueType, typename string_t::value_type>::value
2929 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2930 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2933 operator ValueType()
const 2936 return get<ValueType>();
2978 assert(m_value.array !=
nullptr);
2979 return m_value.array->at(idx);
2981 catch (std::out_of_range&)
2984 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2989 throw std::domain_error(
"cannot use at() with " + type_name());
3022 assert(m_value.array !=
nullptr);
3023 return m_value.array->at(idx);
3025 catch (std::out_of_range&)
3028 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3033 throw std::domain_error(
"cannot use at() with " + type_name());
3070 assert(m_value.object !=
nullptr);
3071 return m_value.object->at(key);
3073 catch (std::out_of_range&)
3076 throw std::out_of_range(
"key '" + key +
"' not found");
3081 throw std::domain_error(
"cannot use at() with " + type_name());
3118 assert(m_value.object !=
nullptr);
3119 return m_value.object->at(key);
3121 catch (std::out_of_range&)
3124 throw std::out_of_range(
"key '" + key +
"' not found");
3129 throw std::domain_error(
"cannot use at() with " + type_name());
3163 m_type = value_t::array;
3164 m_value.
array = create<array_t>();
3171 assert(m_value.array !=
nullptr);
3172 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3174 m_value.array->push_back(basic_json());
3177 return m_value.array->operator[](idx);
3181 throw std::domain_error(
"cannot use operator[] with " + type_name());
3209 assert(m_value.array !=
nullptr);
3210 return m_value.array->operator[](idx);
3214 throw std::domain_error(
"cannot use operator[] with " + type_name());
3250 m_type = value_t::object;
3251 m_value.
object = create<object_t>();
3257 assert(m_value.object !=
nullptr);
3258 return m_value.object->operator[](key);
3262 throw std::domain_error(
"cannot use operator[] with " + type_name());
3298 assert(m_value.object !=
nullptr);
3299 assert(m_value.object->find(key) != m_value.object->end());
3300 return m_value.object->find(key)->second;
3304 throw std::domain_error(
"cannot use operator[] with " + type_name());
3335 template<
typename T, std::
size_t n>
3338 return operator[](static_cast<const T>(key));
3370 template<
typename T, std::
size_t n>
3373 return operator[](static_cast<const T>(key));
3403 template<
typename T>
3409 m_type = value_t::object;
3410 m_value = value_t::object;
3416 assert(m_value.object !=
nullptr);
3417 return m_value.object->operator[](key);
3421 throw std::domain_error(
"cannot use operator[] with " + type_name());
3452 template<
typename T>
3458 assert(m_value.object !=
nullptr);
3459 assert(m_value.object->find(key) != m_value.object->end());
3460 return m_value.object->find(key)->second;
3464 throw std::domain_error(
"cannot use operator[] with " + type_name());
3516 template <
class ValueType,
typename 3518 std::is_convertible<basic_json_t, ValueType>::value
3520 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3526 const auto it = find(key);
3533 return default_value;
3538 throw std::domain_error(
"cannot use value() with " + type_name());
3546 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3548 return value(key,
string_t(default_value));
3679 template <
class InteratorType,
typename 3681 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3682 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3688 if (
this != pos.m_object)
3690 throw std::domain_error(
"iterator does not fit current value");
3693 InteratorType result = end();
3697 case value_t::boolean:
3698 case value_t::number_float:
3699 case value_t::number_integer:
3700 case value_t::number_unsigned:
3701 case value_t::string:
3703 if (not pos.m_it.primitive_iterator.is_begin())
3705 throw std::out_of_range(
"iterator out of range");
3710 delete m_value.string;
3711 m_value.string =
nullptr;
3714 m_type = value_t::null;
3718 case value_t::object:
3720 assert(m_value.object !=
nullptr);
3721 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3725 case value_t::array:
3727 assert(m_value.array !=
nullptr);
3728 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3734 throw std::domain_error(
"cannot use erase() with " + type_name());
3787 template <
class InteratorType,
typename 3789 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3790 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3793 InteratorType
erase(InteratorType first, InteratorType last)
3796 if (
this != first.m_object or
this != last.m_object)
3798 throw std::domain_error(
"iterators do not fit current value");
3801 InteratorType result = end();
3805 case value_t::boolean:
3806 case value_t::number_float:
3807 case value_t::number_integer:
3808 case value_t::number_unsigned:
3809 case value_t::string:
3811 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3813 throw std::out_of_range(
"iterators out of range");
3818 delete m_value.string;
3819 m_value.string =
nullptr;
3822 m_type = value_t::null;
3826 case value_t::object:
3828 assert(m_value.object !=
nullptr);
3829 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3830 last.m_it.object_iterator);
3834 case value_t::array:
3836 assert(m_value.array !=
nullptr);
3837 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3838 last.m_it.array_iterator);
3844 throw std::domain_error(
"cannot use erase() with " + type_name());
3885 assert(m_value.object !=
nullptr);
3886 return m_value.object->erase(key);
3890 throw std::domain_error(
"cannot use erase() with " + type_name());
3925 throw std::out_of_range(
"index out of range");
3928 assert(m_value.array !=
nullptr);
3929 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3933 throw std::domain_error(
"cannot use erase() with " + type_name());
3966 auto result = end();
3970 assert(m_value.object !=
nullptr);
3971 result.m_it.object_iterator = m_value.object->find(key);
3983 auto result = cend();
3987 assert(m_value.object !=
nullptr);
3988 result.m_it.object_iterator = m_value.object->find(key);
4015 assert(not is_object() or m_value.object !=
nullptr);
4016 return is_object() ? m_value.object->count(key) : 0;
4304 template<
typename IteratorType>
class iteration_proxy;
4320 return iteration_proxy<iterator>(cont);
4328 return iteration_proxy<const_iterator>(cont);
4384 case value_t::array:
4386 assert(m_value.array !=
nullptr);
4387 return m_value.array->empty();
4390 case value_t::object:
4392 assert(m_value.object !=
nullptr);
4393 return m_value.object->empty();
4447 case value_t::array:
4449 assert(m_value.array !=
nullptr);
4450 return m_value.array->size();
4453 case value_t::object:
4455 assert(m_value.object !=
nullptr);
4456 return m_value.object->size();
4507 case value_t::array:
4509 assert(m_value.array !=
nullptr);
4510 return m_value.array->max_size();
4513 case value_t::object:
4515 assert(m_value.object !=
nullptr);
4516 return m_value.object->max_size();
4566 case value_t::number_integer:
4568 m_value.number_integer = 0;
4572 case value_t::number_unsigned:
4574 m_value.number_unsigned = 0;
4578 case value_t::number_float:
4580 m_value.number_float = 0.0;
4584 case value_t::boolean:
4586 m_value.boolean =
false;
4590 case value_t::string:
4592 assert(m_value.string !=
nullptr);
4593 m_value.string->clear();
4597 case value_t::array:
4599 assert(m_value.array !=
nullptr);
4600 m_value.array->clear();
4604 case value_t::object:
4606 assert(m_value.object !=
nullptr);
4607 m_value.object->clear();
4641 if (not(is_null() or is_array()))
4643 throw std::domain_error(
"cannot use push_back() with " + type_name());
4649 m_type = value_t::array;
4650 m_value = value_t::array;
4654 assert(m_value.array !=
nullptr);
4655 m_value.array->push_back(std::move(val));
4657 val.m_type = value_t::null;
4666 push_back(std::move(val));
4677 if (not(is_null() or is_array()))
4679 throw std::domain_error(
"cannot use push_back() with " + type_name());
4685 m_type = value_t::array;
4686 m_value = value_t::array;
4690 assert(m_value.array !=
nullptr);
4691 m_value.array->push_back(val);
4727 if (not(is_null() or is_object()))
4729 throw std::domain_error(
"cannot use push_back() with " + type_name());
4735 m_type = value_t::object;
4736 m_value = value_t::object;
4740 assert(m_value.object !=
nullptr);
4741 m_value.object->insert(val);
4751 return operator[](val.first);
4782 if (pos.m_object !=
this)
4784 throw std::domain_error(
"iterator does not fit current value");
4789 assert(m_value.array !=
nullptr);
4790 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4795 throw std::domain_error(
"cannot use insert() with " + type_name());
4805 return insert(pos, val);
4838 if (pos.m_object !=
this)
4840 throw std::domain_error(
"iterator does not fit current value");
4845 assert(m_value.array !=
nullptr);
4846 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4851 throw std::domain_error(
"cannot use insert() with " + type_name());
4890 throw std::domain_error(
"cannot use insert() with " + type_name());
4894 if (pos.m_object !=
this)
4896 throw std::domain_error(
"iterator does not fit current value");
4899 if (first.m_object != last.m_object)
4901 throw std::domain_error(
"iterators do not fit");
4904 if (first.m_object ==
this or last.m_object ==
this)
4906 throw std::domain_error(
"passed iterators may not belong to container");
4911 assert(m_value.array !=
nullptr);
4912 result.m_it.array_iterator = m_value.array->insert(
4913 pos.m_it.array_iterator,
4914 first.m_it.array_iterator,
4915 last.m_it.array_iterator);
4948 throw std::domain_error(
"cannot use insert() with " + type_name());
4952 if (pos.m_object !=
this)
4954 throw std::domain_error(
"iterator does not fit current value");
4959 assert(m_value.array !=
nullptr);
4960 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4982 std::is_nothrow_move_constructible<value_t>::value and
4983 std::is_nothrow_move_assignable<value_t>::value and
4984 std::is_nothrow_move_constructible<json_value>::value and
4985 std::is_nothrow_move_assignable<json_value>::value
4988 std::swap(m_type, other.m_type);
4989 std::swap(m_value, other.m_value);
5017 assert(m_value.array !=
nullptr);
5018 std::swap(*(m_value.array), other);
5022 throw std::domain_error(
"cannot use swap() with " + type_name());
5051 assert(m_value.object !=
nullptr);
5052 std::swap(*(m_value.object), other);
5056 throw std::domain_error(
"cannot use swap() with " + type_name());
5085 assert(m_value.string !=
nullptr);
5086 std::swap(*(m_value.string), other);
5090 throw std::domain_error(
"cannot use swap() with " + type_name());
5116 static constexpr std::array<uint8_t, 8> order = {{
5129 if (lhs == value_t::discarded or rhs == value_t::discarded)
5134 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5163 const auto lhs_type = lhs.type();
5164 const auto rhs_type = rhs.type();
5166 if (lhs_type == rhs_type)
5170 case value_t::array:
5172 assert(lhs.m_value.array !=
nullptr);
5173 assert(rhs.m_value.array !=
nullptr);
5174 return *lhs.m_value.array == *rhs.m_value.array;
5176 case value_t::object:
5178 assert(lhs.m_value.object !=
nullptr);
5179 assert(rhs.m_value.object !=
nullptr);
5180 return *lhs.m_value.object == *rhs.m_value.object;
5186 case value_t::string:
5188 assert(lhs.m_value.string !=
nullptr);
5189 assert(rhs.m_value.string !=
nullptr);
5190 return *lhs.m_value.string == *rhs.m_value.string;
5192 case value_t::boolean:
5194 return lhs.m_value.boolean == rhs.m_value.boolean;
5196 case value_t::number_integer:
5198 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5200 case value_t::number_unsigned:
5202 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5204 case value_t::number_float:
5206 return lhs.m_value.number_float == rhs.m_value.number_float;
5214 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5216 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5218 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5220 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5222 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5224 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5226 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5228 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5230 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5232 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5234 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5236 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5292 return not (lhs == rhs);
5324 return not v.is_null();
5353 const auto lhs_type = lhs.type();
5354 const auto rhs_type = rhs.type();
5356 if (lhs_type == rhs_type)
5360 case value_t::array:
5362 assert(lhs.m_value.array !=
nullptr);
5363 assert(rhs.m_value.array !=
nullptr);
5364 return *lhs.m_value.array < *rhs.m_value.array;
5366 case value_t::object:
5368 assert(lhs.m_value.object !=
nullptr);
5369 assert(rhs.m_value.object !=
nullptr);
5370 return *lhs.m_value.object < *rhs.m_value.object;
5376 case value_t::string:
5378 assert(lhs.m_value.string !=
nullptr);
5379 assert(rhs.m_value.string !=
nullptr);
5380 return *lhs.m_value.string < *rhs.m_value.string;
5382 case value_t::boolean:
5384 return lhs.m_value.boolean < rhs.m_value.boolean;
5386 case value_t::number_integer:
5388 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5390 case value_t::number_unsigned:
5392 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5394 case value_t::number_float:
5396 return lhs.m_value.number_float < rhs.m_value.number_float;
5404 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5406 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5408 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5410 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5412 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5414 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5416 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5418 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5420 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5422 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5424 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5426 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5432 return operator<(lhs_type, rhs_type);
5454 return not (rhs < lhs);
5476 return not (lhs <= rhs);
5498 return not (lhs < rhs);
5533 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5536 const bool pretty_print = (o.width() > 0);
5537 const auto indentation = (pretty_print ? o.width() : 0);
5543 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5551 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5592 return parser(s, cb).
parse();
5621 return parser(i, cb).
parse();
5629 return parser(i, cb).
parse();
5657 j = parser(i).
parse();
5667 j = parser(i).
parse();
5686 case value_t::object:
5688 case value_t::array:
5690 case value_t::string:
5692 case value_t::boolean:
5694 case value_t::discarded:
5709 static std::size_t extra_space(
const string_t& s) noexcept
5711 std::size_t result = 0;
5713 for (
const auto& c : s)
5732 if (c >= 0x00 and c <= 0x1f)
5760 const auto space = extra_space(s);
5767 string_t result(s.size() + space,
'\\');
5768 std::size_t pos = 0;
5770 for (
const auto& c : s)
5777 result[pos + 1] =
'"';
5793 result[pos + 1] =
'b';
5801 result[pos + 1] =
'f';
5809 result[pos + 1] =
'n';
5817 result[pos + 1] =
'r';
5825 result[pos + 1] =
't';
5832 if (c >= 0x00 and c <= 0x1f)
5836 auto hexify = [](
const char v) ->
char 5838 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5843 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5881 void dump(std::ostream& o,
5882 const bool pretty_print,
5883 const unsigned int indent_step,
5884 const unsigned int current_indent = 0)
const 5887 unsigned int new_indent = current_indent;
5891 case value_t::object:
5893 assert(m_value.object !=
nullptr);
5895 if (m_value.object->empty())
5906 new_indent += indent_step;
5910 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5912 if (i != m_value.object->cbegin())
5914 o << (pretty_print ?
",\n" :
",");
5916 o <<
string_t(new_indent,
' ') <<
"\"" 5917 << escape_string(i->first) <<
"\":" 5918 << (pretty_print ?
" " :
"");
5919 i->second.dump(o, pretty_print, indent_step, new_indent);
5925 new_indent -= indent_step;
5929 o <<
string_t(new_indent,
' ') +
"}";
5933 case value_t::array:
5935 assert(m_value.array !=
nullptr);
5937 if (m_value.array->empty())
5948 new_indent += indent_step;
5952 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5954 if (i != m_value.array->cbegin())
5956 o << (pretty_print ?
",\n" :
",");
5959 i->dump(o, pretty_print, indent_step, new_indent);
5965 new_indent -= indent_step;
5969 o <<
string_t(new_indent,
' ') <<
"]";
5973 case value_t::string:
5975 assert(m_value.string !=
nullptr);
5976 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5980 case value_t::boolean:
5982 o << (m_value.boolean ?
"true" :
"false");
5986 case value_t::number_integer:
5988 o << m_value.number_integer;
5992 case value_t::number_unsigned:
5994 o << m_value.number_unsigned;
5998 case value_t::number_float:
6006 if (std::fmod(m_value.number_float, 1) == 0)
6008 o << std::fixed << std::setprecision(1);
6013 o.unsetf(std::ios_base::floatfield);
6014 o << std::setprecision(std::numeric_limits<double>::digits10);
6016 o << m_value.number_float;
6020 case value_t::discarded:
6040 value_t m_type = value_t::null;
6043 json_value m_value = {};
6060 class primitive_iterator_t
6076 bool is_begin()
const 6078 return (m_it == begin_value);
6084 return (m_it == end_value);
6104 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6114 struct internal_iterator
6117 typename object_t::iterator object_iterator;
6119 typename array_t::iterator array_iterator;
6121 primitive_iterator_t primitive_iterator;
6125 : object_iterator(), array_iterator(), primitive_iterator()
6130 template<
typename IteratorType>
6131 class iteration_proxy
6135 class iteration_proxy_internal
6139 IteratorType anchor;
6141 size_t array_index = 0;
6144 iteration_proxy_internal(IteratorType it)
6149 iteration_proxy_internal& operator*()
6155 iteration_proxy_internal& operator++()
6164 bool operator!= (
const iteration_proxy_internal& o)
const 6166 return anchor != o.anchor;
6172 assert(anchor.m_object !=
nullptr);
6174 switch (anchor.m_object->type())
6177 case value_t::array:
6179 return std::to_string(array_index);
6183 case value_t::object:
6185 return anchor.key();
6197 typename IteratorType::reference value()
const 6199 return anchor.value();
6204 typename IteratorType::reference container;
6208 iteration_proxy(
typename IteratorType::reference cont)
6213 iteration_proxy_internal begin()
6215 return iteration_proxy_internal(container.begin());
6219 iteration_proxy_internal end()
6221 return iteration_proxy_internal(container.end());
6239 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6242 friend class basic_json;
6262 assert(m_object !=
nullptr);
6264 switch (m_object->m_type)
6268 m_it.object_iterator =
typename object_t::iterator();
6274 m_it.array_iterator =
typename array_t::iterator();
6280 m_it.primitive_iterator = primitive_iterator_t();
6289 assert(m_object !=
nullptr);
6291 switch (m_object->m_type)
6295 m_it.object_iterator = other.m_it.object_iterator;
6301 m_it.array_iterator = other.m_it.array_iterator;
6307 m_it.primitive_iterator = other.m_it.primitive_iterator;
6315 : m_object(other.m_object), m_it(other.m_it)
6320 std::is_nothrow_move_constructible<pointer>::value and
6321 std::is_nothrow_move_assignable<pointer>::value and
6322 std::is_nothrow_move_constructible<internal_iterator>::value and
6323 std::is_nothrow_move_assignable<internal_iterator>::value
6326 std::swap(m_object, other.m_object);
6327 std::swap(m_it, other.m_it);
6335 assert(m_object !=
nullptr);
6337 switch (m_object->m_type)
6341 assert(m_object->m_value.object !=
nullptr);
6342 m_it.object_iterator = m_object->m_value.object->begin();
6348 assert(m_object->m_value.array !=
nullptr);
6349 m_it.array_iterator = m_object->m_value.array->begin();
6356 m_it.primitive_iterator.set_end();
6362 m_it.primitive_iterator.set_begin();
6371 assert(m_object !=
nullptr);
6373 switch (m_object->m_type)
6377 assert(m_object->m_value.object !=
nullptr);
6378 m_it.object_iterator = m_object->m_value.object->end();
6384 assert(m_object->m_value.array !=
nullptr);
6385 m_it.array_iterator = m_object->m_value.array->end();
6391 m_it.primitive_iterator.set_end();
6401 assert(m_object !=
nullptr);
6403 switch (m_object->m_type)
6407 assert(m_object->m_value.object);
6408 assert(m_it.object_iterator != m_object->m_value.object->end());
6409 return m_it.object_iterator->second;
6414 assert(m_object->m_value.array);
6415 assert(m_it.array_iterator != m_object->m_value.array->end());
6416 return *m_it.array_iterator;
6421 throw std::out_of_range(
"cannot get value");
6426 if (m_it.primitive_iterator.is_begin())
6432 throw std::out_of_range(
"cannot get value");
6441 assert(m_object !=
nullptr);
6443 switch (m_object->m_type)
6447 assert(m_object->m_value.object);
6448 assert(m_it.object_iterator != m_object->m_value.object->end());
6449 return &(m_it.object_iterator->second);
6454 assert(m_object->m_value.array);
6455 assert(m_it.array_iterator != m_object->m_value.array->end());
6456 return &*m_it.array_iterator;
6461 if (m_it.primitive_iterator.is_begin())
6467 throw std::out_of_range(
"cannot get value");
6476 auto result = *
this;
6484 assert(m_object !=
nullptr);
6486 switch (m_object->m_type)
6490 ++m_it.object_iterator;
6496 ++m_it.array_iterator;
6502 ++m_it.primitive_iterator;
6513 auto result = *
this;
6521 assert(m_object !=
nullptr);
6523 switch (m_object->m_type)
6527 --m_it.object_iterator;
6533 --m_it.array_iterator;
6539 --m_it.primitive_iterator;
6551 if (m_object != other.m_object)
6553 throw std::domain_error(
"cannot compare iterators of different containers");
6556 assert(m_object !=
nullptr);
6558 switch (m_object->m_type)
6562 return (m_it.object_iterator == other.m_it.object_iterator);
6567 return (m_it.array_iterator == other.m_it.array_iterator);
6572 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6580 return not operator==(other);
6587 if (m_object != other.m_object)
6589 throw std::domain_error(
"cannot compare iterators of different containers");
6592 assert(m_object !=
nullptr);
6594 switch (m_object->m_type)
6598 throw std::domain_error(
"cannot compare order of object iterators");
6603 return (m_it.array_iterator < other.m_it.array_iterator);
6608 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6616 return not other.operator < (*this);
6622 return not operator<=(other);
6628 return not operator<(other);
6634 assert(m_object !=
nullptr);
6636 switch (m_object->m_type)
6640 throw std::domain_error(
"cannot use offsets with object iterators");
6645 m_it.array_iterator += i;
6651 m_it.primitive_iterator += i;
6662 return operator+=(-i);
6668 auto result = *
this;
6676 auto result = *
this;
6684 assert(m_object !=
nullptr);
6686 switch (m_object->m_type)
6690 throw std::domain_error(
"cannot use offsets with object iterators");
6695 return m_it.array_iterator - other.m_it.array_iterator;
6700 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6708 assert(m_object !=
nullptr);
6710 switch (m_object->m_type)
6714 throw std::domain_error(
"cannot use operator[] for object iterators");
6719 return *(m_it.array_iterator + n);
6724 throw std::out_of_range(
"cannot get value");
6729 if (m_it.primitive_iterator == -n)
6735 throw std::out_of_range(
"cannot get value");
6742 typename object_t::key_type
key()
const 6744 assert(m_object !=
nullptr);
6746 if (m_object->is_object())
6748 return m_it.object_iterator->first;
6752 throw std::domain_error(
"cannot use key() for non-object iterators");
6766 internal_iterator m_it = internal_iterator();
6803 std::is_nothrow_move_constructible<pointer>::value and
6804 std::is_nothrow_move_assignable<pointer>::value and
6805 std::is_nothrow_move_constructible<internal_iterator>::value and
6806 std::is_nothrow_move_assignable<internal_iterator>::value
6809 base_iterator::operator=(other);
6816 return const_cast<reference>(base_iterator::operator*());
6822 return const_cast<pointer>(base_iterator::operator->());
6829 base_iterator::operator++();
6836 base_iterator::operator++();
6844 base_iterator::operator--();
6851 base_iterator::operator--();
6858 base_iterator::operator+=(i);
6865 base_iterator::operator-=(i);
6872 auto result = *
this;
6880 auto result = *
this;
6888 return base_iterator::operator-(other);
6894 return const_cast<reference>(base_iterator::operator[](n));
6900 return const_cast<reference>(base_iterator::value());
6921 template<
typename Base>
6943 return base_iterator::operator++(1);
6949 base_iterator::operator++();
6956 return base_iterator::operator--(1);
6962 base_iterator::operator--();
6969 base_iterator::operator+=(i);
6976 auto result = *
this;
6984 auto result = *
this;
6992 return this->base() - other.base();
6998 return *(this->operator+(n));
7002 typename object_t::key_type
key()
const 7004 auto it = --this->base();
7011 auto it = --this->base();
7012 return it.operator * ();
7033 enum class token_type
7052 using lexer_char_t =
unsigned char;
7055 explicit lexer(
const string_t& s) noexcept
7056 : m_stream(
nullptr), m_buffer(s)
7058 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7059 assert(m_content !=
nullptr);
7060 m_start = m_cursor = m_content;
7061 m_limit = m_content + s.size();
7065 explicit lexer(std::istream* s) noexcept
7066 : m_stream(s), m_buffer()
7068 assert(m_stream !=
nullptr);
7069 getline(*m_stream, m_buffer);
7070 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7071 assert(m_content !=
nullptr);
7072 m_start = m_cursor = m_content;
7073 m_limit = m_content + m_buffer.size();
7080 lexer(
const lexer&) =
delete;
7081 lexer operator=(
const lexer&) =
delete;
7098 static string_t to_unicode(
const std::size_t codepoint1,
7099 const std::size_t codepoint2 = 0)
7102 std::size_t codepoint = codepoint1;
7105 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7108 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7122 throw std::invalid_argument(
"missing or wrong low surrogate");
7128 if (codepoint < 0x80)
7131 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7133 else if (codepoint <= 0x7ff)
7136 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7137 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7139 else if (codepoint <= 0xffff)
7142 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7143 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7144 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7146 else if (codepoint <= 0x10ffff)
7149 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7150 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7151 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7152 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7156 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7163 static std::string token_type_name(token_type t)
7167 case token_type::uninitialized:
7168 return "<uninitialized>";
7169 case token_type::literal_true:
7170 return "true literal";
7171 case token_type::literal_false:
7172 return "false literal";
7173 case token_type::literal_null:
7174 return "null literal";
7175 case token_type::value_string:
7176 return "string literal";
7177 case token_type::value_number:
7178 return "number literal";
7179 case token_type::begin_array:
7181 case token_type::begin_object:
7183 case token_type::end_array:
7185 case token_type::end_object:
7187 case token_type::name_separator:
7189 case token_type::value_separator:
7191 case token_type::parse_error:
7192 return "<parse error>";
7193 case token_type::end_of_input:
7194 return "end of input";
7198 return "unknown token";
7213 token_type scan() noexcept
7220 assert(m_start !=
nullptr);
7225 unsigned int yyaccept = 0;
7226 static const unsigned char yybm[] =
7228 0, 0, 0, 0, 0, 0, 0, 0,
7229 0, 32, 32, 0, 0, 32, 0, 0,
7230 128, 128, 128, 128, 128, 128, 128, 128,
7231 128, 128, 128, 128, 128, 128, 128, 128,
7232 160, 128, 0, 128, 128, 128, 128, 128,
7233 128, 128, 128, 128, 128, 128, 128, 128,
7234 192, 192, 192, 192, 192, 192, 192, 192,
7235 192, 192, 128, 128, 128, 128, 128, 128,
7236 128, 128, 128, 128, 128, 128, 128, 128,
7237 128, 128, 128, 128, 128, 128, 128, 128,
7238 128, 128, 128, 128, 128, 128, 128, 128,
7239 128, 128, 128, 128, 0, 128, 128, 128,
7240 128, 128, 128, 128, 128, 128, 128, 128,
7241 128, 128, 128, 128, 128, 128, 128, 128,
7242 128, 128, 128, 128, 128, 128, 128, 128,
7243 128, 128, 128, 128, 128, 128, 128, 128,
7244 128, 128, 128, 128, 128, 128, 128, 128,
7245 128, 128, 128, 128, 128, 128, 128, 128,
7246 128, 128, 128, 128, 128, 128, 128, 128,
7247 128, 128, 128, 128, 128, 128, 128, 128,
7248 128, 128, 128, 128, 128, 128, 128, 128,
7249 128, 128, 128, 128, 128, 128, 128, 128,
7250 128, 128, 128, 128, 128, 128, 128, 128,
7251 128, 128, 128, 128, 128, 128, 128, 128,
7252 128, 128, 128, 128, 128, 128, 128, 128,
7253 128, 128, 128, 128, 128, 128, 128, 128,
7254 128, 128, 128, 128, 128, 128, 128, 128,
7255 128, 128, 128, 128, 128, 128, 128, 128,
7256 128, 128, 128, 128, 128, 128, 128, 128,
7257 128, 128, 128, 128, 128, 128, 128, 128,
7258 128, 128, 128, 128, 128, 128, 128, 128,
7259 128, 128, 128, 128, 128, 128, 128, 128,
7261 if ((m_limit - m_cursor) < 5)
7266 if (yybm[0 + yych] & 32)
7268 goto basic_json_parser_6;
7278 goto basic_json_parser_2;
7282 goto basic_json_parser_4;
7284 goto basic_json_parser_9;
7290 goto basic_json_parser_4;
7294 goto basic_json_parser_10;
7296 goto basic_json_parser_12;
7305 goto basic_json_parser_4;
7309 goto basic_json_parser_13;
7311 goto basic_json_parser_15;
7317 goto basic_json_parser_17;
7321 goto basic_json_parser_19;
7323 goto basic_json_parser_4;
7335 goto basic_json_parser_21;
7339 goto basic_json_parser_4;
7341 goto basic_json_parser_23;
7347 goto basic_json_parser_24;
7351 goto basic_json_parser_4;
7353 goto basic_json_parser_25;
7362 goto basic_json_parser_26;
7364 goto basic_json_parser_4;
7370 goto basic_json_parser_28;
7374 goto basic_json_parser_30;
7376 goto basic_json_parser_4;
7380 basic_json_parser_2:
7383 return token_type::end_of_input;
7385 basic_json_parser_4:
7387 basic_json_parser_5:
7389 return token_type::parse_error;
7391 basic_json_parser_6:
7393 if (m_limit <= m_cursor)
7398 if (yybm[0 + yych] & 32)
7400 goto basic_json_parser_6;
7405 basic_json_parser_9:
7407 yych = *(m_marker = ++m_cursor);
7410 goto basic_json_parser_5;
7412 goto basic_json_parser_32;
7413 basic_json_parser_10:
7416 return token_type::value_separator;
7418 basic_json_parser_12:
7422 goto basic_json_parser_5;
7426 goto basic_json_parser_13;
7430 goto basic_json_parser_15;
7432 goto basic_json_parser_5;
7433 basic_json_parser_13:
7435 yych = *(m_marker = ++m_cursor);
7440 goto basic_json_parser_37;
7447 goto basic_json_parser_38;
7451 goto basic_json_parser_38;
7454 basic_json_parser_14:
7456 return token_type::value_number;
7458 basic_json_parser_15:
7460 m_marker = ++m_cursor;
7461 if ((m_limit - m_cursor) < 3)
7466 if (yybm[0 + yych] & 64)
7468 goto basic_json_parser_15;
7474 goto basic_json_parser_37;
7476 goto basic_json_parser_14;
7482 goto basic_json_parser_38;
7486 goto basic_json_parser_38;
7488 goto basic_json_parser_14;
7490 basic_json_parser_17:
7493 return token_type::name_separator;
7495 basic_json_parser_19:
7498 return token_type::begin_array;
7500 basic_json_parser_21:
7503 return token_type::end_array;
7505 basic_json_parser_23:
7507 yych = *(m_marker = ++m_cursor);
7510 goto basic_json_parser_39;
7512 goto basic_json_parser_5;
7513 basic_json_parser_24:
7515 yych = *(m_marker = ++m_cursor);
7518 goto basic_json_parser_40;
7520 goto basic_json_parser_5;
7521 basic_json_parser_25:
7523 yych = *(m_marker = ++m_cursor);
7526 goto basic_json_parser_41;
7528 goto basic_json_parser_5;
7529 basic_json_parser_26:
7532 return token_type::begin_object;
7534 basic_json_parser_28:
7537 return token_type::end_object;
7539 basic_json_parser_30:
7541 yych = *(m_marker = ++m_cursor);
7544 goto basic_json_parser_42;
7546 goto basic_json_parser_5;
7547 basic_json_parser_31:
7549 if (m_limit <= m_cursor)
7554 basic_json_parser_32:
7555 if (yybm[0 + yych] & 128)
7557 goto basic_json_parser_31;
7561 goto basic_json_parser_33;
7565 goto basic_json_parser_34;
7567 goto basic_json_parser_36;
7568 basic_json_parser_33:
7569 m_cursor = m_marker;
7572 goto basic_json_parser_5;
7576 goto basic_json_parser_14;
7578 basic_json_parser_34:
7581 return token_type::value_string;
7583 basic_json_parser_36:
7585 if (m_limit <= m_cursor)
7596 goto basic_json_parser_31;
7600 goto basic_json_parser_33;
7602 goto basic_json_parser_31;
7610 goto basic_json_parser_33;
7612 goto basic_json_parser_31;
7618 goto basic_json_parser_31;
7620 goto basic_json_parser_33;
7630 goto basic_json_parser_31;
7634 goto basic_json_parser_31;
7636 goto basic_json_parser_33;
7644 goto basic_json_parser_31;
7646 goto basic_json_parser_33;
7652 goto basic_json_parser_31;
7656 goto basic_json_parser_43;
7658 goto basic_json_parser_33;
7662 basic_json_parser_37:
7666 goto basic_json_parser_33;
7670 goto basic_json_parser_44;
7672 goto basic_json_parser_33;
7673 basic_json_parser_38:
7679 goto basic_json_parser_46;
7681 goto basic_json_parser_33;
7687 goto basic_json_parser_46;
7691 goto basic_json_parser_33;
7695 goto basic_json_parser_47;
7697 goto basic_json_parser_33;
7699 basic_json_parser_39:
7703 goto basic_json_parser_49;
7705 goto basic_json_parser_33;
7706 basic_json_parser_40:
7710 goto basic_json_parser_50;
7712 goto basic_json_parser_33;
7713 basic_json_parser_41:
7717 goto basic_json_parser_51;
7719 goto basic_json_parser_33;
7720 basic_json_parser_42:
7724 goto basic_json_parser_52;
7726 goto basic_json_parser_33;
7727 basic_json_parser_43:
7729 if (m_limit <= m_cursor)
7738 goto basic_json_parser_33;
7742 goto basic_json_parser_54;
7744 goto basic_json_parser_33;
7750 goto basic_json_parser_54;
7754 goto basic_json_parser_33;
7758 goto basic_json_parser_54;
7760 goto basic_json_parser_33;
7762 basic_json_parser_44:
7764 m_marker = ++m_cursor;
7765 if ((m_limit - m_cursor) < 3)
7774 goto basic_json_parser_14;
7778 goto basic_json_parser_44;
7780 goto basic_json_parser_14;
7786 goto basic_json_parser_38;
7790 goto basic_json_parser_38;
7792 goto basic_json_parser_14;
7794 basic_json_parser_46:
7798 goto basic_json_parser_33;
7802 goto basic_json_parser_33;
7804 basic_json_parser_47:
7806 if (m_limit <= m_cursor)
7813 goto basic_json_parser_14;
7817 goto basic_json_parser_47;
7819 goto basic_json_parser_14;
7820 basic_json_parser_49:
7824 goto basic_json_parser_55;
7826 goto basic_json_parser_33;
7827 basic_json_parser_50:
7831 goto basic_json_parser_56;
7833 goto basic_json_parser_33;
7834 basic_json_parser_51:
7838 goto basic_json_parser_58;
7840 goto basic_json_parser_33;
7841 basic_json_parser_52:
7846 basic_json_parser_54:
7848 if (m_limit <= m_cursor)
7857 goto basic_json_parser_33;
7861 goto basic_json_parser_60;
7863 goto basic_json_parser_33;
7869 goto basic_json_parser_60;
7873 goto basic_json_parser_33;
7877 goto basic_json_parser_60;
7879 goto basic_json_parser_33;
7881 basic_json_parser_55:
7885 goto basic_json_parser_61;
7887 goto basic_json_parser_33;
7888 basic_json_parser_56:
7891 return token_type::literal_null;
7893 basic_json_parser_58:
7896 return token_type::literal_true;
7898 basic_json_parser_60:
7900 if (m_limit <= m_cursor)
7909 goto basic_json_parser_33;
7913 goto basic_json_parser_63;
7915 goto basic_json_parser_33;
7921 goto basic_json_parser_63;
7925 goto basic_json_parser_33;
7929 goto basic_json_parser_63;
7931 goto basic_json_parser_33;
7933 basic_json_parser_61:
7936 return token_type::literal_false;
7938 basic_json_parser_63:
7940 if (m_limit <= m_cursor)
7949 goto basic_json_parser_33;
7953 goto basic_json_parser_31;
7955 goto basic_json_parser_33;
7961 goto basic_json_parser_31;
7965 goto basic_json_parser_33;
7969 goto basic_json_parser_31;
7971 goto basic_json_parser_33;
7979 void yyfill() noexcept
7981 if (m_stream ==
nullptr or not * m_stream)
7986 const ssize_t offset_start = m_start - m_content;
7987 const ssize_t offset_marker = m_marker - m_start;
7988 const ssize_t offset_cursor = m_cursor - m_start;
7990 m_buffer.erase(0, static_cast<size_t>(offset_start));
7992 assert(m_stream !=
nullptr);
7993 std::getline(*m_stream, line);
7994 m_buffer +=
"\n" + line;
7996 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7997 assert(m_content !=
nullptr);
7998 m_start = m_content;
7999 m_marker = m_start + offset_marker;
8000 m_cursor = m_start + offset_cursor;
8001 m_limit = m_start + m_buffer.size() - 1;
8005 string_t get_token()
const noexcept
8007 assert(m_start !=
nullptr);
8008 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
8009 static_cast<size_t>(m_cursor - m_start));
8036 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8039 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8095 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8096 4).c_str(),
nullptr, 16);
8099 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8102 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8104 throw std::invalid_argument(
"missing low surrogate");
8108 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8109 (i + 7), 4).c_str(),
nullptr, 16);
8110 result += to_unicode(codepoint, codepoint2);
8117 result += to_unicode(codepoint);
8129 result.append(1, static_cast<typename string_t::value_type>(*i));
8156 long double str_to_float_t(
long double* ,
char** endptr)
const 8158 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8176 double str_to_float_t(
double* ,
char** endptr)
const 8178 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8196 float str_to_float_t(
float* ,
char** endptr)
const 8198 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8213 template <
typename T_A,
typename T_B>
8214 bool attempt_cast(T_A source, T_B& dest)
const 8216 dest =
static_cast<T_B
>(source);
8217 return (source == static_cast<T_A>(dest));
8258 void get_number(basic_json& result)
const 8260 typename string_t::value_type* endptr;
8261 assert(m_start !=
nullptr);
8266 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8270 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8271 10), result.m_value.number_unsigned))
8273 result.m_type = value_t::number_unsigned;
8278 result.m_type = value_t::number_float;
8285 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8286 10), result.m_value.number_integer))
8288 result.m_type = value_t::number_integer;
8293 result.m_type = value_t::number_float;
8299 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8301 result.m_type = value_t::number_float;
8304 if (result.m_type == value_t::number_float)
8311 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8314 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8316 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8323 std::istream* m_stream =
nullptr;
8327 const lexer_char_t* m_content =
nullptr;
8329 const lexer_char_t* m_start =
nullptr;
8331 const lexer_char_t* m_marker =
nullptr;
8333 const lexer_char_t* m_cursor =
nullptr;
8335 const lexer_char_t* m_limit =
nullptr;
8348 : callback(cb), m_lexer(s)
8356 : callback(cb), m_lexer(&_is)
8365 basic_json result = parse_internal(
true);
8367 expect(lexer::token_type::end_of_input);
8376 basic_json parse_internal(
bool keep)
8378 auto result = basic_json(value_t::discarded);
8382 case lexer::token_type::begin_object:
8384 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8387 result.m_type = value_t::object;
8388 result.m_value = json_value(value_t::object);
8395 if (last_token == lexer::token_type::end_object)
8398 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8400 result = basic_json(value_t::discarded);
8406 unexpect(lexer::token_type::value_separator);
8412 if (last_token == lexer::token_type::value_separator)
8418 expect(lexer::token_type::value_string);
8419 const auto key = m_lexer.get_string();
8421 bool keep_tag =
false;
8427 keep_tag = callback(depth, parse_event_t::key, k);
8437 expect(lexer::token_type::name_separator);
8441 auto value = parse_internal(keep);
8442 if (keep and keep_tag and not value.is_discarded())
8444 result[key] = std::move(value);
8447 while (last_token == lexer::token_type::value_separator);
8450 expect(lexer::token_type::end_object);
8452 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8454 result = basic_json(value_t::discarded);
8460 case lexer::token_type::begin_array:
8462 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8465 result.m_type = value_t::array;
8466 result.m_value = json_value(value_t::array);
8473 if (last_token == lexer::token_type::end_array)
8476 if (callback and not callback(--depth, parse_event_t::array_end, result))
8478 result = basic_json(value_t::discarded);
8484 unexpect(lexer::token_type::value_separator);
8490 if (last_token == lexer::token_type::value_separator)
8496 auto value = parse_internal(keep);
8497 if (keep and not value.is_discarded())
8499 result.push_back(std::move(value));
8502 while (last_token == lexer::token_type::value_separator);
8505 expect(lexer::token_type::end_array);
8507 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8509 result = basic_json(value_t::discarded);
8515 case lexer::token_type::literal_null:
8518 result.m_type = value_t::null;
8522 case lexer::token_type::value_string:
8524 const auto s = m_lexer.get_string();
8526 result = basic_json(s);
8530 case lexer::token_type::literal_true:
8533 result.m_type = value_t::boolean;
8534 result.m_value =
true;
8538 case lexer::token_type::literal_false:
8541 result.m_type = value_t::boolean;
8542 result.m_value =
false;
8546 case lexer::token_type::value_number:
8548 m_lexer.get_number(result);
8556 unexpect(last_token);
8560 if (keep and callback and not callback(depth, parse_event_t::value, result))
8562 result = basic_json(value_t::discarded);
8568 typename lexer::token_type get_token()
8570 last_token = m_lexer.scan();
8574 void expect(
typename lexer::token_type t)
const 8576 if (t != last_token)
8578 std::string error_msg =
"parse error - unexpected ";
8579 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8580 lexer::token_type_name(last_token));
8581 error_msg +=
"; expected " + lexer::token_type_name(t);
8582 throw std::invalid_argument(error_msg);
8586 void unexpect(
typename lexer::token_type t)
const 8588 if (t == last_token)
8590 std::string error_msg =
"parse error - unexpected ";
8591 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8592 lexer::token_type_name(last_token));
8593 throw std::invalid_argument(error_msg);
8603 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8641 is_nothrow_move_constructible<nlohmann::json>::value and
8642 is_nothrow_move_assignable<nlohmann::json>::value
8660 const auto& h = hash<nlohmann::json::string_t>();
8678 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8684 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8685 #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
basic_json(std::istream &i, parser_callback_t cb=nullptr)
construct a JSON value given an input stream
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.