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>();
3170 assert(m_value.array !=
nullptr);
3171 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3173 m_value.array->push_back(basic_json());
3176 return m_value.array->operator[](idx);
3180 throw std::domain_error(
"cannot use operator[] with " + type_name());
3208 assert(m_value.array !=
nullptr);
3209 return m_value.array->operator[](idx);
3213 throw std::domain_error(
"cannot use operator[] with " + type_name());
3249 m_type = value_t::object;
3250 m_value.
object = create<object_t>();
3256 assert(m_value.object !=
nullptr);
3257 return m_value.object->operator[](key);
3261 throw std::domain_error(
"cannot use operator[] with " + type_name());
3297 assert(m_value.object !=
nullptr);
3298 assert(m_value.object->find(key) != m_value.object->end());
3299 return m_value.object->find(key)->second;
3303 throw std::domain_error(
"cannot use operator[] with " + type_name());
3334 template<
typename T, std::
size_t n>
3337 return operator[](static_cast<const T>(key));
3369 template<
typename T, std::
size_t n>
3372 return operator[](static_cast<const T>(key));
3402 template<
typename T>
3408 m_type = value_t::object;
3409 m_value = value_t::object;
3415 assert(m_value.object !=
nullptr);
3416 return m_value.object->operator[](key);
3420 throw std::domain_error(
"cannot use operator[] with " + type_name());
3451 template<
typename T>
3457 assert(m_value.object !=
nullptr);
3458 assert(m_value.object->find(key) != m_value.object->end());
3459 return m_value.object->find(key)->second;
3463 throw std::domain_error(
"cannot use operator[] with " + type_name());
3515 template <
class ValueType,
typename 3517 std::is_convertible<basic_json_t, ValueType>::value
3519 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3525 const auto it = find(key);
3532 return default_value;
3537 throw std::domain_error(
"cannot use value() with " + type_name());
3545 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3547 return value(key,
string_t(default_value));
3673 template <
class InteratorType,
typename 3675 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3676 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3682 if (
this != pos.m_object)
3684 throw std::domain_error(
"iterator does not fit current value");
3687 InteratorType result = end();
3691 case value_t::boolean:
3692 case value_t::number_float:
3693 case value_t::number_integer:
3694 case value_t::number_unsigned:
3695 case value_t::string:
3697 if (not pos.m_it.primitive_iterator.is_begin())
3699 throw std::out_of_range(
"iterator out of range");
3704 delete m_value.string;
3705 m_value.string =
nullptr;
3708 m_type = value_t::null;
3712 case value_t::object:
3714 assert(m_value.object !=
nullptr);
3715 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3719 case value_t::array:
3721 assert(m_value.array !=
nullptr);
3722 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3728 throw std::domain_error(
"cannot use erase() with " + type_name());
3779 template <
class InteratorType,
typename 3781 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3782 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3785 InteratorType
erase(InteratorType first, InteratorType last)
3788 if (
this != first.m_object or
this != last.m_object)
3790 throw std::domain_error(
"iterators do not fit current value");
3793 InteratorType result = end();
3797 case value_t::boolean:
3798 case value_t::number_float:
3799 case value_t::number_integer:
3800 case value_t::number_unsigned:
3801 case value_t::string:
3803 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3805 throw std::out_of_range(
"iterators out of range");
3810 delete m_value.string;
3811 m_value.string =
nullptr;
3814 m_type = value_t::null;
3818 case value_t::object:
3820 assert(m_value.object !=
nullptr);
3821 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3822 last.m_it.object_iterator);
3826 case value_t::array:
3828 assert(m_value.array !=
nullptr);
3829 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3830 last.m_it.array_iterator);
3836 throw std::domain_error(
"cannot use erase() with " + type_name());
3874 assert(m_value.object !=
nullptr);
3875 return m_value.object->erase(key);
3879 throw std::domain_error(
"cannot use erase() with " + type_name());
3914 throw std::out_of_range(
"index out of range");
3917 assert(m_value.array !=
nullptr);
3918 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3922 throw std::domain_error(
"cannot use erase() with " + type_name());
3945 auto result = end();
3949 assert(m_value.object !=
nullptr);
3950 result.m_it.object_iterator = m_value.object->find(key);
3962 auto result = cend();
3966 assert(m_value.object !=
nullptr);
3967 result.m_it.object_iterator = m_value.object->find(key);
3994 assert(not is_object() or m_value.object !=
nullptr);
3995 return is_object() ? m_value.object->count(key) : 0;
4283 template<
typename IteratorType>
class iteration_proxy;
4299 return iteration_proxy<iterator>(cont);
4307 return iteration_proxy<const_iterator>(cont);
4363 case value_t::array:
4365 assert(m_value.array !=
nullptr);
4366 return m_value.array->empty();
4369 case value_t::object:
4371 assert(m_value.object !=
nullptr);
4372 return m_value.object->empty();
4426 case value_t::array:
4428 assert(m_value.array !=
nullptr);
4429 return m_value.array->size();
4432 case value_t::object:
4434 assert(m_value.object !=
nullptr);
4435 return m_value.object->size();
4486 case value_t::array:
4488 assert(m_value.array !=
nullptr);
4489 return m_value.array->max_size();
4492 case value_t::object:
4494 assert(m_value.object !=
nullptr);
4495 return m_value.object->max_size();
4545 case value_t::number_integer:
4547 m_value.number_integer = 0;
4551 case value_t::number_unsigned:
4553 m_value.number_unsigned = 0;
4557 case value_t::number_float:
4559 m_value.number_float = 0.0;
4563 case value_t::boolean:
4565 m_value.boolean =
false;
4569 case value_t::string:
4571 assert(m_value.string !=
nullptr);
4572 m_value.string->clear();
4576 case value_t::array:
4578 assert(m_value.array !=
nullptr);
4579 m_value.array->clear();
4583 case value_t::object:
4585 assert(m_value.object !=
nullptr);
4586 m_value.object->clear();
4620 if (not(is_null() or is_array()))
4622 throw std::domain_error(
"cannot use push_back() with " + type_name());
4628 m_type = value_t::array;
4629 m_value = value_t::array;
4633 assert(m_value.array !=
nullptr);
4634 m_value.array->push_back(std::move(val));
4636 val.m_type = value_t::null;
4645 push_back(std::move(val));
4656 if (not(is_null() or is_array()))
4658 throw std::domain_error(
"cannot use push_back() with " + type_name());
4664 m_type = value_t::array;
4665 m_value = value_t::array;
4669 assert(m_value.array !=
nullptr);
4670 m_value.array->push_back(val);
4706 if (not(is_null() or is_object()))
4708 throw std::domain_error(
"cannot use push_back() with " + type_name());
4714 m_type = value_t::object;
4715 m_value = value_t::object;
4719 assert(m_value.object !=
nullptr);
4720 m_value.object->insert(val);
4730 return operator[](val.first);
4761 if (pos.m_object !=
this)
4763 throw std::domain_error(
"iterator does not fit current value");
4768 assert(m_value.array !=
nullptr);
4769 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4774 throw std::domain_error(
"cannot use insert() with " + type_name());
4784 return insert(pos, val);
4817 if (pos.m_object !=
this)
4819 throw std::domain_error(
"iterator does not fit current value");
4824 assert(m_value.array !=
nullptr);
4825 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4830 throw std::domain_error(
"cannot use insert() with " + type_name());
4869 throw std::domain_error(
"cannot use insert() with " + type_name());
4873 if (pos.m_object !=
this)
4875 throw std::domain_error(
"iterator does not fit current value");
4878 if (first.m_object != last.m_object)
4880 throw std::domain_error(
"iterators do not fit");
4883 if (first.m_object ==
this or last.m_object ==
this)
4885 throw std::domain_error(
"passed iterators may not belong to container");
4890 assert(m_value.array !=
nullptr);
4891 result.m_it.array_iterator = m_value.array->insert(
4892 pos.m_it.array_iterator,
4893 first.m_it.array_iterator,
4894 last.m_it.array_iterator);
4927 throw std::domain_error(
"cannot use insert() with " + type_name());
4931 if (pos.m_object !=
this)
4933 throw std::domain_error(
"iterator does not fit current value");
4938 assert(m_value.array !=
nullptr);
4939 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4961 std::is_nothrow_move_constructible<value_t>::value and
4962 std::is_nothrow_move_assignable<value_t>::value and
4963 std::is_nothrow_move_constructible<json_value>::value and
4964 std::is_nothrow_move_assignable<json_value>::value
4967 std::swap(m_type, other.m_type);
4968 std::swap(m_value, other.m_value);
4996 assert(m_value.array !=
nullptr);
4997 std::swap(*(m_value.array), other);
5001 throw std::domain_error(
"cannot use swap() with " + type_name());
5030 assert(m_value.object !=
nullptr);
5031 std::swap(*(m_value.object), other);
5035 throw std::domain_error(
"cannot use swap() with " + type_name());
5064 assert(m_value.string !=
nullptr);
5065 std::swap(*(m_value.string), other);
5069 throw std::domain_error(
"cannot use swap() with " + type_name());
5095 static constexpr std::array<uint8_t, 8> order = {{
5108 if (lhs == value_t::discarded or rhs == value_t::discarded)
5113 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5142 const auto lhs_type = lhs.type();
5143 const auto rhs_type = rhs.type();
5145 if (lhs_type == rhs_type)
5149 case value_t::array:
5151 assert(lhs.m_value.array !=
nullptr);
5152 assert(rhs.m_value.array !=
nullptr);
5153 return *lhs.m_value.array == *rhs.m_value.array;
5155 case value_t::object:
5157 assert(lhs.m_value.object !=
nullptr);
5158 assert(rhs.m_value.object !=
nullptr);
5159 return *lhs.m_value.object == *rhs.m_value.object;
5165 case value_t::string:
5167 assert(lhs.m_value.string !=
nullptr);
5168 assert(rhs.m_value.string !=
nullptr);
5169 return *lhs.m_value.string == *rhs.m_value.string;
5171 case value_t::boolean:
5173 return lhs.m_value.boolean == rhs.m_value.boolean;
5175 case value_t::number_integer:
5177 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5179 case value_t::number_unsigned:
5181 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5183 case value_t::number_float:
5185 return lhs.m_value.number_float == rhs.m_value.number_float;
5193 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5195 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5197 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5199 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5201 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5203 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5205 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5207 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5209 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5211 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5213 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5215 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5271 return not (lhs == rhs);
5303 return not v.is_null();
5332 const auto lhs_type = lhs.type();
5333 const auto rhs_type = rhs.type();
5335 if (lhs_type == rhs_type)
5339 case value_t::array:
5341 assert(lhs.m_value.array !=
nullptr);
5342 assert(rhs.m_value.array !=
nullptr);
5343 return *lhs.m_value.array < *rhs.m_value.array;
5345 case value_t::object:
5347 assert(lhs.m_value.object !=
nullptr);
5348 assert(rhs.m_value.object !=
nullptr);
5349 return *lhs.m_value.object < *rhs.m_value.object;
5355 case value_t::string:
5357 assert(lhs.m_value.string !=
nullptr);
5358 assert(rhs.m_value.string !=
nullptr);
5359 return *lhs.m_value.string < *rhs.m_value.string;
5361 case value_t::boolean:
5363 return lhs.m_value.boolean < rhs.m_value.boolean;
5365 case value_t::number_integer:
5367 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5369 case value_t::number_unsigned:
5371 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5373 case value_t::number_float:
5375 return lhs.m_value.number_float < rhs.m_value.number_float;
5383 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5385 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5387 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5389 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5391 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5393 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5395 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5397 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5399 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5401 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5403 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5405 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5411 return operator<(lhs_type, rhs_type);
5433 return not (rhs < lhs);
5455 return not (lhs <= rhs);
5477 return not (lhs < rhs);
5512 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5515 const bool pretty_print = (o.width() > 0);
5516 const auto indentation = (pretty_print ? o.width() : 0);
5522 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5530 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5571 return parser(s, cb).
parse();
5600 return parser(i, cb).
parse();
5608 return parser(i, cb).
parse();
5636 j = parser(i).
parse();
5646 j = parser(i).
parse();
5665 case value_t::object:
5667 case value_t::array:
5669 case value_t::string:
5671 case value_t::boolean:
5673 case value_t::discarded:
5688 static std::size_t extra_space(
const string_t& s) noexcept
5690 std::size_t result = 0;
5692 for (
const auto& c : s)
5711 if (c >= 0x00 and c <= 0x1f)
5739 const auto space = extra_space(s);
5746 string_t result(s.size() + space,
'\\');
5747 std::size_t pos = 0;
5749 for (
const auto& c : s)
5756 result[pos + 1] =
'"';
5772 result[pos + 1] =
'b';
5780 result[pos + 1] =
'f';
5788 result[pos + 1] =
'n';
5796 result[pos + 1] =
'r';
5804 result[pos + 1] =
't';
5811 if (c >= 0x00 and c <= 0x1f)
5815 auto hexify = [](
const char v) ->
char 5817 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5822 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5860 void dump(std::ostream& o,
5861 const bool pretty_print,
5862 const unsigned int indent_step,
5863 const unsigned int current_indent = 0)
const 5866 unsigned int new_indent = current_indent;
5870 case value_t::object:
5872 assert(m_value.object !=
nullptr);
5874 if (m_value.object->empty())
5885 new_indent += indent_step;
5889 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5891 if (i != m_value.object->cbegin())
5893 o << (pretty_print ?
",\n" :
",");
5895 o <<
string_t(new_indent,
' ') <<
"\"" 5896 << escape_string(i->first) <<
"\":" 5897 << (pretty_print ?
" " :
"");
5898 i->second.dump(o, pretty_print, indent_step, new_indent);
5904 new_indent -= indent_step;
5908 o <<
string_t(new_indent,
' ') +
"}";
5912 case value_t::array:
5914 assert(m_value.array !=
nullptr);
5916 if (m_value.array->empty())
5927 new_indent += indent_step;
5931 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5933 if (i != m_value.array->cbegin())
5935 o << (pretty_print ?
",\n" :
",");
5938 i->dump(o, pretty_print, indent_step, new_indent);
5944 new_indent -= indent_step;
5948 o <<
string_t(new_indent,
' ') <<
"]";
5952 case value_t::string:
5954 assert(m_value.string !=
nullptr);
5955 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5959 case value_t::boolean:
5961 o << (m_value.boolean ?
"true" :
"false");
5965 case value_t::number_integer:
5967 o << m_value.number_integer;
5971 case value_t::number_unsigned:
5973 o << m_value.number_unsigned;
5977 case value_t::number_float:
5985 if (std::fmod(m_value.number_float, 1) == 0)
5987 o << std::fixed << std::setprecision(1);
5992 o.unsetf(std::ios_base::floatfield);
5993 o << std::setprecision(std::numeric_limits<double>::digits10);
5995 o << m_value.number_float;
5999 case value_t::discarded:
6019 value_t m_type = value_t::null;
6022 json_value m_value = {};
6039 class primitive_iterator_t
6055 bool is_begin()
const 6057 return (m_it == begin_value);
6063 return (m_it == end_value);
6083 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6093 struct internal_iterator
6096 typename object_t::iterator object_iterator;
6098 typename array_t::iterator array_iterator;
6100 primitive_iterator_t primitive_iterator;
6104 : object_iterator(), array_iterator(), primitive_iterator()
6109 template<
typename IteratorType>
6110 class iteration_proxy
6114 class iteration_proxy_internal
6118 IteratorType anchor;
6120 size_t array_index = 0;
6123 iteration_proxy_internal(IteratorType it)
6128 iteration_proxy_internal& operator*()
6134 iteration_proxy_internal& operator++()
6143 bool operator!= (
const iteration_proxy_internal& o)
const 6145 return anchor != o.anchor;
6151 assert(anchor.m_object !=
nullptr);
6153 switch (anchor.m_object->type())
6156 case value_t::array:
6158 return std::to_string(array_index);
6162 case value_t::object:
6164 return anchor.key();
6176 typename IteratorType::reference value()
const 6178 return anchor.value();
6183 typename IteratorType::reference container;
6187 iteration_proxy(
typename IteratorType::reference cont)
6192 iteration_proxy_internal begin()
6194 return iteration_proxy_internal(container.begin());
6198 iteration_proxy_internal end()
6200 return iteration_proxy_internal(container.end());
6218 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6221 friend class basic_json;
6241 assert(m_object !=
nullptr);
6243 switch (m_object->m_type)
6247 m_it.object_iterator =
typename object_t::iterator();
6253 m_it.array_iterator =
typename array_t::iterator();
6259 m_it.primitive_iterator = primitive_iterator_t();
6268 assert(m_object !=
nullptr);
6270 switch (m_object->m_type)
6274 m_it.object_iterator = other.m_it.object_iterator;
6280 m_it.array_iterator = other.m_it.array_iterator;
6286 m_it.primitive_iterator = other.m_it.primitive_iterator;
6294 : m_object(other.m_object), m_it(other.m_it)
6299 std::is_nothrow_move_constructible<pointer>::value and
6300 std::is_nothrow_move_assignable<pointer>::value and
6301 std::is_nothrow_move_constructible<internal_iterator>::value and
6302 std::is_nothrow_move_assignable<internal_iterator>::value
6305 std::swap(m_object, other.m_object);
6306 std::swap(m_it, other.m_it);
6314 assert(m_object !=
nullptr);
6316 switch (m_object->m_type)
6320 assert(m_object->m_value.object !=
nullptr);
6321 m_it.object_iterator = m_object->m_value.object->begin();
6327 assert(m_object->m_value.array !=
nullptr);
6328 m_it.array_iterator = m_object->m_value.array->begin();
6335 m_it.primitive_iterator.set_end();
6341 m_it.primitive_iterator.set_begin();
6350 assert(m_object !=
nullptr);
6352 switch (m_object->m_type)
6356 assert(m_object->m_value.object !=
nullptr);
6357 m_it.object_iterator = m_object->m_value.object->end();
6363 assert(m_object->m_value.array !=
nullptr);
6364 m_it.array_iterator = m_object->m_value.array->end();
6370 m_it.primitive_iterator.set_end();
6380 assert(m_object !=
nullptr);
6382 switch (m_object->m_type)
6386 assert(m_object->m_value.object);
6387 assert(m_it.object_iterator != m_object->m_value.object->end());
6388 return m_it.object_iterator->second;
6393 assert(m_object->m_value.array);
6394 assert(m_it.array_iterator != m_object->m_value.array->end());
6395 return *m_it.array_iterator;
6400 throw std::out_of_range(
"cannot get value");
6405 if (m_it.primitive_iterator.is_begin())
6411 throw std::out_of_range(
"cannot get value");
6420 assert(m_object !=
nullptr);
6422 switch (m_object->m_type)
6426 assert(m_object->m_value.object);
6427 assert(m_it.object_iterator != m_object->m_value.object->end());
6428 return &(m_it.object_iterator->second);
6433 assert(m_object->m_value.array);
6434 assert(m_it.array_iterator != m_object->m_value.array->end());
6435 return &*m_it.array_iterator;
6440 if (m_it.primitive_iterator.is_begin())
6446 throw std::out_of_range(
"cannot get value");
6455 auto result = *
this;
6463 assert(m_object !=
nullptr);
6465 switch (m_object->m_type)
6469 ++m_it.object_iterator;
6475 ++m_it.array_iterator;
6481 ++m_it.primitive_iterator;
6492 auto result = *
this;
6500 assert(m_object !=
nullptr);
6502 switch (m_object->m_type)
6506 --m_it.object_iterator;
6512 --m_it.array_iterator;
6518 --m_it.primitive_iterator;
6530 if (m_object != other.m_object)
6532 throw std::domain_error(
"cannot compare iterators of different containers");
6535 assert(m_object !=
nullptr);
6537 switch (m_object->m_type)
6541 return (m_it.object_iterator == other.m_it.object_iterator);
6546 return (m_it.array_iterator == other.m_it.array_iterator);
6551 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6559 return not operator==(other);
6566 if (m_object != other.m_object)
6568 throw std::domain_error(
"cannot compare iterators of different containers");
6571 assert(m_object !=
nullptr);
6573 switch (m_object->m_type)
6577 throw std::domain_error(
"cannot compare order of object iterators");
6582 return (m_it.array_iterator < other.m_it.array_iterator);
6587 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6595 return not other.operator < (*this);
6601 return not operator<=(other);
6607 return not operator<(other);
6613 assert(m_object !=
nullptr);
6615 switch (m_object->m_type)
6619 throw std::domain_error(
"cannot use offsets with object iterators");
6624 m_it.array_iterator += i;
6630 m_it.primitive_iterator += i;
6641 return operator+=(-i);
6647 auto result = *
this;
6655 auto result = *
this;
6663 assert(m_object !=
nullptr);
6665 switch (m_object->m_type)
6669 throw std::domain_error(
"cannot use offsets with object iterators");
6674 return m_it.array_iterator - other.m_it.array_iterator;
6679 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6687 assert(m_object !=
nullptr);
6689 switch (m_object->m_type)
6693 throw std::domain_error(
"cannot use operator[] for object iterators");
6698 return *(m_it.array_iterator + n);
6703 throw std::out_of_range(
"cannot get value");
6708 if (m_it.primitive_iterator == -n)
6714 throw std::out_of_range(
"cannot get value");
6721 typename object_t::key_type
key()
const 6723 assert(m_object !=
nullptr);
6725 if (m_object->is_object())
6727 return m_it.object_iterator->first;
6731 throw std::domain_error(
"cannot use key() for non-object iterators");
6745 internal_iterator m_it = internal_iterator();
6782 std::is_nothrow_move_constructible<pointer>::value and
6783 std::is_nothrow_move_assignable<pointer>::value and
6784 std::is_nothrow_move_constructible<internal_iterator>::value and
6785 std::is_nothrow_move_assignable<internal_iterator>::value
6788 base_iterator::operator=(other);
6795 return const_cast<reference>(base_iterator::operator*());
6801 return const_cast<pointer>(base_iterator::operator->());
6808 base_iterator::operator++();
6815 base_iterator::operator++();
6823 base_iterator::operator--();
6830 base_iterator::operator--();
6837 base_iterator::operator+=(i);
6844 base_iterator::operator-=(i);
6851 auto result = *
this;
6859 auto result = *
this;
6867 return base_iterator::operator-(other);
6873 return const_cast<reference>(base_iterator::operator[](n));
6879 return const_cast<reference>(base_iterator::value());
6900 template<
typename Base>
6922 return base_iterator::operator++(1);
6928 base_iterator::operator++();
6935 return base_iterator::operator--(1);
6941 base_iterator::operator--();
6948 base_iterator::operator+=(i);
6955 auto result = *
this;
6963 auto result = *
this;
6971 return this->base() - other.base();
6977 return *(this->operator+(n));
6981 typename object_t::key_type
key()
const 6983 auto it = --this->base();
6990 auto it = --this->base();
6991 return it.operator * ();
7012 enum class token_type
7031 using lexer_char_t =
unsigned char;
7034 explicit lexer(
const string_t& s) noexcept
7035 : m_stream(
nullptr), m_buffer(s)
7037 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7038 assert(m_content !=
nullptr);
7039 m_start = m_cursor = m_content;
7040 m_limit = m_content + s.size();
7044 explicit lexer(std::istream* s) noexcept
7045 : m_stream(s), m_buffer()
7047 assert(m_stream !=
nullptr);
7048 getline(*m_stream, m_buffer);
7049 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7050 assert(m_content !=
nullptr);
7051 m_start = m_cursor = m_content;
7052 m_limit = m_content + m_buffer.size();
7059 lexer(
const lexer&) =
delete;
7060 lexer operator=(
const lexer&) =
delete;
7077 static string_t to_unicode(
const std::size_t codepoint1,
7078 const std::size_t codepoint2 = 0)
7081 std::size_t codepoint = codepoint1;
7084 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7087 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7101 throw std::invalid_argument(
"missing or wrong low surrogate");
7107 if (codepoint < 0x80)
7110 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7112 else if (codepoint <= 0x7ff)
7115 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7116 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7118 else if (codepoint <= 0xffff)
7121 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7122 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7123 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7125 else if (codepoint <= 0x10ffff)
7128 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7129 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7130 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7131 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7135 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7142 static std::string token_type_name(token_type t)
7146 case token_type::uninitialized:
7147 return "<uninitialized>";
7148 case token_type::literal_true:
7149 return "true literal";
7150 case token_type::literal_false:
7151 return "false literal";
7152 case token_type::literal_null:
7153 return "null literal";
7154 case token_type::value_string:
7155 return "string literal";
7156 case token_type::value_number:
7157 return "number literal";
7158 case token_type::begin_array:
7160 case token_type::begin_object:
7162 case token_type::end_array:
7164 case token_type::end_object:
7166 case token_type::name_separator:
7168 case token_type::value_separator:
7170 case token_type::parse_error:
7171 return "<parse error>";
7172 case token_type::end_of_input:
7173 return "end of input";
7177 return "unknown token";
7192 token_type scan() noexcept
7199 assert(m_start !=
nullptr);
7204 unsigned int yyaccept = 0;
7205 static const unsigned char yybm[] =
7207 0, 0, 0, 0, 0, 0, 0, 0,
7208 0, 32, 32, 0, 0, 32, 0, 0,
7209 128, 128, 128, 128, 128, 128, 128, 128,
7210 128, 128, 128, 128, 128, 128, 128, 128,
7211 160, 128, 0, 128, 128, 128, 128, 128,
7212 128, 128, 128, 128, 128, 128, 128, 128,
7213 192, 192, 192, 192, 192, 192, 192, 192,
7214 192, 192, 128, 128, 128, 128, 128, 128,
7215 128, 128, 128, 128, 128, 128, 128, 128,
7216 128, 128, 128, 128, 128, 128, 128, 128,
7217 128, 128, 128, 128, 128, 128, 128, 128,
7218 128, 128, 128, 128, 0, 128, 128, 128,
7219 128, 128, 128, 128, 128, 128, 128, 128,
7220 128, 128, 128, 128, 128, 128, 128, 128,
7221 128, 128, 128, 128, 128, 128, 128, 128,
7222 128, 128, 128, 128, 128, 128, 128, 128,
7223 128, 128, 128, 128, 128, 128, 128, 128,
7224 128, 128, 128, 128, 128, 128, 128, 128,
7225 128, 128, 128, 128, 128, 128, 128, 128,
7226 128, 128, 128, 128, 128, 128, 128, 128,
7227 128, 128, 128, 128, 128, 128, 128, 128,
7228 128, 128, 128, 128, 128, 128, 128, 128,
7229 128, 128, 128, 128, 128, 128, 128, 128,
7230 128, 128, 128, 128, 128, 128, 128, 128,
7231 128, 128, 128, 128, 128, 128, 128, 128,
7232 128, 128, 128, 128, 128, 128, 128, 128,
7233 128, 128, 128, 128, 128, 128, 128, 128,
7234 128, 128, 128, 128, 128, 128, 128, 128,
7235 128, 128, 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,
7240 if ((m_limit - m_cursor) < 5)
7245 if (yybm[0 + yych] & 32)
7247 goto basic_json_parser_6;
7257 goto basic_json_parser_2;
7261 goto basic_json_parser_4;
7263 goto basic_json_parser_9;
7269 goto basic_json_parser_4;
7273 goto basic_json_parser_10;
7275 goto basic_json_parser_12;
7284 goto basic_json_parser_4;
7288 goto basic_json_parser_13;
7290 goto basic_json_parser_15;
7296 goto basic_json_parser_17;
7300 goto basic_json_parser_19;
7302 goto basic_json_parser_4;
7314 goto basic_json_parser_21;
7318 goto basic_json_parser_4;
7320 goto basic_json_parser_23;
7326 goto basic_json_parser_24;
7330 goto basic_json_parser_4;
7332 goto basic_json_parser_25;
7341 goto basic_json_parser_26;
7343 goto basic_json_parser_4;
7349 goto basic_json_parser_28;
7353 goto basic_json_parser_30;
7355 goto basic_json_parser_4;
7359 basic_json_parser_2:
7362 return token_type::end_of_input;
7364 basic_json_parser_4:
7366 basic_json_parser_5:
7368 return token_type::parse_error;
7370 basic_json_parser_6:
7372 if (m_limit <= m_cursor)
7377 if (yybm[0 + yych] & 32)
7379 goto basic_json_parser_6;
7384 basic_json_parser_9:
7386 yych = *(m_marker = ++m_cursor);
7389 goto basic_json_parser_5;
7391 goto basic_json_parser_32;
7392 basic_json_parser_10:
7395 return token_type::value_separator;
7397 basic_json_parser_12:
7401 goto basic_json_parser_5;
7405 goto basic_json_parser_13;
7409 goto basic_json_parser_15;
7411 goto basic_json_parser_5;
7412 basic_json_parser_13:
7414 yych = *(m_marker = ++m_cursor);
7419 goto basic_json_parser_37;
7426 goto basic_json_parser_38;
7430 goto basic_json_parser_38;
7433 basic_json_parser_14:
7435 return token_type::value_number;
7437 basic_json_parser_15:
7439 m_marker = ++m_cursor;
7440 if ((m_limit - m_cursor) < 3)
7445 if (yybm[0 + yych] & 64)
7447 goto basic_json_parser_15;
7453 goto basic_json_parser_37;
7455 goto basic_json_parser_14;
7461 goto basic_json_parser_38;
7465 goto basic_json_parser_38;
7467 goto basic_json_parser_14;
7469 basic_json_parser_17:
7472 return token_type::name_separator;
7474 basic_json_parser_19:
7477 return token_type::begin_array;
7479 basic_json_parser_21:
7482 return token_type::end_array;
7484 basic_json_parser_23:
7486 yych = *(m_marker = ++m_cursor);
7489 goto basic_json_parser_39;
7491 goto basic_json_parser_5;
7492 basic_json_parser_24:
7494 yych = *(m_marker = ++m_cursor);
7497 goto basic_json_parser_40;
7499 goto basic_json_parser_5;
7500 basic_json_parser_25:
7502 yych = *(m_marker = ++m_cursor);
7505 goto basic_json_parser_41;
7507 goto basic_json_parser_5;
7508 basic_json_parser_26:
7511 return token_type::begin_object;
7513 basic_json_parser_28:
7516 return token_type::end_object;
7518 basic_json_parser_30:
7520 yych = *(m_marker = ++m_cursor);
7523 goto basic_json_parser_42;
7525 goto basic_json_parser_5;
7526 basic_json_parser_31:
7528 if (m_limit <= m_cursor)
7533 basic_json_parser_32:
7534 if (yybm[0 + yych] & 128)
7536 goto basic_json_parser_31;
7540 goto basic_json_parser_33;
7544 goto basic_json_parser_34;
7546 goto basic_json_parser_36;
7547 basic_json_parser_33:
7548 m_cursor = m_marker;
7551 goto basic_json_parser_5;
7555 goto basic_json_parser_14;
7557 basic_json_parser_34:
7560 return token_type::value_string;
7562 basic_json_parser_36:
7564 if (m_limit <= m_cursor)
7575 goto basic_json_parser_31;
7579 goto basic_json_parser_33;
7581 goto basic_json_parser_31;
7589 goto basic_json_parser_33;
7591 goto basic_json_parser_31;
7597 goto basic_json_parser_31;
7599 goto basic_json_parser_33;
7609 goto basic_json_parser_31;
7613 goto basic_json_parser_31;
7615 goto basic_json_parser_33;
7623 goto basic_json_parser_31;
7625 goto basic_json_parser_33;
7631 goto basic_json_parser_31;
7635 goto basic_json_parser_43;
7637 goto basic_json_parser_33;
7641 basic_json_parser_37:
7645 goto basic_json_parser_33;
7649 goto basic_json_parser_44;
7651 goto basic_json_parser_33;
7652 basic_json_parser_38:
7658 goto basic_json_parser_46;
7660 goto basic_json_parser_33;
7666 goto basic_json_parser_46;
7670 goto basic_json_parser_33;
7674 goto basic_json_parser_47;
7676 goto basic_json_parser_33;
7678 basic_json_parser_39:
7682 goto basic_json_parser_49;
7684 goto basic_json_parser_33;
7685 basic_json_parser_40:
7689 goto basic_json_parser_50;
7691 goto basic_json_parser_33;
7692 basic_json_parser_41:
7696 goto basic_json_parser_51;
7698 goto basic_json_parser_33;
7699 basic_json_parser_42:
7703 goto basic_json_parser_52;
7705 goto basic_json_parser_33;
7706 basic_json_parser_43:
7708 if (m_limit <= m_cursor)
7717 goto basic_json_parser_33;
7721 goto basic_json_parser_54;
7723 goto basic_json_parser_33;
7729 goto basic_json_parser_54;
7733 goto basic_json_parser_33;
7737 goto basic_json_parser_54;
7739 goto basic_json_parser_33;
7741 basic_json_parser_44:
7743 m_marker = ++m_cursor;
7744 if ((m_limit - m_cursor) < 3)
7753 goto basic_json_parser_14;
7757 goto basic_json_parser_44;
7759 goto basic_json_parser_14;
7765 goto basic_json_parser_38;
7769 goto basic_json_parser_38;
7771 goto basic_json_parser_14;
7773 basic_json_parser_46:
7777 goto basic_json_parser_33;
7781 goto basic_json_parser_33;
7783 basic_json_parser_47:
7785 if (m_limit <= m_cursor)
7792 goto basic_json_parser_14;
7796 goto basic_json_parser_47;
7798 goto basic_json_parser_14;
7799 basic_json_parser_49:
7803 goto basic_json_parser_55;
7805 goto basic_json_parser_33;
7806 basic_json_parser_50:
7810 goto basic_json_parser_56;
7812 goto basic_json_parser_33;
7813 basic_json_parser_51:
7817 goto basic_json_parser_58;
7819 goto basic_json_parser_33;
7820 basic_json_parser_52:
7825 basic_json_parser_54:
7827 if (m_limit <= m_cursor)
7836 goto basic_json_parser_33;
7840 goto basic_json_parser_60;
7842 goto basic_json_parser_33;
7848 goto basic_json_parser_60;
7852 goto basic_json_parser_33;
7856 goto basic_json_parser_60;
7858 goto basic_json_parser_33;
7860 basic_json_parser_55:
7864 goto basic_json_parser_61;
7866 goto basic_json_parser_33;
7867 basic_json_parser_56:
7870 return token_type::literal_null;
7872 basic_json_parser_58:
7875 return token_type::literal_true;
7877 basic_json_parser_60:
7879 if (m_limit <= m_cursor)
7888 goto basic_json_parser_33;
7892 goto basic_json_parser_63;
7894 goto basic_json_parser_33;
7900 goto basic_json_parser_63;
7904 goto basic_json_parser_33;
7908 goto basic_json_parser_63;
7910 goto basic_json_parser_33;
7912 basic_json_parser_61:
7915 return token_type::literal_false;
7917 basic_json_parser_63:
7919 if (m_limit <= m_cursor)
7928 goto basic_json_parser_33;
7932 goto basic_json_parser_31;
7934 goto basic_json_parser_33;
7940 goto basic_json_parser_31;
7944 goto basic_json_parser_33;
7948 goto basic_json_parser_31;
7950 goto basic_json_parser_33;
7958 void yyfill() noexcept
7960 if (m_stream ==
nullptr or not * m_stream)
7965 const ssize_t offset_start = m_start - m_content;
7966 const ssize_t offset_marker = m_marker - m_start;
7967 const ssize_t offset_cursor = m_cursor - m_start;
7969 m_buffer.erase(0, static_cast<size_t>(offset_start));
7971 assert(m_stream !=
nullptr);
7972 std::getline(*m_stream, line);
7973 m_buffer +=
"\n" + line;
7975 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7976 assert(m_content !=
nullptr);
7977 m_start = m_content;
7978 m_marker = m_start + offset_marker;
7979 m_cursor = m_start + offset_cursor;
7980 m_limit = m_start + m_buffer.size() - 1;
7984 string_t get_token()
const noexcept
7986 assert(m_start !=
nullptr);
7987 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7988 static_cast<size_t>(m_cursor - m_start));
8015 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8018 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8074 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8075 4).c_str(),
nullptr, 16);
8078 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8081 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8083 throw std::invalid_argument(
"missing low surrogate");
8087 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8088 (i + 7), 4).c_str(),
nullptr, 16);
8089 result += to_unicode(codepoint, codepoint2);
8096 result += to_unicode(codepoint);
8108 result.append(1, static_cast<typename string_t::value_type>(*i));
8135 long double str_to_float_t(
long double* ,
char** endptr)
const 8137 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8155 double str_to_float_t(
double* ,
char** endptr)
const 8157 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8175 float str_to_float_t(
float* ,
char** endptr)
const 8177 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8192 template <
typename T_A,
typename T_B>
8193 bool attempt_cast(T_A source, T_B& dest)
const 8195 dest =
static_cast<T_B
>(source);
8196 return (source == static_cast<T_A>(dest));
8237 void get_number(basic_json& result)
const 8239 typename string_t::value_type* endptr;
8240 assert(m_start !=
nullptr);
8245 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8249 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8250 10), result.m_value.number_unsigned))
8252 result.m_type = value_t::number_unsigned;
8257 result.m_type = value_t::number_float;
8264 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8265 10), result.m_value.number_integer))
8267 result.m_type = value_t::number_integer;
8272 result.m_type = value_t::number_float;
8278 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8280 result.m_type = value_t::number_float;
8283 if (result.m_type == value_t::number_float)
8290 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8293 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8295 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8302 std::istream* m_stream =
nullptr;
8306 const lexer_char_t* m_content =
nullptr;
8308 const lexer_char_t* m_start =
nullptr;
8310 const lexer_char_t* m_marker =
nullptr;
8312 const lexer_char_t* m_cursor =
nullptr;
8314 const lexer_char_t* m_limit =
nullptr;
8327 : callback(cb), m_lexer(s)
8335 : callback(cb), m_lexer(&_is)
8344 basic_json result = parse_internal(
true);
8346 expect(lexer::token_type::end_of_input);
8355 basic_json parse_internal(
bool keep)
8357 auto result = basic_json(value_t::discarded);
8361 case lexer::token_type::begin_object:
8363 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8366 result.m_type = value_t::object;
8367 result.m_value = json_value(value_t::object);
8374 if (last_token == lexer::token_type::end_object)
8377 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8379 result = basic_json(value_t::discarded);
8385 unexpect(lexer::token_type::value_separator);
8391 if (last_token == lexer::token_type::value_separator)
8397 expect(lexer::token_type::value_string);
8398 const auto key = m_lexer.get_string();
8400 bool keep_tag =
false;
8406 keep_tag = callback(depth, parse_event_t::key, k);
8416 expect(lexer::token_type::name_separator);
8420 auto value = parse_internal(keep);
8421 if (keep and keep_tag and not value.is_discarded())
8423 result[key] = std::move(value);
8426 while (last_token == lexer::token_type::value_separator);
8429 expect(lexer::token_type::end_object);
8431 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8433 result = basic_json(value_t::discarded);
8439 case lexer::token_type::begin_array:
8441 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8444 result.m_type = value_t::array;
8445 result.m_value = json_value(value_t::array);
8452 if (last_token == lexer::token_type::end_array)
8455 if (callback and not callback(--depth, parse_event_t::array_end, result))
8457 result = basic_json(value_t::discarded);
8463 unexpect(lexer::token_type::value_separator);
8469 if (last_token == lexer::token_type::value_separator)
8475 auto value = parse_internal(keep);
8476 if (keep and not value.is_discarded())
8478 result.push_back(std::move(value));
8481 while (last_token == lexer::token_type::value_separator);
8484 expect(lexer::token_type::end_array);
8486 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8488 result = basic_json(value_t::discarded);
8494 case lexer::token_type::literal_null:
8497 result.m_type = value_t::null;
8501 case lexer::token_type::value_string:
8503 const auto s = m_lexer.get_string();
8505 result = basic_json(s);
8509 case lexer::token_type::literal_true:
8512 result.m_type = value_t::boolean;
8513 result.m_value =
true;
8517 case lexer::token_type::literal_false:
8520 result.m_type = value_t::boolean;
8521 result.m_value =
false;
8525 case lexer::token_type::value_number:
8527 m_lexer.get_number(result);
8535 unexpect(last_token);
8539 if (keep and callback and not callback(depth, parse_event_t::value, result))
8541 result = basic_json(value_t::discarded);
8547 typename lexer::token_type get_token()
8549 last_token = m_lexer.scan();
8553 void expect(
typename lexer::token_type t)
const 8555 if (t != last_token)
8557 std::string error_msg =
"parse error - unexpected ";
8558 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8559 lexer::token_type_name(last_token));
8560 error_msg +=
"; expected " + lexer::token_type_name(t);
8561 throw std::invalid_argument(error_msg);
8565 void unexpect(
typename lexer::token_type t)
const 8567 if (t == last_token)
8569 std::string error_msg =
"parse error - unexpected ";
8570 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8571 lexer::token_type_name(last_token));
8572 throw std::invalid_argument(error_msg);
8582 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8620 is_nothrow_move_constructible<nlohmann::json>::value and
8621 is_nothrow_move_assignable<nlohmann::json>::value
8639 const auto& h = hash<nlohmann::json::string_t>();
8657 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8663 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8664 #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.