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)
968 basic_json() noexcept =
default;
1013 : m_type(
value_t::object), m_value(val)
1039 template <
class CompatibleObjectType,
typename 1041 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1042 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
1049 m_value.object = create<object_t>(begin(val), end(val));
1072 : m_type(
value_t::array), m_value(val)
1098 template <
class CompatibleArrayType,
typename 1100 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1101 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1102 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1103 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1104 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1105 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1106 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1113 m_value.array = create<array_t>(begin(val), end(val));
1138 : m_type(
value_t::string), m_value(val)
1188 template <
class CompatibleStringType,
typename 1190 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1211 : m_type(
value_t::boolean), m_value(val)
1239 template<
typename T,
1240 typename std::enable_if<
1241 not (std::is_same<T, int>::value)
1242 and std::is_same<T, number_integer_t>::value
1246 : m_type(
value_t::number_integer), m_value(val)
1275 : m_type(
value_t::number_integer),
1304 template<
typename CompatibleNumberIntegerType,
typename 1306 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1307 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1308 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1309 CompatibleNumberIntegerType>::type
1312 : m_type(value_t::number_integer),
1313 m_value(static_cast<number_integer_t>(val))
1333 template<
typename T,
1334 typename std::enable_if<
1335 not (std::is_same<T, int>::value)
1336 and std::is_same<T, number_unsigned_t>::value
1340 : m_type(
value_t::number_unsigned), m_value(val)
1363 template <
typename CompatibleNumberUnsignedType,
typename 1365 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1366 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1367 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1368 CompatibleNumberUnsignedType >::type
1371 : m_type(value_t::number_unsigned),
1372 m_value(static_cast<number_unsigned_t>(val))
1400 : m_type(
value_t::number_float), m_value(val)
1403 if (not std::isfinite(val))
1405 m_type = value_t::null;
1406 m_value = json_value();
1440 template<
typename CompatibleNumberFloatType,
typename =
typename 1442 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1443 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1519 bool type_deduction =
true,
1520 value_t manual_type = value_t::array)
1523 bool is_an_object =
true;
1527 for (
const auto& element : init)
1529 if (not element.is_array() or element.size() != 2
1530 or not element[0].is_string())
1534 is_an_object =
false;
1540 if (not type_deduction)
1543 if (manual_type == value_t::array)
1545 is_an_object =
false;
1549 if (manual_type == value_t::object and not is_an_object)
1551 throw std::domain_error(
"cannot create object from initializer list");
1558 m_type = value_t::object;
1559 m_value = value_t::object;
1561 assert(m_value.object !=
nullptr);
1563 for (
auto& element : init)
1565 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1571 m_type = value_t::array;
1572 m_value.array = create<array_t>(std::move(init));
1610 static basic_json
array(std::initializer_list<basic_json> init =
1611 std::initializer_list<basic_json>())
1613 return basic_json(init,
false, value_t::array);
1650 static basic_json
object(std::initializer_list<basic_json> init =
1651 std::initializer_list<basic_json>())
1653 return basic_json(init,
false, value_t::object);
1677 m_value.array = create<array_t>(cnt, val);
1714 template <
class InputIT,
typename 1716 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1717 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1720 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1723 if (first.m_object != last.m_object)
1725 throw std::domain_error(
"iterators are not compatible");
1731 case value_t::boolean:
1732 case value_t::number_float:
1733 case value_t::number_integer:
1734 case value_t::number_unsigned:
1735 case value_t::string:
1737 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1739 throw std::out_of_range(
"iterators out of range");
1752 case value_t::number_integer:
1754 assert(first.m_object !=
nullptr);
1755 m_value.number_integer = first.m_object->m_value.number_integer;
1759 case value_t::number_unsigned:
1761 assert(first.m_object !=
nullptr);
1762 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1766 case value_t::number_float:
1768 assert(first.m_object !=
nullptr);
1769 m_value.number_float = first.m_object->m_value.number_float;
1773 case value_t::boolean:
1775 assert(first.m_object !=
nullptr);
1776 m_value.boolean = first.m_object->m_value.boolean;
1780 case value_t::string:
1782 assert(first.m_object !=
nullptr);
1783 m_value = *first.m_object->m_value.string;
1787 case value_t::object:
1789 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1793 case value_t::array:
1795 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1801 assert(first.m_object !=
nullptr);
1802 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1832 : m_type(other.m_type)
1836 case value_t::object:
1838 assert(other.m_value.object !=
nullptr);
1839 m_value = *other.m_value.object;
1843 case value_t::array:
1845 assert(other.m_value.array !=
nullptr);
1846 m_value = *other.m_value.array;
1850 case value_t::string:
1852 assert(other.m_value.string !=
nullptr);
1853 m_value = *other.m_value.string;
1857 case value_t::boolean:
1859 m_value = other.m_value.boolean;
1863 case value_t::number_integer:
1865 m_value = other.m_value.number_integer;
1869 case value_t::number_unsigned:
1871 m_value = other.m_value.number_unsigned;
1875 case value_t::number_float:
1877 m_value = other.m_value.number_float;
1907 : m_type(
std::move(other.m_type)),
1908 m_value(
std::move(other.m_value))
1911 other.m_type = value_t::null;
1937 std::is_nothrow_move_constructible<value_t>::value and
1938 std::is_nothrow_move_assignable<value_t>::value and
1939 std::is_nothrow_move_constructible<json_value>::value and
1940 std::is_nothrow_move_assignable<json_value>::value
1944 swap(m_type, other.m_type);
1945 swap(m_value, other.m_value);
1966 case value_t::object:
1968 AllocatorType<object_t> alloc;
1969 alloc.destroy(m_value.object);
1970 alloc.deallocate(m_value.object, 1);
1974 case value_t::array:
1976 AllocatorType<array_t> alloc;
1977 alloc.destroy(m_value.array);
1978 alloc.deallocate(m_value.array, 1);
1982 case value_t::string:
1984 AllocatorType<string_t> alloc;
1985 alloc.destroy(m_value.string);
1986 alloc.deallocate(m_value.string, 1);
2033 std::stringstream ss;
2037 dump(ss,
true, static_cast<unsigned int>(indent));
2085 return is_null() or is_string() or is_boolean() or is_number();
2105 return is_array() or is_object();
2124 return m_type == value_t::null;
2143 return m_type == value_t::boolean;
2170 return is_number_integer() or is_number_float();
2196 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2221 return m_type == value_t::number_unsigned;
2246 return m_type == value_t::number_float;
2265 return m_type == value_t::object;
2284 return m_type == value_t::array;
2303 return m_type == value_t::string;
2327 return m_type == value_t::discarded;
2358 template <
class T,
typename 2360 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2361 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2363 T get_impl(T*)
const 2367 assert(m_value.object !=
nullptr);
2368 return T(m_value.object->begin(), m_value.object->end());
2372 throw std::domain_error(
"type must be object, but is " + type_name());
2381 assert(m_value.object !=
nullptr);
2382 return *(m_value.object);
2386 throw std::domain_error(
"type must be object, but is " + type_name());
2391 template <
class T,
typename 2393 std::is_convertible<basic_json_t, typename T::value_type>::value and
2394 not std::is_same<basic_json_t, typename T::value_type>::value and
2395 not std::is_arithmetic<T>::value and
2396 not std::is_convertible<std::string, T>::value and
2397 not has_mapped_type<T>::value
2399 T get_impl(T*)
const 2404 assert(m_value.array !=
nullptr);
2405 std::transform(m_value.array->begin(), m_value.array->end(),
2406 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2408 return i.
get<
typename T::value_type>();
2414 throw std::domain_error(
"type must be array, but is " + type_name());
2419 template <
class T,
typename 2421 std::is_convertible<basic_json_t, T>::value and
2422 not std::is_same<basic_json_t, T>::value
2424 std::vector<T> get_impl(std::vector<T>*)
const 2428 std::vector<T> to_vector;
2429 assert(m_value.array !=
nullptr);
2430 to_vector.reserve(m_value.array->size());
2431 std::transform(m_value.array->begin(), m_value.array->end(),
2432 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2440 throw std::domain_error(
"type must be array, but is " + type_name());
2445 template <
class T,
typename 2447 std::is_same<basic_json, typename T::value_type>::value and
2448 not has_mapped_type<T>::value
2450 T get_impl(T*)
const 2454 assert(m_value.array !=
nullptr);
2455 return T(m_value.array->begin(), m_value.array->end());
2459 throw std::domain_error(
"type must be array, but is " + type_name());
2468 assert(m_value.array !=
nullptr);
2469 return *(m_value.array);
2473 throw std::domain_error(
"type must be array, but is " + type_name());
2478 template <
typename T,
typename 2480 std::is_convertible<string_t, T>::value
2482 T get_impl(T*)
const 2486 assert(m_value.string !=
nullptr);
2487 return *m_value.string;
2491 throw std::domain_error(
"type must be string, but is " + type_name());
2496 template<
typename T,
typename 2498 std::is_arithmetic<T>::value
2500 T get_impl(T*)
const 2504 case value_t::number_integer:
2506 return static_cast<T
>(m_value.number_integer);
2509 case value_t::number_unsigned:
2511 return static_cast<T
>(m_value.number_unsigned);
2514 case value_t::number_float:
2516 return static_cast<T
>(m_value.number_float);
2521 throw std::domain_error(
"type must be number, but is " + type_name());
2531 return m_value.boolean;
2535 throw std::domain_error(
"type must be boolean, but is " + type_name());
2542 return is_object() ? m_value.object :
nullptr;
2548 return is_object() ? m_value.object :
nullptr;
2554 return is_array() ? m_value.array :
nullptr;
2560 return is_array() ? m_value.array :
nullptr;
2566 return is_string() ? m_value.string :
nullptr;
2572 return is_string() ? m_value.string :
nullptr;
2578 return is_boolean() ? &m_value.boolean :
nullptr;
2584 return is_boolean() ? &m_value.boolean :
nullptr;
2590 return is_number_integer() ? &m_value.number_integer :
nullptr;
2596 return is_number_integer() ? &m_value.number_integer :
nullptr;
2602 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2608 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2614 return is_number_float() ? &m_value.number_float :
nullptr;
2620 return is_number_float() ? &m_value.number_float :
nullptr;
2634 template<
typename ReferenceType,
typename ThisType>
2635 static ReferenceType get_ref_impl(ThisType& obj)
2638 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2639 auto ptr = obj.template get_ptr<PointerType>();
2647 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2690 template<
typename ValueType,
typename 2692 not std::is_pointer<ValueType>::value
2694 ValueType
get()
const 2696 return get_impl(static_cast<ValueType*>(
nullptr));
2725 template<
typename PointerType,
typename 2727 std::is_pointer<PointerType>::value
2729 PointerType
get() noexcept
2732 return get_ptr<PointerType>();
2739 template<
typename PointerType,
typename 2741 std::is_pointer<PointerType>::value
2743 const PointerType
get()
const noexcept
2746 return get_ptr<PointerType>();
2774 template<
typename PointerType,
typename 2776 std::is_pointer<PointerType>::value
2781 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2788 template<
typename PointerType,
typename 2790 std::is_pointer<PointerType>::value
2791 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2796 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2825 template<
typename ReferenceType,
typename 2827 std::is_reference<ReferenceType>::value
2832 return get_ref_impl<ReferenceType>(*this);
2839 template<
typename ReferenceType,
typename 2841 std::is_reference<ReferenceType>::value
2842 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2847 return get_ref_impl<ReferenceType>(*this);
2878 template <
typename ValueType,
typename 2880 not std::is_pointer<ValueType>::value
2881 and not std::is_same<ValueType, typename string_t::value_type>::value
2882 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2883 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2886 operator ValueType()
const 2889 return get<ValueType>();
2931 assert(m_value.array !=
nullptr);
2932 return m_value.array->at(idx);
2934 catch (std::out_of_range&)
2937 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2942 throw std::domain_error(
"cannot use at() with " + type_name());
2975 assert(m_value.array !=
nullptr);
2976 return m_value.array->at(idx);
2978 catch (std::out_of_range&)
2981 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2986 throw std::domain_error(
"cannot use at() with " + type_name());
3023 assert(m_value.object !=
nullptr);
3024 return m_value.object->at(key);
3026 catch (std::out_of_range&)
3029 throw std::out_of_range(
"key '" + key +
"' not found");
3034 throw std::domain_error(
"cannot use at() with " + type_name());
3071 assert(m_value.object !=
nullptr);
3072 return m_value.object->at(key);
3074 catch (std::out_of_range&)
3077 throw std::out_of_range(
"key '" + key +
"' not found");
3082 throw std::domain_error(
"cannot use at() with " + type_name());
3116 m_type = value_t::array;
3117 m_value.
array = create<array_t>();
3123 assert(m_value.array !=
nullptr);
3124 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3126 m_value.array->push_back(basic_json());
3129 return m_value.array->operator[](idx);
3133 throw std::domain_error(
"cannot use operator[] with " + type_name());
3161 assert(m_value.array !=
nullptr);
3162 return m_value.array->operator[](idx);
3166 throw std::domain_error(
"cannot use operator[] with " + type_name());
3202 m_type = value_t::object;
3203 m_value.
object = create<object_t>();
3209 assert(m_value.object !=
nullptr);
3210 return m_value.object->operator[](key);
3214 throw std::domain_error(
"cannot use operator[] with " + type_name());
3250 assert(m_value.object !=
nullptr);
3251 assert(m_value.object->find(key) != m_value.object->end());
3252 return m_value.object->find(key)->second;
3256 throw std::domain_error(
"cannot use operator[] with " + type_name());
3287 template<
typename T, std::
size_t n>
3290 return operator[](static_cast<const T>(key));
3322 template<
typename T, std::
size_t n>
3325 return operator[](static_cast<const T>(key));
3355 template<
typename T>
3361 m_type = value_t::object;
3362 m_value = value_t::object;
3368 assert(m_value.object !=
nullptr);
3369 return m_value.object->operator[](key);
3373 throw std::domain_error(
"cannot use operator[] with " + type_name());
3404 template<
typename T>
3410 assert(m_value.object !=
nullptr);
3411 assert(m_value.object->find(key) != m_value.object->end());
3412 return m_value.object->find(key)->second;
3416 throw std::domain_error(
"cannot use operator[] with " + type_name());
3468 template <
class ValueType,
typename 3470 std::is_convertible<basic_json_t, ValueType>::value
3472 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3478 const auto it = find(key);
3485 return default_value;
3490 throw std::domain_error(
"cannot use value() with " + type_name());
3498 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3500 return value(key,
string_t(default_value));
3618 template <
class InteratorType,
typename 3620 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3621 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3627 if (
this != pos.m_object)
3629 throw std::domain_error(
"iterator does not fit current value");
3632 InteratorType result = end();
3636 case value_t::boolean:
3637 case value_t::number_float:
3638 case value_t::number_integer:
3639 case value_t::number_unsigned:
3640 case value_t::string:
3642 if (not pos.m_it.primitive_iterator.is_begin())
3644 throw std::out_of_range(
"iterator out of range");
3649 delete m_value.string;
3650 m_value.string =
nullptr;
3653 m_type = value_t::null;
3657 case value_t::object:
3659 assert(m_value.object !=
nullptr);
3660 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3664 case value_t::array:
3666 assert(m_value.array !=
nullptr);
3667 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3673 throw std::domain_error(
"cannot use erase() with " + type_name());
3724 template <
class InteratorType,
typename 3726 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3727 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3730 InteratorType
erase(InteratorType first, InteratorType last)
3733 if (
this != first.m_object or
this != last.m_object)
3735 throw std::domain_error(
"iterators do not fit current value");
3738 InteratorType result = end();
3742 case value_t::boolean:
3743 case value_t::number_float:
3744 case value_t::number_integer:
3745 case value_t::number_unsigned:
3746 case value_t::string:
3748 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3750 throw std::out_of_range(
"iterators out of range");
3755 delete m_value.string;
3756 m_value.string =
nullptr;
3759 m_type = value_t::null;
3763 case value_t::object:
3765 assert(m_value.object !=
nullptr);
3766 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3767 last.m_it.object_iterator);
3771 case value_t::array:
3773 assert(m_value.array !=
nullptr);
3774 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3775 last.m_it.array_iterator);
3781 throw std::domain_error(
"cannot use erase() with " + type_name());
3819 assert(m_value.object !=
nullptr);
3820 return m_value.object->erase(key);
3824 throw std::domain_error(
"cannot use erase() with " + type_name());
3859 throw std::out_of_range(
"index out of range");
3862 assert(m_value.array !=
nullptr);
3863 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3867 throw std::domain_error(
"cannot use erase() with " + type_name());
3890 auto result = end();
3894 assert(m_value.object !=
nullptr);
3895 result.m_it.object_iterator = m_value.object->find(key);
3907 auto result = cend();
3911 assert(m_value.object !=
nullptr);
3912 result.m_it.object_iterator = m_value.object->find(key);
3939 assert(not is_object() or m_value.object !=
nullptr);
3940 return is_object() ? m_value.object->count(key) : 0;
4180 template<
typename IteratorType>
class iteration_proxy;
4196 return iteration_proxy<iterator>(cont);
4204 return iteration_proxy<const_iterator>(cont);
4256 case value_t::array:
4258 assert(m_value.array !=
nullptr);
4259 return m_value.array->empty();
4262 case value_t::object:
4264 assert(m_value.object !=
nullptr);
4265 return m_value.object->empty();
4314 case value_t::array:
4316 assert(m_value.array !=
nullptr);
4317 return m_value.array->size();
4320 case value_t::object:
4322 assert(m_value.object !=
nullptr);
4323 return m_value.object->size();
4370 case value_t::array:
4372 assert(m_value.array !=
nullptr);
4373 return m_value.array->max_size();
4376 case value_t::object:
4378 assert(m_value.object !=
nullptr);
4379 return m_value.object->max_size();
4429 case value_t::number_integer:
4431 m_value.number_integer = 0;
4435 case value_t::number_unsigned:
4437 m_value.number_unsigned = 0;
4441 case value_t::number_float:
4443 m_value.number_float = 0.0;
4447 case value_t::boolean:
4449 m_value.boolean =
false;
4453 case value_t::string:
4455 assert(m_value.string !=
nullptr);
4456 m_value.string->clear();
4460 case value_t::array:
4462 assert(m_value.array !=
nullptr);
4463 m_value.array->clear();
4467 case value_t::object:
4469 assert(m_value.object !=
nullptr);
4470 m_value.object->clear();
4504 if (not(is_null() or is_array()))
4506 throw std::domain_error(
"cannot use push_back() with " + type_name());
4512 m_type = value_t::array;
4513 m_value = value_t::array;
4517 assert(m_value.array !=
nullptr);
4518 m_value.array->push_back(std::move(val));
4520 val.m_type = value_t::null;
4529 push_back(std::move(val));
4540 if (not(is_null() or is_array()))
4542 throw std::domain_error(
"cannot use push_back() with " + type_name());
4548 m_type = value_t::array;
4549 m_value = value_t::array;
4553 assert(m_value.array !=
nullptr);
4554 m_value.array->push_back(val);
4590 if (not(is_null() or is_object()))
4592 throw std::domain_error(
"cannot use push_back() with " + type_name());
4598 m_type = value_t::object;
4599 m_value = value_t::object;
4603 assert(m_value.object !=
nullptr);
4604 m_value.object->insert(val);
4614 return operator[](val.first);
4645 if (pos.m_object !=
this)
4647 throw std::domain_error(
"iterator does not fit current value");
4652 assert(m_value.array !=
nullptr);
4653 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4658 throw std::domain_error(
"cannot use insert() with " + type_name());
4668 return insert(pos, val);
4701 if (pos.m_object !=
this)
4703 throw std::domain_error(
"iterator does not fit current value");
4708 assert(m_value.array !=
nullptr);
4709 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4714 throw std::domain_error(
"cannot use insert() with " + type_name());
4753 throw std::domain_error(
"cannot use insert() with " + type_name());
4757 if (pos.m_object !=
this)
4759 throw std::domain_error(
"iterator does not fit current value");
4762 if (first.m_object != last.m_object)
4764 throw std::domain_error(
"iterators do not fit");
4767 if (first.m_object ==
this or last.m_object ==
this)
4769 throw std::domain_error(
"passed iterators may not belong to container");
4774 assert(m_value.array !=
nullptr);
4775 result.m_it.array_iterator = m_value.array->insert(
4776 pos.m_it.array_iterator,
4777 first.m_it.array_iterator,
4778 last.m_it.array_iterator);
4811 throw std::domain_error(
"cannot use insert() with " + type_name());
4815 if (pos.m_object !=
this)
4817 throw std::domain_error(
"iterator does not fit current value");
4822 assert(m_value.array !=
nullptr);
4823 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4845 std::is_nothrow_move_constructible<value_t>::value and
4846 std::is_nothrow_move_assignable<value_t>::value and
4847 std::is_nothrow_move_constructible<json_value>::value and
4848 std::is_nothrow_move_assignable<json_value>::value
4851 std::swap(m_type, other.m_type);
4852 std::swap(m_value, other.m_value);
4880 assert(m_value.array !=
nullptr);
4881 std::swap(*(m_value.array), other);
4885 throw std::domain_error(
"cannot use swap() with " + type_name());
4914 assert(m_value.object !=
nullptr);
4915 std::swap(*(m_value.object), other);
4919 throw std::domain_error(
"cannot use swap() with " + type_name());
4948 assert(m_value.string !=
nullptr);
4949 std::swap(*(m_value.string), other);
4953 throw std::domain_error(
"cannot use swap() with " + type_name());
4979 static constexpr std::array<uint8_t, 8> order = {{
4992 if (lhs == value_t::discarded or rhs == value_t::discarded)
4997 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5026 const auto lhs_type = lhs.type();
5027 const auto rhs_type = rhs.type();
5029 if (lhs_type == rhs_type)
5033 case value_t::array:
5035 assert(lhs.m_value.array !=
nullptr);
5036 assert(rhs.m_value.array !=
nullptr);
5037 return *lhs.m_value.array == *rhs.m_value.array;
5039 case value_t::object:
5041 assert(lhs.m_value.object !=
nullptr);
5042 assert(rhs.m_value.object !=
nullptr);
5043 return *lhs.m_value.object == *rhs.m_value.object;
5049 case value_t::string:
5051 assert(lhs.m_value.string !=
nullptr);
5052 assert(rhs.m_value.string !=
nullptr);
5053 return *lhs.m_value.string == *rhs.m_value.string;
5055 case value_t::boolean:
5057 return lhs.m_value.boolean == rhs.m_value.boolean;
5059 case value_t::number_integer:
5061 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5063 case value_t::number_unsigned:
5065 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5067 case value_t::number_float:
5069 return lhs.m_value.number_float == rhs.m_value.number_float;
5077 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5079 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5081 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5083 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5085 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5087 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5089 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5091 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5093 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5095 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5097 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5099 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5155 return not (lhs == rhs);
5187 return not v.is_null();
5216 const auto lhs_type = lhs.type();
5217 const auto rhs_type = rhs.type();
5219 if (lhs_type == rhs_type)
5223 case value_t::array:
5225 assert(lhs.m_value.array !=
nullptr);
5226 assert(rhs.m_value.array !=
nullptr);
5227 return *lhs.m_value.array < *rhs.m_value.array;
5229 case value_t::object:
5231 assert(lhs.m_value.object !=
nullptr);
5232 assert(rhs.m_value.object !=
nullptr);
5233 return *lhs.m_value.object < *rhs.m_value.object;
5239 case value_t::string:
5241 assert(lhs.m_value.string !=
nullptr);
5242 assert(rhs.m_value.string !=
nullptr);
5243 return *lhs.m_value.string < *rhs.m_value.string;
5245 case value_t::boolean:
5247 return lhs.m_value.boolean < rhs.m_value.boolean;
5249 case value_t::number_integer:
5251 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5253 case value_t::number_unsigned:
5255 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5257 case value_t::number_float:
5259 return lhs.m_value.number_float < rhs.m_value.number_float;
5267 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5269 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5271 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5273 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5275 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5277 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5279 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5281 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5283 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5285 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5287 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5289 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5295 return operator<(lhs_type, rhs_type);
5317 return not (rhs < lhs);
5339 return not (lhs <= rhs);
5361 return not (lhs < rhs);
5396 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5399 const bool pretty_print = (o.width() > 0);
5400 const auto indentation = (pretty_print ? o.width() : 0);
5406 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5414 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5455 return parser(s, cb).
parse();
5484 return parser(i, cb).
parse();
5492 return parser(i, cb).
parse();
5520 j = parser(i).
parse();
5530 j = parser(i).
parse();
5549 case value_t::object:
5551 case value_t::array:
5553 case value_t::string:
5555 case value_t::boolean:
5557 case value_t::discarded:
5572 static std::size_t extra_space(
const string_t& s) noexcept
5574 std::size_t result = 0;
5576 for (
const auto& c : s)
5595 if (c >= 0x00 and c <= 0x1f)
5623 const auto space = extra_space(s);
5630 string_t result(s.size() + space,
'\\');
5631 std::size_t pos = 0;
5633 for (
const auto& c : s)
5640 result[pos + 1] =
'"';
5656 result[pos + 1] =
'b';
5664 result[pos + 1] =
'f';
5672 result[pos + 1] =
'n';
5680 result[pos + 1] =
'r';
5688 result[pos + 1] =
't';
5695 if (c >= 0x00 and c <= 0x1f)
5698 auto hexify = [](
const char v) ->
char 5700 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5705 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5743 void dump(std::ostream& o,
5744 const bool pretty_print,
5745 const unsigned int indent_step,
5746 const unsigned int current_indent = 0)
const 5749 unsigned int new_indent = current_indent;
5753 case value_t::object:
5755 assert(m_value.object !=
nullptr);
5757 if (m_value.object->empty())
5768 new_indent += indent_step;
5772 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5774 if (i != m_value.object->cbegin())
5776 o << (pretty_print ?
",\n" :
",");
5778 o <<
string_t(new_indent,
' ') <<
"\"" 5779 << escape_string(i->first) <<
"\":" 5780 << (pretty_print ?
" " :
"");
5781 i->second.dump(o, pretty_print, indent_step, new_indent);
5787 new_indent -= indent_step;
5791 o <<
string_t(new_indent,
' ') +
"}";
5795 case value_t::array:
5797 assert(m_value.array !=
nullptr);
5799 if (m_value.array->empty())
5810 new_indent += indent_step;
5814 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5816 if (i != m_value.array->cbegin())
5818 o << (pretty_print ?
",\n" :
",");
5821 i->dump(o, pretty_print, indent_step, new_indent);
5827 new_indent -= indent_step;
5831 o <<
string_t(new_indent,
' ') <<
"]";
5835 case value_t::string:
5837 assert(m_value.string !=
nullptr);
5838 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5842 case value_t::boolean:
5844 o << (m_value.boolean ?
"true" :
"false");
5848 case value_t::number_integer:
5850 o << m_value.number_integer;
5854 case value_t::number_unsigned:
5856 o << m_value.number_unsigned;
5860 case value_t::number_float:
5868 if (std::fmod(m_value.number_float, 1) == 0)
5870 o << std::fixed << std::setprecision(1);
5875 o.unsetf(std::ios_base::floatfield);
5876 o << std::setprecision(std::numeric_limits<double>::digits10);
5878 o << m_value.number_float;
5882 case value_t::discarded:
5902 value_t m_type = value_t::null;
5905 json_value m_value = {};
5922 class primitive_iterator_t
5938 bool is_begin()
const 5940 return (m_it == begin_value);
5946 return (m_it == end_value);
5966 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
5976 struct internal_iterator
5979 typename object_t::iterator object_iterator;
5981 typename array_t::iterator array_iterator;
5983 primitive_iterator_t primitive_iterator;
5987 : object_iterator(), array_iterator(), primitive_iterator()
5992 template<
typename IteratorType>
5993 class iteration_proxy
5997 class iteration_proxy_internal
6001 IteratorType anchor;
6003 size_t array_index = 0;
6006 iteration_proxy_internal(IteratorType it)
6011 iteration_proxy_internal& operator*()
6017 iteration_proxy_internal& operator++()
6026 bool operator!= (
const iteration_proxy_internal& o)
const 6028 return anchor != o.anchor;
6034 assert(anchor.m_object !=
nullptr);
6036 switch (anchor.m_object->type())
6039 case value_t::array:
6041 return std::to_string(array_index);
6045 case value_t::object:
6047 return anchor.key();
6059 typename IteratorType::reference value()
const 6061 return anchor.value();
6066 typename IteratorType::reference container;
6070 iteration_proxy(
typename IteratorType::reference cont)
6075 iteration_proxy_internal begin()
6077 return iteration_proxy_internal(container.begin());
6081 iteration_proxy_internal end()
6083 return iteration_proxy_internal(container.end());
6101 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6104 friend class basic_json;
6124 assert(m_object !=
nullptr);
6126 switch (m_object->m_type)
6130 m_it.object_iterator =
typename object_t::iterator();
6136 m_it.array_iterator =
typename array_t::iterator();
6142 m_it.primitive_iterator = primitive_iterator_t();
6151 assert(m_object !=
nullptr);
6153 switch (m_object->m_type)
6157 m_it.object_iterator = other.m_it.object_iterator;
6163 m_it.array_iterator = other.m_it.array_iterator;
6169 m_it.primitive_iterator = other.m_it.primitive_iterator;
6177 : m_object(other.m_object), m_it(other.m_it)
6182 std::is_nothrow_move_constructible<pointer>::value and
6183 std::is_nothrow_move_assignable<pointer>::value and
6184 std::is_nothrow_move_constructible<internal_iterator>::value and
6185 std::is_nothrow_move_assignable<internal_iterator>::value
6188 std::swap(m_object, other.m_object);
6189 std::swap(m_it, other.m_it);
6197 assert(m_object !=
nullptr);
6199 switch (m_object->m_type)
6203 assert(m_object->m_value.object !=
nullptr);
6204 m_it.object_iterator = m_object->m_value.object->begin();
6210 assert(m_object->m_value.array !=
nullptr);
6211 m_it.array_iterator = m_object->m_value.array->begin();
6218 m_it.primitive_iterator.set_end();
6224 m_it.primitive_iterator.set_begin();
6233 assert(m_object !=
nullptr);
6235 switch (m_object->m_type)
6239 assert(m_object->m_value.object !=
nullptr);
6240 m_it.object_iterator = m_object->m_value.object->end();
6246 assert(m_object->m_value.array !=
nullptr);
6247 m_it.array_iterator = m_object->m_value.array->end();
6253 m_it.primitive_iterator.set_end();
6263 assert(m_object !=
nullptr);
6265 switch (m_object->m_type)
6269 assert(m_object->m_value.object);
6270 assert(m_it.object_iterator != m_object->m_value.object->end());
6271 return m_it.object_iterator->second;
6276 assert(m_object->m_value.array);
6277 assert(m_it.array_iterator != m_object->m_value.array->end());
6278 return *m_it.array_iterator;
6283 throw std::out_of_range(
"cannot get value");
6288 if (m_it.primitive_iterator.is_begin())
6294 throw std::out_of_range(
"cannot get value");
6303 assert(m_object !=
nullptr);
6305 switch (m_object->m_type)
6309 assert(m_object->m_value.object);
6310 assert(m_it.object_iterator != m_object->m_value.object->end());
6311 return &(m_it.object_iterator->second);
6316 assert(m_object->m_value.array);
6317 assert(m_it.array_iterator != m_object->m_value.array->end());
6318 return &*m_it.array_iterator;
6323 if (m_it.primitive_iterator.is_begin())
6329 throw std::out_of_range(
"cannot get value");
6338 auto result = *
this;
6346 assert(m_object !=
nullptr);
6348 switch (m_object->m_type)
6352 ++m_it.object_iterator;
6358 ++m_it.array_iterator;
6364 ++m_it.primitive_iterator;
6375 auto result = *
this;
6383 assert(m_object !=
nullptr);
6385 switch (m_object->m_type)
6389 --m_it.object_iterator;
6395 --m_it.array_iterator;
6401 --m_it.primitive_iterator;
6413 if (m_object != other.m_object)
6415 throw std::domain_error(
"cannot compare iterators of different containers");
6418 assert(m_object !=
nullptr);
6420 switch (m_object->m_type)
6424 return (m_it.object_iterator == other.m_it.object_iterator);
6429 return (m_it.array_iterator == other.m_it.array_iterator);
6434 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6442 return not operator==(other);
6449 if (m_object != other.m_object)
6451 throw std::domain_error(
"cannot compare iterators of different containers");
6454 assert(m_object !=
nullptr);
6456 switch (m_object->m_type)
6460 throw std::domain_error(
"cannot compare order of object iterators");
6465 return (m_it.array_iterator < other.m_it.array_iterator);
6470 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6478 return not other.operator < (*this);
6484 return not operator<=(other);
6490 return not operator<(other);
6496 assert(m_object !=
nullptr);
6498 switch (m_object->m_type)
6502 throw std::domain_error(
"cannot use offsets with object iterators");
6507 m_it.array_iterator += i;
6513 m_it.primitive_iterator += i;
6524 return operator+=(-i);
6530 auto result = *
this;
6538 auto result = *
this;
6546 assert(m_object !=
nullptr);
6548 switch (m_object->m_type)
6552 throw std::domain_error(
"cannot use offsets with object iterators");
6557 return m_it.array_iterator - other.m_it.array_iterator;
6562 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6570 assert(m_object !=
nullptr);
6572 switch (m_object->m_type)
6576 throw std::domain_error(
"cannot use operator[] for object iterators");
6581 return *(m_it.array_iterator + n);
6586 throw std::out_of_range(
"cannot get value");
6591 if (m_it.primitive_iterator == -n)
6597 throw std::out_of_range(
"cannot get value");
6604 typename object_t::key_type
key()
const 6606 assert(m_object !=
nullptr);
6608 if (m_object->is_object())
6610 return m_it.object_iterator->first;
6614 throw std::domain_error(
"cannot use key() for non-object iterators");
6628 internal_iterator m_it = internal_iterator();
6665 std::is_nothrow_move_constructible<pointer>::value and
6666 std::is_nothrow_move_assignable<pointer>::value and
6667 std::is_nothrow_move_constructible<internal_iterator>::value and
6668 std::is_nothrow_move_assignable<internal_iterator>::value
6671 base_iterator::operator=(other);
6678 return const_cast<reference>(base_iterator::operator*());
6684 return const_cast<pointer>(base_iterator::operator->());
6691 base_iterator::operator++();
6698 base_iterator::operator++();
6706 base_iterator::operator--();
6713 base_iterator::operator--();
6720 base_iterator::operator+=(i);
6727 base_iterator::operator-=(i);
6734 auto result = *
this;
6742 auto result = *
this;
6749 return base_iterator::operator-(other);
6755 return const_cast<reference>(base_iterator::operator[](n));
6761 return const_cast<reference>(base_iterator::value());
6782 template<
typename Base>
6804 return base_iterator::operator++(1);
6810 base_iterator::operator++();
6817 return base_iterator::operator--(1);
6823 base_iterator::operator--();
6830 base_iterator::operator+=(i);
6837 auto result = *
this;
6845 auto result = *
this;
6853 return this->base() - other.base();
6859 return *(this->operator+(n));
6863 typename object_t::key_type
key()
const 6865 auto it = --this->base();
6872 auto it = --this->base();
6873 return it.operator * ();
6894 enum class token_type
6913 using lexer_char_t =
unsigned char;
6916 explicit lexer(
const string_t& s) noexcept
6917 : m_stream(
nullptr), m_buffer(s)
6919 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
6920 assert(m_content !=
nullptr);
6921 m_start = m_cursor = m_content;
6922 m_limit = m_content + s.size();
6926 explicit lexer(std::istream* s) noexcept
6927 : m_stream(s), m_buffer()
6929 assert(m_stream !=
nullptr);
6930 getline(*m_stream, m_buffer);
6931 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
6932 assert(m_content !=
nullptr);
6933 m_start = m_cursor = m_content;
6934 m_limit = m_content + m_buffer.size();
6941 lexer(
const lexer&) =
delete;
6942 lexer operator=(
const lexer&) =
delete;
6959 static string_t to_unicode(
const std::size_t codepoint1,
6960 const std::size_t codepoint2 = 0)
6965 std::size_t codepoint = codepoint1;
6968 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
6971 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
6985 throw std::invalid_argument(
"missing or wrong low surrogate");
6989 if (codepoint < 0x80)
6992 result.append(1, static_cast<typename string_t::value_type>(codepoint));
6994 else if (codepoint <= 0x7ff)
6997 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
6998 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7000 else if (codepoint <= 0xffff)
7003 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7004 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7005 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7007 else if (codepoint <= 0x10ffff)
7010 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7011 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7012 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7013 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7017 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7024 static std::string token_type_name(token_type t)
7028 case token_type::uninitialized:
7029 return "<uninitialized>";
7030 case token_type::literal_true:
7031 return "true literal";
7032 case token_type::literal_false:
7033 return "false literal";
7034 case token_type::literal_null:
7035 return "null literal";
7036 case token_type::value_string:
7037 return "string literal";
7038 case token_type::value_number:
7039 return "number literal";
7040 case token_type::begin_array:
7042 case token_type::begin_object:
7044 case token_type::end_array:
7046 case token_type::end_object:
7048 case token_type::name_separator:
7050 case token_type::value_separator:
7052 case token_type::parse_error:
7053 return "<parse error>";
7054 case token_type::end_of_input:
7055 return "end of input";
7059 return "unknown token";
7074 token_type scan() noexcept
7081 assert(m_start !=
nullptr);
7086 unsigned int yyaccept = 0;
7087 static const unsigned char yybm[] =
7089 0, 0, 0, 0, 0, 0, 0, 0,
7090 0, 32, 32, 0, 0, 32, 0, 0,
7091 128, 128, 128, 128, 128, 128, 128, 128,
7092 128, 128, 128, 128, 128, 128, 128, 128,
7093 160, 128, 0, 128, 128, 128, 128, 128,
7094 128, 128, 128, 128, 128, 128, 128, 128,
7095 192, 192, 192, 192, 192, 192, 192, 192,
7096 192, 192, 128, 128, 128, 128, 128, 128,
7097 128, 128, 128, 128, 128, 128, 128, 128,
7098 128, 128, 128, 128, 128, 128, 128, 128,
7099 128, 128, 128, 128, 128, 128, 128, 128,
7100 128, 128, 128, 128, 0, 128, 128, 128,
7101 128, 128, 128, 128, 128, 128, 128, 128,
7102 128, 128, 128, 128, 128, 128, 128, 128,
7103 128, 128, 128, 128, 128, 128, 128, 128,
7104 128, 128, 128, 128, 128, 128, 128, 128,
7105 128, 128, 128, 128, 128, 128, 128, 128,
7106 128, 128, 128, 128, 128, 128, 128, 128,
7107 128, 128, 128, 128, 128, 128, 128, 128,
7108 128, 128, 128, 128, 128, 128, 128, 128,
7109 128, 128, 128, 128, 128, 128, 128, 128,
7110 128, 128, 128, 128, 128, 128, 128, 128,
7111 128, 128, 128, 128, 128, 128, 128, 128,
7112 128, 128, 128, 128, 128, 128, 128, 128,
7113 128, 128, 128, 128, 128, 128, 128, 128,
7114 128, 128, 128, 128, 128, 128, 128, 128,
7115 128, 128, 128, 128, 128, 128, 128, 128,
7116 128, 128, 128, 128, 128, 128, 128, 128,
7117 128, 128, 128, 128, 128, 128, 128, 128,
7118 128, 128, 128, 128, 128, 128, 128, 128,
7119 128, 128, 128, 128, 128, 128, 128, 128,
7120 128, 128, 128, 128, 128, 128, 128, 128,
7122 if ((m_limit - m_cursor) < 5)
7127 if (yybm[0 + yych] & 32)
7129 goto basic_json_parser_6;
7139 goto basic_json_parser_2;
7143 goto basic_json_parser_4;
7145 goto basic_json_parser_9;
7151 goto basic_json_parser_4;
7155 goto basic_json_parser_10;
7157 goto basic_json_parser_12;
7166 goto basic_json_parser_4;
7170 goto basic_json_parser_13;
7172 goto basic_json_parser_15;
7178 goto basic_json_parser_17;
7182 goto basic_json_parser_19;
7184 goto basic_json_parser_4;
7196 goto basic_json_parser_21;
7200 goto basic_json_parser_4;
7202 goto basic_json_parser_23;
7208 goto basic_json_parser_24;
7212 goto basic_json_parser_4;
7214 goto basic_json_parser_25;
7223 goto basic_json_parser_26;
7225 goto basic_json_parser_4;
7231 goto basic_json_parser_28;
7235 goto basic_json_parser_30;
7237 goto basic_json_parser_4;
7241 basic_json_parser_2:
7244 return token_type::end_of_input;
7246 basic_json_parser_4:
7248 basic_json_parser_5:
7250 return token_type::parse_error;
7252 basic_json_parser_6:
7254 if (m_limit <= m_cursor)
7259 if (yybm[0 + yych] & 32)
7261 goto basic_json_parser_6;
7266 basic_json_parser_9:
7268 yych = *(m_marker = ++m_cursor);
7271 goto basic_json_parser_5;
7273 goto basic_json_parser_32;
7274 basic_json_parser_10:
7277 return token_type::value_separator;
7279 basic_json_parser_12:
7283 goto basic_json_parser_5;
7287 goto basic_json_parser_13;
7291 goto basic_json_parser_15;
7293 goto basic_json_parser_5;
7294 basic_json_parser_13:
7296 yych = *(m_marker = ++m_cursor);
7301 goto basic_json_parser_37;
7308 goto basic_json_parser_38;
7312 goto basic_json_parser_38;
7315 basic_json_parser_14:
7317 return token_type::value_number;
7319 basic_json_parser_15:
7321 m_marker = ++m_cursor;
7322 if ((m_limit - m_cursor) < 3)
7327 if (yybm[0 + yych] & 64)
7329 goto basic_json_parser_15;
7335 goto basic_json_parser_37;
7337 goto basic_json_parser_14;
7343 goto basic_json_parser_38;
7347 goto basic_json_parser_38;
7349 goto basic_json_parser_14;
7351 basic_json_parser_17:
7354 return token_type::name_separator;
7356 basic_json_parser_19:
7359 return token_type::begin_array;
7361 basic_json_parser_21:
7364 return token_type::end_array;
7366 basic_json_parser_23:
7368 yych = *(m_marker = ++m_cursor);
7371 goto basic_json_parser_39;
7373 goto basic_json_parser_5;
7374 basic_json_parser_24:
7376 yych = *(m_marker = ++m_cursor);
7379 goto basic_json_parser_40;
7381 goto basic_json_parser_5;
7382 basic_json_parser_25:
7384 yych = *(m_marker = ++m_cursor);
7387 goto basic_json_parser_41;
7389 goto basic_json_parser_5;
7390 basic_json_parser_26:
7393 return token_type::begin_object;
7395 basic_json_parser_28:
7398 return token_type::end_object;
7400 basic_json_parser_30:
7402 yych = *(m_marker = ++m_cursor);
7405 goto basic_json_parser_42;
7407 goto basic_json_parser_5;
7408 basic_json_parser_31:
7410 if (m_limit <= m_cursor)
7415 basic_json_parser_32:
7416 if (yybm[0 + yych] & 128)
7418 goto basic_json_parser_31;
7422 goto basic_json_parser_33;
7426 goto basic_json_parser_34;
7428 goto basic_json_parser_36;
7429 basic_json_parser_33:
7430 m_cursor = m_marker;
7433 goto basic_json_parser_5;
7437 goto basic_json_parser_14;
7439 basic_json_parser_34:
7442 return token_type::value_string;
7444 basic_json_parser_36:
7446 if (m_limit <= m_cursor)
7457 goto basic_json_parser_31;
7461 goto basic_json_parser_33;
7463 goto basic_json_parser_31;
7471 goto basic_json_parser_33;
7473 goto basic_json_parser_31;
7479 goto basic_json_parser_31;
7481 goto basic_json_parser_33;
7491 goto basic_json_parser_31;
7495 goto basic_json_parser_31;
7497 goto basic_json_parser_33;
7505 goto basic_json_parser_31;
7507 goto basic_json_parser_33;
7513 goto basic_json_parser_31;
7517 goto basic_json_parser_43;
7519 goto basic_json_parser_33;
7523 basic_json_parser_37:
7527 goto basic_json_parser_33;
7531 goto basic_json_parser_44;
7533 goto basic_json_parser_33;
7534 basic_json_parser_38:
7540 goto basic_json_parser_46;
7542 goto basic_json_parser_33;
7548 goto basic_json_parser_46;
7552 goto basic_json_parser_33;
7556 goto basic_json_parser_47;
7558 goto basic_json_parser_33;
7560 basic_json_parser_39:
7564 goto basic_json_parser_49;
7566 goto basic_json_parser_33;
7567 basic_json_parser_40:
7571 goto basic_json_parser_50;
7573 goto basic_json_parser_33;
7574 basic_json_parser_41:
7578 goto basic_json_parser_51;
7580 goto basic_json_parser_33;
7581 basic_json_parser_42:
7585 goto basic_json_parser_52;
7587 goto basic_json_parser_33;
7588 basic_json_parser_43:
7590 if (m_limit <= m_cursor)
7599 goto basic_json_parser_33;
7603 goto basic_json_parser_54;
7605 goto basic_json_parser_33;
7611 goto basic_json_parser_54;
7615 goto basic_json_parser_33;
7619 goto basic_json_parser_54;
7621 goto basic_json_parser_33;
7623 basic_json_parser_44:
7625 m_marker = ++m_cursor;
7626 if ((m_limit - m_cursor) < 3)
7635 goto basic_json_parser_14;
7639 goto basic_json_parser_44;
7641 goto basic_json_parser_14;
7647 goto basic_json_parser_38;
7651 goto basic_json_parser_38;
7653 goto basic_json_parser_14;
7655 basic_json_parser_46:
7659 goto basic_json_parser_33;
7663 goto basic_json_parser_33;
7665 basic_json_parser_47:
7667 if (m_limit <= m_cursor)
7674 goto basic_json_parser_14;
7678 goto basic_json_parser_47;
7680 goto basic_json_parser_14;
7681 basic_json_parser_49:
7685 goto basic_json_parser_55;
7687 goto basic_json_parser_33;
7688 basic_json_parser_50:
7692 goto basic_json_parser_56;
7694 goto basic_json_parser_33;
7695 basic_json_parser_51:
7699 goto basic_json_parser_58;
7701 goto basic_json_parser_33;
7702 basic_json_parser_52:
7707 basic_json_parser_54:
7709 if (m_limit <= m_cursor)
7718 goto basic_json_parser_33;
7722 goto basic_json_parser_60;
7724 goto basic_json_parser_33;
7730 goto basic_json_parser_60;
7734 goto basic_json_parser_33;
7738 goto basic_json_parser_60;
7740 goto basic_json_parser_33;
7742 basic_json_parser_55:
7746 goto basic_json_parser_61;
7748 goto basic_json_parser_33;
7749 basic_json_parser_56:
7752 return token_type::literal_null;
7754 basic_json_parser_58:
7757 return token_type::literal_true;
7759 basic_json_parser_60:
7761 if (m_limit <= m_cursor)
7770 goto basic_json_parser_33;
7774 goto basic_json_parser_63;
7776 goto basic_json_parser_33;
7782 goto basic_json_parser_63;
7786 goto basic_json_parser_33;
7790 goto basic_json_parser_63;
7792 goto basic_json_parser_33;
7794 basic_json_parser_61:
7797 return token_type::literal_false;
7799 basic_json_parser_63:
7801 if (m_limit <= m_cursor)
7810 goto basic_json_parser_33;
7814 goto basic_json_parser_31;
7816 goto basic_json_parser_33;
7822 goto basic_json_parser_31;
7826 goto basic_json_parser_33;
7830 goto basic_json_parser_31;
7832 goto basic_json_parser_33;
7840 void yyfill() noexcept
7842 if (m_stream ==
nullptr or not * m_stream)
7847 const ssize_t offset_start = m_start - m_content;
7848 const ssize_t offset_marker = m_marker - m_start;
7849 const ssize_t offset_cursor = m_cursor - m_start;
7851 m_buffer.erase(0, static_cast<size_t>(offset_start));
7853 assert(m_stream !=
nullptr);
7854 std::getline(*m_stream, line);
7855 m_buffer +=
"\n" + line;
7857 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7858 assert(m_content !=
nullptr);
7859 m_start = m_content;
7860 m_marker = m_start + offset_marker;
7861 m_cursor = m_start + offset_cursor;
7862 m_limit = m_start + m_buffer.size() - 1;
7866 string_t get_token()
const noexcept
7868 assert(m_start !=
nullptr);
7869 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7870 static_cast<size_t>(m_cursor - m_start));
7897 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
7900 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
7956 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
7957 4).c_str(),
nullptr, 16);
7960 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
7963 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
7965 throw std::invalid_argument(
"missing low surrogate");
7969 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
7970 (i + 7), 4).c_str(),
nullptr, 16);
7971 result += to_unicode(codepoint, codepoint2);
7978 result += to_unicode(codepoint);
7990 result.append(1, static_cast<typename string_t::value_type>(*i));
8017 long double str_to_float_t(
long double* ,
char** endptr)
const 8019 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8036 double str_to_float_t(
double* ,
char** endptr)
const 8038 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8055 float str_to_float_t(
float* ,
char** endptr)
const 8057 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8072 template <
typename T_A,
typename T_B>
8073 bool attempt_cast(T_A source, T_B& dest)
const 8075 dest =
static_cast<T_B
>(source);
8076 return (source == static_cast<T_A>(dest));
8117 void get_number(basic_json& result)
const 8119 typename string_t::value_type* endptr;
8120 assert(m_start !=
nullptr);
8125 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8129 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8130 10), result.m_value.number_unsigned))
8132 result.m_type = value_t::number_unsigned;
8137 result.m_type = value_t::number_float;
8144 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8145 10), result.m_value.number_integer))
8147 result.m_type = value_t::number_integer;
8152 result.m_type = value_t::number_float;
8158 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8160 result.m_type = value_t::number_float;
8163 if (result.m_type == value_t::number_float)
8170 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8173 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8175 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8182 std::istream* m_stream =
nullptr;
8186 const lexer_char_t* m_content =
nullptr;
8188 const lexer_char_t* m_start =
nullptr;
8190 const lexer_char_t* m_marker =
nullptr;
8192 const lexer_char_t* m_cursor =
nullptr;
8194 const lexer_char_t* m_limit =
nullptr;
8207 : callback(cb), m_lexer(s)
8215 : callback(cb), m_lexer(&_is)
8224 basic_json result = parse_internal(
true);
8226 expect(lexer::token_type::end_of_input);
8235 basic_json parse_internal(
bool keep)
8237 auto result = basic_json(value_t::discarded);
8241 case lexer::token_type::begin_object:
8243 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8246 result.m_type = value_t::object;
8247 result.m_value = json_value(value_t::object);
8254 if (last_token == lexer::token_type::end_object)
8257 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8259 result = basic_json(value_t::discarded);
8265 unexpect(lexer::token_type::value_separator);
8271 if (last_token == lexer::token_type::value_separator)
8277 expect(lexer::token_type::value_string);
8278 const auto key = m_lexer.get_string();
8280 bool keep_tag =
false;
8286 keep_tag = callback(depth, parse_event_t::key, k);
8296 expect(lexer::token_type::name_separator);
8300 auto value = parse_internal(keep);
8301 if (keep and keep_tag and not value.is_discarded())
8303 result[key] = std::move(value);
8306 while (last_token == lexer::token_type::value_separator);
8309 expect(lexer::token_type::end_object);
8311 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8313 result = basic_json(value_t::discarded);
8319 case lexer::token_type::begin_array:
8321 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8324 result.m_type = value_t::array;
8325 result.m_value = json_value(value_t::array);
8332 if (last_token == lexer::token_type::end_array)
8335 if (callback and not callback(--depth, parse_event_t::array_end, result))
8337 result = basic_json(value_t::discarded);
8343 unexpect(lexer::token_type::value_separator);
8349 if (last_token == lexer::token_type::value_separator)
8355 auto value = parse_internal(keep);
8356 if (keep and not value.is_discarded())
8358 result.push_back(std::move(value));
8361 while (last_token == lexer::token_type::value_separator);
8364 expect(lexer::token_type::end_array);
8366 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8368 result = basic_json(value_t::discarded);
8374 case lexer::token_type::literal_null:
8377 result.m_type = value_t::null;
8381 case lexer::token_type::value_string:
8383 const auto s = m_lexer.get_string();
8385 result = basic_json(s);
8389 case lexer::token_type::literal_true:
8392 result.m_type = value_t::boolean;
8393 result.m_value =
true;
8397 case lexer::token_type::literal_false:
8400 result.m_type = value_t::boolean;
8401 result.m_value =
false;
8405 case lexer::token_type::value_number:
8407 m_lexer.get_number(result);
8415 unexpect(last_token);
8419 if (keep and callback and not callback(depth, parse_event_t::value, result))
8421 result = basic_json(value_t::discarded);
8427 typename lexer::token_type get_token()
8429 last_token = m_lexer.scan();
8433 void expect(
typename lexer::token_type t)
const 8435 if (t != last_token)
8437 std::string error_msg =
"parse error - unexpected ";
8438 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8439 lexer::token_type_name(last_token));
8440 error_msg +=
"; expected " + lexer::token_type_name(t);
8441 throw std::invalid_argument(error_msg);
8445 void unexpect(
typename lexer::token_type t)
const 8447 if (t == last_token)
8449 std::string error_msg =
"parse error - unexpected ";
8450 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8451 lexer::token_type_name(last_token));
8452 throw std::invalid_argument(error_msg);
8462 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8500 is_nothrow_move_constructible<nlohmann::json>::value and
8501 is_nothrow_move_assignable<nlohmann::json>::value
8519 const auto& h = hash<nlohmann::json::string_t>();
8537 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8543 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8544 #pragma GCC diagnostic pop bool is_null() const noexcept
return whether value is null
reference operator*()
return a reference to the value pointed to by the iterator
reverse_iterator rbegin()
returns an iterator to the reverse-beginning
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
basic_json(const value_t value_type)
create an empty value with a given type
basic_json(const array_t &val)
create an array (explicit)
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
value_t type() const noexcept
return the type of the JSON value (explicit)
bool is_number_integer() const noexcept
return whether value is an integer number
const_reference operator[](size_type idx) const
access specified array element
reference value() const
return the value of an iterator
json_reverse_iterator & operator--()
pre-decrement (–it)
bool is_boolean() const noexcept
return whether value is a boolean
void clear() noexcept
clears the contents
bool operator==(const const_iterator &other) const
comparison: equal
json_reverse_iterator operator--(int)
post-decrement (it–)
reference operator[](T *(&key)[n])
access specified object element
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
bool is_number() const noexcept
return whether value is a number
iterator & operator+=(difference_type i)
add to iterator
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
const_iterator operator-(difference_type i)
subtract from iterator
BooleanType boolean_t
a type for a boolean
reference operator+=(const typename object_t::value_type &val)
add an object to an object
bool is_array() const noexcept
return whether value is an array
basic_json(const typename string_t::value_type *val)
create a string (explicit)
basic_json(boolean_t val)
create a boolean (explicit)
reference operator[](difference_type n) const
access to successor
iterator find(typename object_t::key_type key)
find an element in a JSON object
basic_json(const number_unsigned_t val)
create an unsigned integer number (explicit)
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
basic_json(const string_t &val)
create a string (explicit)
void push_back(const basic_json &val)
add an object to an array
void erase(const size_type idx)
remove element from a JSON array given an index
basic_json<> json
default JSON class
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
bool is_structured() const noexcept
return whether type is structured
reference front()
access the first element
void swap(object_t &other)
exchanges the values
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
const_iterator & operator+=(difference_type i)
add to iterator
a class to store JSON values
basic_json(const number_float_t val)
create a floating-point number (explicit)
pointer operator->()
dereference the iterator
reference value() const
return the value of an iterator
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
const_reverse_iterator crbegin() const
returns a const reverse iterator to the last element
NumberIntegerType number_integer_t
a type for a number (integer)
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
const_iterator operator+(difference_type i)
add to iterator
const_reverse_iterator rbegin() const
returns a const reverse iterator to the last element
a mutable random access iterator for the basic_json class
static basic_json parse(std::istream &&i, parser_callback_t cb=nullptr)
deserialize from stream
const_iterator operator++(int)
post-increment (it++)
bool is_string() const noexcept
return whether value is a string
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
reference & operator=(basic_json other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
copy assignment
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
PointerType get_ptr() noexcept
get a pointer value (implicit)
reference back()
access the last element
const value_type & const_reference
the type of an element const reference
typename basic_json::const_pointer pointer
defines a pointer to the type iterated over (value_type)
bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
void push_back(const typename object_t::value_type &val)
add an object to an object
iterator end()
returns an iterator to one past the last element
static basic_json parse(const string_t &s, parser_callback_t cb=nullptr)
deserialize from string
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
basic_json(std::nullptr_t) noexcept
create a null object (explicitly)
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
reference operator[](difference_type n) const
access to successor
static allocator_type get_allocator()
returns the allocator associated with the container
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
const_reference operator[](T *key) const
read-only access specified object element
json_reverse_iterator operator+(difference_type i) const
add to iterator
bool empty() const noexcept
checks whether the container is empty
std::size_t size_type
a type to represent container sizes
object_t::key_type key() const
return the key of an object iterator
basic_json(const CompatibleArrayType &val)
create an array (implicit)
const_reference at(size_type idx) const
access specified array element with bounds checking
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
const_iterator(const iterator &other)
copy constructor given a nonconst iterator
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
iterator insert(const_iterator pos, const basic_json &val)
inserts element
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
iterator & operator++()
pre-increment (++it)
bool operator<(const const_iterator &other) const
comparison: smaller
iterator operator++(int)
post-increment (it++)
basic_json(basic_json &&other) noexcept
move constructor
const_iterator operator--(int)
post-decrement (it–)
bool is_discarded() const noexcept
return whether value is discarded
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
iterator & operator=(iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
object (unordered set of name/value pairs)
size_type max_size() const noexcept
returns the maximum possible number of elements
iterator operator--(int)
post-decrement (it–)
iterator operator-(difference_type i)
subtract from iterator
const_iterator & operator--()
pre-decrement (–it)
const_iterator cend() const
returns a const iterator to one past the last element
string_t dump(const int indent=-1) const
serialization
basic_json value_type
the type of elements in a basic_json container
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
AllocatorType< basic_json > allocator_type
the allocator type
StringType string_t
a type for a string
reference operator+=(const basic_json &val)
add an object to an array
iterator begin()
returns an iterator to the first element
difference_type operator-(const const_iterator &other) const
return difference
value_type & reference
the type of an element reference
const_iterator begin() const
returns a const iterator to the first element
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
difference_type operator-(const iterator &other) const
basic_json(const int val)
create an integer number from an enum type (explicit)
iterator(const iterator &other) noexcept
copy constructor
namespace for Niels Lohmann
typename basic_json::difference_type difference_type
a type to represent differences between iterators
void swap(string_t &other)
exchanges the values
json_reverse_iterator(const base_iterator &it)
create reverse iterator from base class
basic_json(const number_integer_t val)
create an integer number (explicit)
reverse_iterator rend()
returns an iterator to the reverse-end
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
const_reference front() const
access the first element
bool operator>(const const_iterator &other) const
comparison: greater than
bool is_object() const noexcept
return whether value is an object
pointer operator->() const
dereference the iterator
NumberFloatType number_float_t
a type for a number (floating-point)
void swap(reference other) noexcept( std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value )
exchanges the values
value_t
the JSON type enumeration
const_reverse_iterator rend() const
returns a const reverse iterator to one before the first
std::ptrdiff_t difference_type
a type to represent differences between iterators
bool is_primitive() const noexcept
return whether type is primitive
ValueType get() const
get a value (explicit)
void swap(array_t &other)
exchanges the values
InteratorType erase(InteratorType first, InteratorType last)
remove elements given an iterator range
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
typename Base::reference reference
the reference type for the pointed-to element
const_reference back() const
access the last element
void push_back(basic_json &&val)
add an object to an array
array (ordered collection of values)
json_reverse_iterator & operator++()
pre-increment (++it)
static basic_json parse(std::istream &i, parser_callback_t cb=nullptr)
deserialize from stream
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
ReferenceType get_ref() const
get a reference value (implicit)
basic_json(const CompatibleNumberUnsignedType val) noexcept
create an unsigned number (implicit)
const_iterator(pointer object)
constructor for a given JSON instance
reference operator*() const
return a reference to the value pointed to by the iterator
friend bool operator<(const value_t lhs, const value_t rhs)
comparison operator for JSON types
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
iterator operator+(difference_type i)
add to iterator
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
bool operator<=(const const_iterator &other) const
comparison: less than or equal
InteratorType erase(InteratorType pos)
remove element given an iterator
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
iterator(pointer object) noexcept
constructor for a given JSON instance
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
json_reverse_iterator(const typename base_iterator::iterator_type &it)
create reverse iterator from iterator
const_iterator & operator++()
pre-increment (++it)
bool is_number_float() const noexcept
return whether value is a floating-point number
reference value() const
return the value of an iterator
std::bidirectional_iterator_tag iterator_category
the category of the iterator
difference_type operator-(const json_reverse_iterator &other) const
return difference
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
basic_json(const CompatibleObjectType &val)
create an object (implicit)
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
bool operator>=(const const_iterator &other) const
comparison: greater than or equal
const_iterator & operator=(const_iterator other) noexcept( std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value )
copy assignment
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
reference operator[](const typename object_t::key_type &key)
access specified object element
object_t::key_type key() const
return the key of an object iterator
const_iterator end() const
returns a const iterator to one past the last element
reference operator+=(basic_json &&val)
add an object to an array
reference operator[](difference_type n) const
access to successor
a const random access iterator for the basic_json class
a template for a reverse iterator class
typename basic_json::const_reference reference
defines a reference to the type iterated over (value_type)
json_reverse_iterator operator++(int)
post-increment (it++)
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
reference operator[](size_type idx)
access specified array element
bool operator!=(const const_iterator &other) const
comparison: not equal
json_reverse_iterator & operator+=(difference_type i)
add to iterator
reference at(size_type idx)
access specified array element with bounds checking
size_type size() const noexcept
returns the number of elements
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
const_iterator cbegin() const
returns a const iterator to the first element
iterator & operator-=(difference_type i)
subtract from iterator
const_reverse_iterator crend() const
returns a const reverse iterator to one before the first
basic_json(const object_t &val)
create an object (explicit)
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
const_iterator(const const_iterator &other) noexcept
copy constructor
iterator & operator--()
pre-decrement (–it)
iterator insert(const_iterator pos, basic_json &&val)
inserts element
ReferenceType get_ref()
get a reference value (implicit)
const_iterator & operator-=(difference_type i)
subtract from iterator
basic_json(const CompatibleStringType &val)
create a string (implicit)
basic_json(const basic_json &other)
copy constructor
reference operator[](T *key)
access specified object element
parse_event_t
JSON callback events.